aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNuno Lopes <nunoplopes@sapo.pt>2008-07-07 16:46:50 +0000
committerNuno Lopes <nunoplopes@sapo.pt>2008-07-07 16:46:50 +0000
commit9a979c327c442597c6a9cee961336530460fed04 (patch)
treec37e446268649d77c62c1414df31f419022759ca
parente8fdc83ee4819336f5b201e2aa14d0dddcf14b63 (diff)
fix CheckForConstantInitializer() for Compound Literals
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
-rw-r--r--lib/AST/Expr.cpp2
-rw-r--r--lib/Sema/SemaDecl.cpp5
-rw-r--r--test/Sema/compound-literal.c7
3 files changed, 11 insertions, 3 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index de0c740fd2..8d9bbcb65a 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -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
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 80c37b9764..8b98cbad11 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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;
diff --git a/test/Sema/compound-literal.c b/test/Sema/compound-literal.c
index 80dd370962..f25d54fc90 100644
--- a/test/Sema/compound-literal.c
+++ b/test/Sema/compound-literal.c
@@ -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};