Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,9 @@ def err_expansion_stmt_requires_cxx2c : Error<
"expansion statements are only supported in C++2c">;
def err_for_template : Error<
"'for template' is invalid; use 'template for' instead">;
def ext_expansion_stmt_missing_braces : Extension<
"ISO C++ requires a compound statement to be the body of an expansion statement">,
Comment thread
zwuis marked this conversation as resolved.
Resolved
InGroup<DiagGroup<"expansion-stmt-missing-braces">>;

def err_expected_case_before_expression: Error<
"expected 'case' keyword before expression">;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2329,6 +2329,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc,
// the other parts.
getCurScope()->EnterLoopBody(PrecedingLabel);

// attribute-specifier without attribute (`[[]]`) isn't in AST.
bool BodyStartsWithSquare = Tok.is(tok::l_square);
SourceLocation BodyBeginLoc = Tok.getLocation();

// C99 6.8.5p5 - In C99, the body of the for statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do this
// if the body isn't a compound statement to avoid push/pop in common cases.
Expand Down Expand Up @@ -2379,6 +2383,9 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc,
return StmtError();
}

if (!isa<CompoundStmt>(Body.get()) || BodyStartsWithSquare)
Diag(BodyBeginLoc, diag::ext_expansion_stmt_missing_braces);

Comment thread
zwuis marked this conversation as resolved.
Resolved
return Actions.FinishCXXExpansionStmt(ForRangeStmt.get(), Body.get());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -Wexpansion-stmt-missing-braces -verify
// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -Wpedantic -verify

void f() {
template for (int x : {1})
template for (int y : {1}) // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
; // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
template for (int x : {1})
if (x) // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
;
template for (int x : {1})
switch (x) // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
;
template for (int x : {1})
for (;;) // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
;
template for (int x : {1})
while (x) // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
;
template for (int x : {1})
do // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
;
while (x);
template for (int x : {1})
return; // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
template for (int x : {1})
[ // expected-warning {{ISO C++ requires a compound statement to be the body of an expansion statement}}
[]] {}
template for (int x : {1})
foo: {} // expected-error {{labels are not allowed in expansion statements}}
}
Loading