================
@@ -1880,16 +1880,70 @@ Sema::ConditionResult 
Parser::ParseCXXCondition(StmtResult *InitStmt,
     return Sema::ConditionError();
   }
 
+  if (!getLangOpts().CPlusPlus && Tok.is(tok::kw___extension__)) {
+    // In C, the first clause of a condition may be a declaration used as an
+    // init-statement (C2y), and that declaration may be prefixed by one or 
more
+    // __extension__ markers. Consume them up front -- mirroring 
block-statement
+    // parsing -- so the disambiguation below sees the real start of the
+    // declaration. The markers also silence extension diagnostics for the rest
+    // of the condition, including the diagnostic for the init-statement
+    // extension itself.
+    std::optional<ExtensionRAIIObject> ExtensionGuard;
+    ExtensionGuard.emplace(Diags);
+    while (TryConsumeToken(tok::kw___extension__))
+      ;
+  }
+
   ParsedAttributes attrs(AttrFactory);
-  MaybeParseCXX11Attributes(attrs);
+  bool ParsedAttrs = MaybeParseCXX11Attributes(attrs);
+  if (!getLangOpts().CPlusPlus)
----------------
bassiounix wrote:

Ok after investigating the behavior of the current code, we do want to parse 
this in C mode only because in C++ this code will raise an error and a warning 
in case we used `[[]]` or any attributes only in the init stmt.
```cpp
if ([[]]; true) {}
if (__attribute__((assume(1 > 0))); true) {}
if (__attribute__(()); true) {}
```

But we do handle `[[]];` in C mode since we parse CXX11 attributes and check 
them down with the existence of `;`
```cpp
    // Handle 'if (; true)' and 'if ([[...]]; true)'.
    if (Tok.is(tok::semi)) {
```

Yes GNU attributes are handled for `ConditionOrInitStatement::InitStmtDecl`, 
but since it has C++ specific code it raises error/warnings on empty 
declarations, which is not desired in C mode.

We can go ahead and suppress these reports but it will cause a parsing behavior 
that's completely wrong rejecting valid code like `__attribute__((...)) 
__attribute__((...)) int x;`. If we wanted to handle that we should have a 
state somewhere to know what to accept and what to reject, which will alter 
functions' signature and becomes a messy edit.

The best way to go around it in my opinion is to catch that case before even 
entering `ConditionOrInitStatement::InitStmtDecl` and handle it in `if 
(Tok.is(tok::semi)) {` like we already do with `[[]]` by 
`MaybeParseCXX11Attributes(attrs);`.

And since this is only a valid case in C mode, we don't want to do that in C++ 
mode and let the compiler report empty init stmt like desired.

https://github.com/llvm/llvm-project/pull/198244
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to