Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -3381,7 +3381,7 @@ return false; } APValue Lit; - if (!Evaluate(Lit, Info, CLE->getInitializer())) + if (!EvaluateInPlace(Lit, Info, LVal, CLE->getInitializer())) return false; CompleteObject LitObj(&Lit, Base->getType(), false); return extractSubobject(Info, Conv, LitObj, LVal.Designator, RVal); @@ -5360,6 +5360,11 @@ return HandleBaseToDerivedCast(Info, E, Result); } } + bool VisitInitListExpr(const InitListExpr *E) { + // Initialization for string literals should go through EvaluateInPlace. + assert(!E->isStringLiteralInit()); + return LValueExprEvaluatorBaseTy::VisitInitListExpr(E); + } }; } // end anonymous namespace @@ -7182,6 +7187,11 @@ bool VisitCXXConstructExpr(const CXXConstructExpr *E, const LValue &Subobject, APValue *Value, QualType Type); + bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { + // Compound literals are always lvalues in C. + assert(Info.getLangOpts().CPlusPlus && "Unexpected compound literal"); + return EvaluateInPlace(Result, Info, This, E->getInitializer()); + } }; } // end anonymous namespace @@ -7212,15 +7222,10 @@ if (!CAT) return Error(E); - // C++11 [dcl.init.string]p1: A char array [...] can be initialized by [...] - // an appropriately-typed string literal enclosed in braces. if (E->isStringLiteralInit()) { - LValue LV; - if (!EvaluateLValue(E->getInit(0), LV, Info)) - return false; - APValue Val; - LV.moveInto(Val); - return Success(Val, E); + // In C++11 mode, init lists for string literal inits are lvalues. + assert(!Info.getLangOpts().CPlusPlus11 && "Unexpected init list"); + return EvaluateInPlace(Result, Info, This, E->getInit(0)); } bool Success = true; @@ -10921,6 +10926,35 @@ } } + if (This.getLValueDesignator().MostDerivedType->isArrayType()) { + // We're initializing a value with "lvalue" array. It isn't really + // an lvalue, though. There are a few ways to land in this situation, + // currently: + // + // 1. String literal initialization ([dcl.init.string]). + // 2. @encode literal initialization (essentially the same as string + // literal initialization). + // 3. The GNU compound literal initialization extension: + // "char x[] = (char[]){0}". (Only allowed in C.) + // + // Bail out for now if we see a compound literal. + if (auto *CLE = dyn_cast(E->IgnoreParens())) + return false; + // Otherwise, we have some sort of literal we can evaluate as a + // constant array. + assert(isa(E->IgnoreParens()) || + isa(E->IgnoreParens()) || + isa(E->IgnoreParens())); + LValue LV; + if (!EvaluateLValue(E, LV, Info)) + llvm_unreachable("String literal init can't fail"); + + // Semantically, we should convert the LValue into an array, but currently + // we skip that step, and expect users to convert if necessary. + LV.moveInto(Result); + return true; + } + // For any other type, in-place evaluation is unimportant. return Evaluate(Result, Info, E); }