[PATCH] D57086: Ignore trailing NullStmts in StmtExprs for GCC compatibility
Dominic Ferreira via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 22 22:50:27 PST 2019
domdom created this revision.
domdom added reviewers: lattner, rsmith.
Herald added a subscriber: cfe-commits.
Ignore trailing NullStmts in compound expressions when determining the result type and value. This is to match the GCC behavior which ignores semicolons at the end of compound expressions.
Repository:
rC Clang
https://reviews.llvm.org/D57086
Files:
clang/lib/Parse/ParseStmt.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/Sema/statements.c
Index: clang/test/Sema/statements.c
===================================================================
--- clang/test/Sema/statements.c
+++ clang/test/Sema/statements.c
@@ -119,3 +119,17 @@
SIZE = sizeof(({unsigned long __ptr; __ptr;}))
};
}
+
+// GCC ignores empty statements at the end of compound expressions where the
+// result type is concerned.
+void test13() {
+ int a;
+ a = ({1;});
+ a = ({1;;});
+ a = ({int x = 1; (void)x;}); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+ a = ({int x = 1; (void)x;;}); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+}
+
+void test14() { return ({}); }
+void test15() { return ({;;;;}); }
+void test16() { return ({test:;;}); }
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13320,11 +13320,22 @@
// More semantic analysis is needed.
// If there are sub-stmts in the compound stmt, take the type of the last one
- // as the type of the stmtexpr.
+ // as the type of the stmtexpr. For GCC compatibility this excludes trailing
+ // NullStmts
QualType Ty = Context.VoidTy;
bool StmtExprMayBindToTemp = false;
if (!Compound->body_empty()) {
- Stmt *LastStmt = Compound->body_back();
+ // GCC ignores empty statements at the end of compound expressions
+ // i.e. ({ 5;;; })
+ // ^^ ignored
+ // This code skips past these NullStmts
+ Stmt *LastStmt = nullptr;
+ for (Stmt *I : llvm::make_range(Compound->body_rbegin(),
+ Compound->body_rend())) {
+ LastStmt = I;
+ if (!isa<NullStmt>(LastStmt))
+ break;
+ }
LabelStmt *LastLabelStmt = nullptr;
// If LastStmt is a label, skip down through into the body.
while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt)) {
Index: clang/lib/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -959,10 +959,18 @@
bool Parser::isExprValueDiscarded() {
if (Actions.isCurCompoundStmtAStmtExpr()) {
- // Look to see if the next two tokens close the statement expression;
- // if so, this expression statement is the last statement in a
- // statment expression.
- return Tok.isNot(tok::r_brace) || NextToken().isNot(tok::r_paren);
+ // For gcc compatibility we skip past NullStmts
+ int lookahead = 0;
+ while(GetLookAheadToken(lookahead).is(tok::semi)) {
+ lookahead++;
+ }
+
+ // Then look to see if the next two tokens close the statement expression;
+ // if so, this expression statement is the last statement in a statment
+ // expression.
+
+ return GetLookAheadToken(lookahead).isNot(tok::r_brace) ||
+ GetLookAheadToken(lookahead + 1).isNot(tok::r_paren);
}
return true;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57086.183037.patch
Type: text/x-patch
Size: 2937 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190123/c5f8e2e3/attachment.bin>
More information about the cfe-commits
mailing list