[clang] [clang][Parser] Warn when the body of expansion statement is not a compound statement (PR #209229)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 15 06:57:08 PDT 2026


================
@@ -2379,6 +2382,11 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc,
       return StmtError();
     }
 
+    // attribute-specifier without attribute (`[[]]`) isn't in AST.
+    // `__declspec()` is only applied to declarations, so we can ignore it.
+    if (!isa<CompoundStmt>(Body.get()) || BodyStartsWithAttr)
----------------
AaronBallman wrote:

Whelp, I think this logic is correct but I really don't agree with the design in the standard and think there's another extension hiding in here:
```
int main() {
  template for (int x : {1}) [[clang::atomic(remote_memory)]] {}
}
```
That's invalid per the standard because the standard requires a compound-statement and that grammar production cannot have a leading attribute. If WG21 used statement instead, then a leading attribute would be accepted as you'd expect.

I think the diagnostic text will be confusing in that situation because there *is* a compound statement. That suggests we want to handle attributes with their own diagnostic, but that would mean we'd need to get much better about recognizing attributes instead of looking for a single token.

Ideally, we'd have a `CompoundStmt` or an `AttributedStmt` which wraps a `CompoundStmt`, but there are two scenarios I think that won't cover:
```
template for (int x : {1}) [[]] { } // Empty attributes don't make an AttributedStmt
template for (int x : {1}) [[unknown]] {} // Unknown attributes don't make an AttributedStmt either
```
Other test cases to consider would be Objective-C++ or lambdas in C++, so it's not just attributes:
```
template for (int x : {1}) [obj msg];
template for (int x : {1}) [](){}();
```


https://github.com/llvm/llvm-project/pull/209229


More information about the cfe-commits mailing list