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(this)->getDecl(); - // Accept address of function. - if (isa(D) || isa(D)) + if (isa(D)) return true; if (Loc) *Loc = getLocStart(); - if (isa(D)) - return TR->isArrayType(); return false; } case UnaryOperatorClass: { @@ -541,6 +538,19 @@ SubExpr = cast(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;