]> granicus.if.org Git - clang/commitdiff
fix CheckForConstantInitializer() for Compound Literals
authorNuno Lopes <nunoplopes@sapo.pt>
Mon, 7 Jul 2008 16:46:50 +0000 (16:46 +0000)
committerNuno Lopes <nunoplopes@sapo.pt>
Mon, 7 Jul 2008 16:46:50 +0000 (16:46 +0000)
also fix the correspondent test (it was expecting more errors than it should. please confirm my fix is correct (at least gcc agrees with me)

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

lib/AST/Expr.cpp
lib/Sema/SemaDecl.cpp
test/Sema/compound-literal.c

index de0c740fd293bbd1ad6219cd9e0900ee539b654e..8d9bbcb65a658fa14545c68a16f8b9c8e33d33aa 100644 (file)
@@ -670,7 +670,7 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
 /// expression. The generalization of the wording to include any subexpression
 /// that is not evaluated (C99 6.6p3) means that nonconstant subexpressions
 /// can appear as operands to other operators (e.g. &&, ||, ?:). For instance,
-/// "0 || f()" can be treated as a constant expression. In C90 this expression,
+/// "1 || f()" can be treated as a constant expression. In C90 this expression,
 /// occurring in a context requiring a constant, would have been a constraint
 /// violation. FIXME: This routine currently implements C90 semantics.
 /// To properly implement C99 semantics this routine will need to evaluate
index 80c37b97641ca2578f56e65204d12e88cfeaee99..8b98cbad112bdaf044a8589498e5f646ef88acfb 100644 (file)
@@ -1197,10 +1197,15 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) {
 }
 
 bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
+  Init = Init->IgnoreParens();
+
   // Look through CXXDefaultArgExprs; they have no meaning in this context.
   if (CXXDefaultArgExpr* DAE = dyn_cast<CXXDefaultArgExpr>(Init))
     return CheckForConstantInitializer(DAE->getExpr(), DclT);
 
+  if (CompoundLiteralExpr *e = dyn_cast<CompoundLiteralExpr>(Init))
+    return CheckForConstantInitializer(e->getInitializer(), DclT);
+
   if (Init->getType()->isReferenceType()) {
     // FIXME: Work out how the heck reference types work
     return false;
index 80dd370962a86095488cd6859c4f8698a7d15e4b..f25d54fc90fd1201c216e385b670407cc5caac94 100644 (file)
@@ -2,15 +2,18 @@
 
 struct foo { int a, b; };
 
-static struct foo t = (struct foo){0,0}; // -expected-error {{initializer element is not constant}}
+static struct foo t = (struct foo){0,0};
 static struct foo t2 = {0,0}; 
 static struct foo t3 = t2; // -expected-error {{initializer element is not constant}}
 static int *p = (int []){2,4}; 
-static int x = (int){1}; // -expected-error {{initializer element is not constant}} -expected-warning{{braces around scalar initializer}}
+static int x = (int){1}; // -expected-warning{{braces around scalar initializer}}
 
 static int *p2 = (int []){2,x}; // -expected-error {{initializer element is not constant}}
 static int *p3 = (int []){2,"x"}; // -expected-warning {{incompatible pointer to integer conversion initializing 'char [2]', expected 'int'}}
 
+typedef struct { } cache_t; // -expected-warning{{use of empty struct extension}}
+static cache_t clo_I1_cache = ((cache_t) { } ); // -expected-warning{{use of GNU empty initializer extension}}
+
 typedef struct Test {int a;int b;} Test;
 static Test* ll = &(Test) {0,0};