[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