]> granicus.if.org Git - clang/commitdiff
Parse: Don't crash when namespace is in GNU statement expr
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 9 Jan 2015 09:38:14 +0000 (09:38 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 9 Jan 2015 09:38:14 +0000 (09:38 +0000)
Parser::ParseNamespace can get a little confused when it found itself
inside a compound statement inside of a non-static data member
initializer.

Try to determine that the statement expression's scope makes sense
before trying to parse it's contents.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225514 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Parse/ParseExpr.cpp
lib/Sema/SemaExpr.cpp
test/Parser/namespaces.cpp

index f39c2b888ede47fbac0ac4a0d3261dbea391be42..239d4d20bb72c93d885e8851fe644b099bcb03af 100644 (file)
@@ -131,6 +131,8 @@ def ext_gnu_indirect_goto : Extension<
   "use of GNU indirect-goto extension">, InGroup<GNULabelsAsValue>;
 def ext_gnu_address_of_label : Extension<
   "use of GNU address-of-label extension">, InGroup<GNULabelsAsValue>;
+def err_stmtexpr_file_scope : Error<
+  "statement expression not allowed at file scope">;
 def ext_gnu_statement_expr : Extension<
   "use of GNU statement expression extension">, InGroup<GNUStatementExpression>;
 def ext_gnu_conditional_expr : Extension<
index d3129bd62ecf78434617cb081c868d1368730aff..cfe7b99b932185d0321189e6b2de8fb32b761a1f 100644 (file)
@@ -4984,8 +4984,6 @@ def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error<
   "|arithmetic operation with operands of type %diff{ ($ and $)|}0,1}2"
   " which are pointers to non-overlapping address spaces">;
 def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
-def err_stmtexpr_file_scope : Error<
-  "statement expression not allowed at file scope">;
 def warn_mixed_sign_comparison : Warning<
   "comparison of integers of different signs: %0 and %1">,
   InGroup<SignCompare>, DefaultIgnore;
index a89036a98cb7c1e354a735c4ee2e053eeef1a044..d0d97de84c10cdf7d4dee4dc9df7e1a4fe83667d 100644 (file)
@@ -2084,16 +2084,21 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
   // unless they've already reported an error.
   if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
     Diag(Tok, diag::ext_gnu_statement_expr);
-    Actions.ActOnStartStmtExpr();
 
-    StmtResult Stmt(ParseCompoundStatement(true));
-    ExprType = CompoundStmt;
-
-    // If the substmt parsed correctly, build the AST node.
-    if (!Stmt.isInvalid()) {
-      Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation());
+    if (!getCurScope()->getFnParent() && !getCurScope()->getBlockParent()) {
+      Result = ExprError(Diag(OpenLoc, diag::err_stmtexpr_file_scope));
     } else {
-      Actions.ActOnStmtExprError();
+      Actions.ActOnStartStmtExpr();
+
+      StmtResult Stmt(ParseCompoundStatement(true));
+      ExprType = CompoundStmt;
+
+      // If the substmt parsed correctly, build the AST node.
+      if (!Stmt.isInvalid()) {
+        Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation());
+      } else {
+        Actions.ActOnStmtExprError();
+      }
     }
   } else if (ExprType >= CompoundLiteral && BridgeCast) {
     tok::TokenKind tokenKind = Tok.getKind();
index 623d18d04e743d47602a45000514cadc9669614c..68bad16ff38cf671d85e2e6c5ace19d35841d67f 100644 (file)
@@ -10275,11 +10275,6 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
   assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!");
   PopExpressionEvaluationContext();
 
-  bool isFileScope
-    = (getCurFunctionOrMethodDecl() == nullptr) && (getCurBlock() == nullptr);
-  if (isFileScope)
-    return ExprError(Diag(LPLoc, diag::err_stmtexpr_file_scope));
-
   // FIXME: there are a variety of strange constraints to enforce here, for
   // example, it is not possible to goto into a stmt expression apparently.
   // More semantic analysis is needed.
index 6491cfd446b311ba15e956a1d8d42f266cb662eb..25ff73b8ec01d779c96fba22523467c6012bfbd2 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 
 // PR6596
 namespace g { enum { o = 0 }; }
@@ -10,3 +10,7 @@ void foo() {
 // PR14085
 namespace PR14085 {}
 namespace = PR14085; // expected-error {{expected identifier}}
+
+struct namespace_nested_in_record {
+  int k = ({namespace {}}); // expected-error {{statement expression not allowed at file scope}}
+};