>From http://llvm.org/bugs/show_bug.cgi?id=1891; patch at
http://llvm.org/bugs/attachment.cgi?id=1318, and also attached (I
don't know if GMail will mangle it...).
Patch fixes testcases like:
static int *p = (int []){2, 4};
and
typedef struct Test {int a;int b;} Test;
static Test* ll = &(Test) {0,0};
so that they get through sema correctly.
This patch fixes a few underlying issues:
1. It was previously not possible to determine (AFAIK) whether a
CompoundLiteralExpr was file scope or not, so this patch propagates
that information from the parser. This is the biggest change, but is
mostly mechanical.
2. It makes Expr::hasStaticStorage use that information when necessary.
3. It makes Expr::isConstantExpr deal with arrays that aren't
declarations (currently, that's just compound literals).
4. It changes the order of the checks in Sema::CheckSingleInitializer
so that any necessary implicit casts get added before checking for
whether an initializer is constant.
Expr::isConstantExpr definitely needs more work; it is currently
letting through some expressions that aren't constant, like:
static int r[2] = {1,2};
static int ss[2] = {3,4};
static int t = r-ss; // Wrong: Illegal per C99, and impossible to emit to LLVM
static int* zz = &r[t]; // Wrong: Obviously not constant
Expr::hasStaticStorage and Expr::isConstantExpr probably need to be
restructured to deal with cases like &r[t];
-Eli Friedman
Index: Sema/SemaDecl.cpp
===================================================================
--- Sema/SemaDecl.cpp (revision 45425)
+++ Sema/SemaDecl.cpp (working copy)
@@ -354,16 +354,6 @@
bool Sema::CheckSingleInitializer(Expr *&Init, bool isStatic,
QualType DeclType) {
- // FIXME: Remove the isReferenceType check and handle assignment
- // to a reference.
- SourceLocation loc;
- if (isStatic && !DeclType->isReferenceType() &&
- !Init->isConstantExpr(Context, &loc)) { // C99 6.7.8p4.
- assert(loc.isValid() && "isConstantExpr didn't return a loc!");
- Diag(loc, diag::err_init_element_not_constant, Init->getSourceRange());
- return true;
- }
-
AssignmentCheckResult result;
// Get the type before calling CheckSingleAssignmentConstraints(), since
// it can promote the expression.
@@ -405,6 +395,21 @@
Init->getSourceRange());
break;
}
+
+ // This has to be done after checking for assignment
+ // compatibility because those checks might introduce a necessary
+ // implicit conversion (e.g. a static array isn't constant, but a
+ // pointer to a static array is constant).
+ // FIXME: Remove the isReferenceType check and handle assignment
+ // to a reference.
+ SourceLocation loc;
+ if (isStatic && !DeclType->isReferenceType() &&
+ !Init->isConstantExpr(Context, &loc)) { // C99 6.7.8p4.
+ assert(loc.isValid() && "isConstantExpr didn't return a loc!");
+ Diag(loc, diag::err_init_element_not_constant, Init->getSourceRange());
+ return true;
+ }
+
return false;
}
Index: AST/Expr.cpp
===================================================================
--- AST/Expr.cpp (revision 45425)
+++ AST/Expr.cpp (working copy)
@@ -461,12 +461,9 @@
}
case DeclRefExprClass: {
const Decl *D = cast<DeclRefExpr>(this)->getDecl();
- // Accept address of function.
- if (isa<EnumConstantDecl>(D) || isa<FunctionDecl>(D))
+ if (isa<EnumConstantDecl>(D))
return true;
if (Loc) *Loc = getLocStart();
- if (isa<VarDecl>(D))
- return TR->isArrayType();
return false;
}
case UnaryOperatorClass: {
@@ -541,6 +538,19 @@
SubExpr = cast<ImplicitCastExpr>(this)->getSubExpr();
CastLoc = getLocStart();
}
+ if (SubExpr->getType()->isArrayType()) {
+ // FIXME: This check isn't strict enough: the fact that an array has
static scope
+ // doesn't mean the address is computable at compile-time.
+ // FIXME: This code should be shared with the code for
UnaryOperator::AddrOf.
+ if (!SubExpr->hasStaticStorage()) {
+ if (Loc) *Loc = getLocStart();
+ return false;
+ }
+ return true;
+ }
+ // FIXME: Only correct for C, AFAIK. (consider "static Func* f = obj->f;"
in C++)
+ if (SubExpr->getType()->isFunctionType())
+ return true;
if (!SubExpr->isConstantExpr(Ctx, Loc)) {
if (Loc) *Loc = SubExpr->getLocStart();
return false;
_______________________________________________
cfe-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev