01.06.2015, 17:31, "Jonathan Roelofs" <[email protected]>:
> +cfe-commits
>
> On 6/1/15 7:56 AM, Косов Евгений wrote:
>>  Hello.
>>
>>  https://llvm.org/bugs/show_bug.cgi?id=21945
>>  Fix is simple - do not enter in a loop body iterating an empty container.
>
> Going forward, Clang patches should be sent to [email protected].

Thanks for the info.

> Also, please upload patches with more context (i.e. `git diff -U999`).

Why so much? Because you don't apply patch but just read through it?

>>  If the patch is ok how can it be committed into trunk?
>
> While you're here, mind putting an llvm_unreachable after the loop body?

Sure, why not?

>>  Do I need to sign something?
>
> No. You can get commit access by following:
> http://llvm.org/docs/DeveloperPolicy.html#id16, or one of us can commit
> it for you after you've got a "LGTM" on it.

For now I don't need commit rights. So if my patch is ok please commit it.

>
> Cheers,
>
> Jon
>>  Eugene
>>
>>  _______________________________________________
>>  llvm-commits mailing list
>>  [email protected]
>>  http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> --
> Jon Roelofs
> [email protected]
> CodeSourcery / Mentor Embedded

Eugene
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp	(revision 238723)
+++ lib/AST/ExprConstant.cpp	(working copy)
@@ -3280,2023 +3280,2028 @@
 static EvalStmtResult EvaluateSwitch(APValue &Result, EvalInfo &Info,
                                      const SwitchStmt *SS) {
   BlockScopeRAII Scope(Info);
 
   // Evaluate the switch condition.
   APSInt Value;
   {
     FullExpressionRAII Scope(Info);
     if (SS->getConditionVariable() &&
         !EvaluateDecl(Info, SS->getConditionVariable()))
       return ESR_Failed;
     if (!EvaluateInteger(SS->getCond(), Value, Info))
       return ESR_Failed;
   }
 
   // Find the switch case corresponding to the value of the condition.
   // FIXME: Cache this lookup.
   const SwitchCase *Found = nullptr;
   for (const SwitchCase *SC = SS->getSwitchCaseList(); SC;
        SC = SC->getNextSwitchCase()) {
     if (isa<DefaultStmt>(SC)) {
       Found = SC;
       continue;
     }
 
     const CaseStmt *CS = cast<CaseStmt>(SC);
     APSInt LHS = CS->getLHS()->EvaluateKnownConstInt(Info.Ctx);
     APSInt RHS = CS->getRHS() ? CS->getRHS()->EvaluateKnownConstInt(Info.Ctx)
                               : LHS;
     if (LHS <= Value && Value <= RHS) {
       Found = SC;
       break;
     }
   }
 
   if (!Found)
     return ESR_Succeeded;
 
   // Search the switch body for the switch case and evaluate it from there.
   switch (EvalStmtResult ESR = EvaluateStmt(Result, Info, SS->getBody(), Found)) {
   case ESR_Break:
     return ESR_Succeeded;
   case ESR_Succeeded:
   case ESR_Continue:
   case ESR_Failed:
   case ESR_Returned:
     return ESR;
   case ESR_CaseNotFound:
     // This can only happen if the switch case is nested within a statement
     // expression. We have no intention of supporting that.
     Info.Diag(Found->getLocStart(), diag::note_constexpr_stmt_expr_unsupported);
     return ESR_Failed;
   }
   llvm_unreachable("Invalid EvalStmtResult!");
 }
 
 // Evaluate a statement.
 static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
                                    const Stmt *S, const SwitchCase *Case) {
   if (!Info.nextStep(S))
     return ESR_Failed;
 
   // If we're hunting down a 'case' or 'default' label, recurse through
   // substatements until we hit the label.
   if (Case) {
     // FIXME: We don't start the lifetime of objects whose initialization we
     // jump over. However, such objects must be of class type with a trivial
     // default constructor that initialize all subobjects, so must be empty,
     // so this almost never matters.
     switch (S->getStmtClass()) {
     case Stmt::CompoundStmtClass:
       // FIXME: Precompute which substatement of a compound statement we
       // would jump to, and go straight there rather than performing a
       // linear scan each time.
     case Stmt::LabelStmtClass:
     case Stmt::AttributedStmtClass:
     case Stmt::DoStmtClass:
       break;
 
     case Stmt::CaseStmtClass:
     case Stmt::DefaultStmtClass:
       if (Case == S)
         Case = nullptr;
       break;
 
     case Stmt::IfStmtClass: {
       // FIXME: Precompute which side of an 'if' we would jump to, and go
       // straight there rather than scanning both sides.
       const IfStmt *IS = cast<IfStmt>(S);
 
       // Wrap the evaluation in a block scope, in case it's a DeclStmt
       // preceded by our switch label.
       BlockScopeRAII Scope(Info);
 
       EvalStmtResult ESR = EvaluateStmt(Result, Info, IS->getThen(), Case);
       if (ESR != ESR_CaseNotFound || !IS->getElse())
         return ESR;
       return EvaluateStmt(Result, Info, IS->getElse(), Case);
     }
 
     case Stmt::WhileStmtClass: {
       EvalStmtResult ESR =
           EvaluateLoopBody(Result, Info, cast<WhileStmt>(S)->getBody(), Case);
       if (ESR != ESR_Continue)
         return ESR;
       break;
     }
 
     case Stmt::ForStmtClass: {
       const ForStmt *FS = cast<ForStmt>(S);
       EvalStmtResult ESR =
           EvaluateLoopBody(Result, Info, FS->getBody(), Case);
       if (ESR != ESR_Continue)
         return ESR;
       if (FS->getInc()) {
         FullExpressionRAII IncScope(Info);
         if (!EvaluateIgnoredValue(Info, FS->getInc()))
           return ESR_Failed;
       }
       break;
     }
 
     case Stmt::DeclStmtClass:
       // FIXME: If the variable has initialization that can't be jumped over,
       // bail out of any immediately-surrounding compound-statement too.
     default:
       return ESR_CaseNotFound;
     }
   }
 
   switch (S->getStmtClass()) {
   default:
     if (const Expr *E = dyn_cast<Expr>(S)) {
       // Don't bother evaluating beyond an expression-statement which couldn't
       // be evaluated.
       FullExpressionRAII Scope(Info);
       if (!EvaluateIgnoredValue(Info, E))
         return ESR_Failed;
       return ESR_Succeeded;
     }
 
     Info.Diag(S->getLocStart());
     return ESR_Failed;
 
   case Stmt::NullStmtClass:
     return ESR_Succeeded;
 
   case Stmt::DeclStmtClass: {
     const DeclStmt *DS = cast<DeclStmt>(S);
     for (const auto *DclIt : DS->decls()) {
       // Each declaration initialization is its own full-expression.
       // FIXME: This isn't quite right; if we're performing aggregate
       // initialization, each braced subexpression is its own full-expression.
       FullExpressionRAII Scope(Info);
       if (!EvaluateDecl(Info, DclIt) && !Info.keepEvaluatingAfterFailure())
         return ESR_Failed;
     }
     return ESR_Succeeded;
   }
 
   case Stmt::ReturnStmtClass: {
     const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
     FullExpressionRAII Scope(Info);
     if (RetExpr && !Evaluate(Result, Info, RetExpr))
       return ESR_Failed;
     return ESR_Returned;
   }
 
   case Stmt::CompoundStmtClass: {
     BlockScopeRAII Scope(Info);
 
     const CompoundStmt *CS = cast<CompoundStmt>(S);
     for (const auto *BI : CS->body()) {
       EvalStmtResult ESR = EvaluateStmt(Result, Info, BI, Case);
       if (ESR == ESR_Succeeded)
         Case = nullptr;
       else if (ESR != ESR_CaseNotFound)
         return ESR;
     }
     return Case ? ESR_CaseNotFound : ESR_Succeeded;
   }
 
   case Stmt::IfStmtClass: {
     const IfStmt *IS = cast<IfStmt>(S);
 
     // Evaluate the condition, as either a var decl or as an expression.
     BlockScopeRAII Scope(Info);
     bool Cond;
     if (!EvaluateCond(Info, IS->getConditionVariable(), IS->getCond(), Cond))
       return ESR_Failed;
 
     if (const Stmt *SubStmt = Cond ? IS->getThen() : IS->getElse()) {
       EvalStmtResult ESR = EvaluateStmt(Result, Info, SubStmt);
       if (ESR != ESR_Succeeded)
         return ESR;
     }
     return ESR_Succeeded;
   }
 
   case Stmt::WhileStmtClass: {
     const WhileStmt *WS = cast<WhileStmt>(S);
     while (true) {
       BlockScopeRAII Scope(Info);
       bool Continue;
       if (!EvaluateCond(Info, WS->getConditionVariable(), WS->getCond(),
                         Continue))
         return ESR_Failed;
       if (!Continue)
         break;
 
       EvalStmtResult ESR = EvaluateLoopBody(Result, Info, WS->getBody());
       if (ESR != ESR_Continue)
         return ESR;
     }
     return ESR_Succeeded;
   }
 
   case Stmt::DoStmtClass: {
     const DoStmt *DS = cast<DoStmt>(S);
     bool Continue;
     do {
       EvalStmtResult ESR = EvaluateLoopBody(Result, Info, DS->getBody(), Case);
       if (ESR != ESR_Continue)
         return ESR;
       Case = nullptr;
 
       FullExpressionRAII CondScope(Info);
       if (!EvaluateAsBooleanCondition(DS->getCond(), Continue, Info))
         return ESR_Failed;
     } while (Continue);
     return ESR_Succeeded;
   }
 
   case Stmt::ForStmtClass: {
     const ForStmt *FS = cast<ForStmt>(S);
     BlockScopeRAII Scope(Info);
     if (FS->getInit()) {
       EvalStmtResult ESR = EvaluateStmt(Result, Info, FS->getInit());
       if (ESR != ESR_Succeeded)
         return ESR;
     }
     while (true) {
       BlockScopeRAII Scope(Info);
       bool Continue = true;
       if (FS->getCond() && !EvaluateCond(Info, FS->getConditionVariable(),
                                          FS->getCond(), Continue))
         return ESR_Failed;
       if (!Continue)
         break;
 
       EvalStmtResult ESR = EvaluateLoopBody(Result, Info, FS->getBody());
       if (ESR != ESR_Continue)
         return ESR;
 
       if (FS->getInc()) {
         FullExpressionRAII IncScope(Info);
         if (!EvaluateIgnoredValue(Info, FS->getInc()))
           return ESR_Failed;
       }
     }
     return ESR_Succeeded;
   }
 
   case Stmt::CXXForRangeStmtClass: {
     const CXXForRangeStmt *FS = cast<CXXForRangeStmt>(S);
     BlockScopeRAII Scope(Info);
 
     // Initialize the __range variable.
     EvalStmtResult ESR = EvaluateStmt(Result, Info, FS->getRangeStmt());
     if (ESR != ESR_Succeeded)
       return ESR;
 
     // Create the __begin and __end iterators.
     ESR = EvaluateStmt(Result, Info, FS->getBeginEndStmt());
     if (ESR != ESR_Succeeded)
       return ESR;
 
     while (true) {
       // Condition: __begin != __end.
       {
         bool Continue = true;
         FullExpressionRAII CondExpr(Info);
         if (!EvaluateAsBooleanCondition(FS->getCond(), Continue, Info))
           return ESR_Failed;
         if (!Continue)
           break;
       }
 
       // User's variable declaration, initialized by *__begin.
       BlockScopeRAII InnerScope(Info);
       ESR = EvaluateStmt(Result, Info, FS->getLoopVarStmt());
       if (ESR != ESR_Succeeded)
         return ESR;
 
       // Loop body.
       ESR = EvaluateLoopBody(Result, Info, FS->getBody());
       if (ESR != ESR_Continue)
         return ESR;
 
       // Increment: ++__begin
       if (!EvaluateIgnoredValue(Info, FS->getInc()))
         return ESR_Failed;
     }
 
     return ESR_Succeeded;
   }
 
   case Stmt::SwitchStmtClass:
     return EvaluateSwitch(Result, Info, cast<SwitchStmt>(S));
 
   case Stmt::ContinueStmtClass:
     return ESR_Continue;
 
   case Stmt::BreakStmtClass:
     return ESR_Break;
 
   case Stmt::LabelStmtClass:
     return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
 
   case Stmt::AttributedStmtClass:
     // As a general principle, C++11 attributes can be ignored without
     // any semantic impact.
     return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
                         Case);
 
   case Stmt::CaseStmtClass:
   case Stmt::DefaultStmtClass:
     return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
   }
 }
 
 /// CheckTrivialDefaultConstructor - Check whether a constructor is a trivial
 /// default constructor. If so, we'll fold it whether or not it's marked as
 /// constexpr. If it is marked as constexpr, we will never implicitly define it,
 /// so we need special handling.
 static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc,
                                            const CXXConstructorDecl *CD,
                                            bool IsValueInitialization) {
   if (!CD->isTrivial() || !CD->isDefaultConstructor())
     return false;
 
   // Value-initialization does not call a trivial default constructor, so such a
   // call is a core constant expression whether or not the constructor is
   // constexpr.
   if (!CD->isConstexpr() && !IsValueInitialization) {
     if (Info.getLangOpts().CPlusPlus11) {
       // FIXME: If DiagDecl is an implicitly-declared special member function,
       // we should be much more explicit about why it's not constexpr.
       Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
         << /*IsConstexpr*/0 << /*IsConstructor*/1 << CD;
       Info.Note(CD->getLocation(), diag::note_declared_at);
     } else {
       Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
     }
   }
   return true;
 }
 
 /// CheckConstexprFunction - Check that a function can be called in a constant
 /// expression.
 static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc,
                                    const FunctionDecl *Declaration,
                                    const FunctionDecl *Definition) {
   // Potential constant expressions can contain calls to declared, but not yet
   // defined, constexpr functions.
   if (Info.checkingPotentialConstantExpression() && !Definition &&
       Declaration->isConstexpr())
     return false;
 
   // Bail out with no diagnostic if the function declaration itself is invalid.
   // We will have produced a relevant diagnostic while parsing it.
   if (Declaration->isInvalidDecl())
     return false;
 
   // Can we evaluate this function call?
   if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl())
     return true;
 
   if (Info.getLangOpts().CPlusPlus11) {
     const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
     // FIXME: If DiagDecl is an implicitly-declared special member function, we
     // should be much more explicit about why it's not constexpr.
     Info.Diag(CallLoc, diag::note_constexpr_invalid_function, 1)
       << DiagDecl->isConstexpr() << isa<CXXConstructorDecl>(DiagDecl)
       << DiagDecl;
     Info.Note(DiagDecl->getLocation(), diag::note_declared_at);
   } else {
     Info.Diag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
   }
   return false;
 }
 
 /// Determine if a class has any fields that might need to be copied by a
 /// trivial copy or move operation.
 static bool hasFields(const CXXRecordDecl *RD) {
   if (!RD || RD->isEmpty())
     return false;
   for (auto *FD : RD->fields()) {
     if (FD->isUnnamedBitfield())
       continue;
     return true;
   }
   for (auto &Base : RD->bases())
     if (hasFields(Base.getType()->getAsCXXRecordDecl()))
       return true;
   return false;
 }
 
 namespace {
 typedef SmallVector<APValue, 8> ArgVector;
 }
 
 /// EvaluateArgs - Evaluate the arguments to a function call.
 static bool EvaluateArgs(ArrayRef<const Expr*> Args, ArgVector &ArgValues,
                          EvalInfo &Info) {
   bool Success = true;
   for (ArrayRef<const Expr*>::iterator I = Args.begin(), E = Args.end();
        I != E; ++I) {
     if (!Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
       // If we're checking for a potential constant expression, evaluate all
       // initializers even if some of them fail.
       if (!Info.keepEvaluatingAfterFailure())
         return false;
       Success = false;
     }
   }
   return Success;
 }
 
 /// Evaluate a function call.
 static bool HandleFunctionCall(SourceLocation CallLoc,
                                const FunctionDecl *Callee, const LValue *This,
                                ArrayRef<const Expr*> Args, const Stmt *Body,
                                EvalInfo &Info, APValue &Result) {
   ArgVector ArgValues(Args.size());
   if (!EvaluateArgs(Args, ArgValues, Info))
     return false;
 
   if (!Info.CheckCallLimit(CallLoc))
     return false;
 
   CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
 
   // For a trivial copy or move assignment, perform an APValue copy. This is
   // essential for unions, where the operations performed by the assignment
   // operator cannot be represented as statements.
   //
   // Skip this for non-union classes with no fields; in that case, the defaulted
   // copy/move does not actually read the object.
   const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee);
   if (MD && MD->isDefaulted() &&
       (MD->getParent()->isUnion() ||
        (MD->isTrivial() && hasFields(MD->getParent())))) {
     assert(This &&
            (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
     LValue RHS;
     RHS.setFrom(Info.Ctx, ArgValues[0]);
     APValue RHSValue;
     if (!handleLValueToRValueConversion(Info, Args[0], Args[0]->getType(),
                                         RHS, RHSValue))
       return false;
     if (!handleAssignment(Info, Args[0], *This, MD->getThisType(Info.Ctx),
                           RHSValue))
       return false;
     This->moveInto(Result);
     return true;
   }
 
   EvalStmtResult ESR = EvaluateStmt(Result, Info, Body);
   if (ESR == ESR_Succeeded) {
     if (Callee->getReturnType()->isVoidType())
       return true;
     Info.Diag(Callee->getLocEnd(), diag::note_constexpr_no_return);
   }
   return ESR == ESR_Returned;
 }
 
 /// Evaluate a constructor call.
 static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
                                   ArrayRef<const Expr*> Args,
                                   const CXXConstructorDecl *Definition,
                                   EvalInfo &Info, APValue &Result) {
   ArgVector ArgValues(Args.size());
   if (!EvaluateArgs(Args, ArgValues, Info))
     return false;
 
   if (!Info.CheckCallLimit(CallLoc))
     return false;
 
   const CXXRecordDecl *RD = Definition->getParent();
   if (RD->getNumVBases()) {
     Info.Diag(CallLoc, diag::note_constexpr_virtual_base) << RD;
     return false;
   }
 
   CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues.data());
 
   // If it's a delegating constructor, just delegate.
   if (Definition->isDelegatingConstructor()) {
     CXXConstructorDecl::init_const_iterator I = Definition->init_begin();
     {
       FullExpressionRAII InitScope(Info);
       if (!EvaluateInPlace(Result, Info, This, (*I)->getInit()))
         return false;
     }
     return EvaluateStmt(Result, Info, Definition->getBody()) != ESR_Failed;
   }
 
   // For a trivial copy or move constructor, perform an APValue copy. This is
   // essential for unions (or classes with anonymous union members), where the
   // operations performed by the constructor cannot be represented by
   // ctor-initializers.
   //
   // Skip this for empty non-union classes; we should not perform an
   // lvalue-to-rvalue conversion on them because their copy constructor does not
   // actually read them.
   if (Definition->isDefaulted() && Definition->isCopyOrMoveConstructor() &&
       (Definition->getParent()->isUnion() ||
        (Definition->isTrivial() && hasFields(Definition->getParent())))) {
     LValue RHS;
     RHS.setFrom(Info.Ctx, ArgValues[0]);
     return handleLValueToRValueConversion(Info, Args[0], Args[0]->getType(),
                                           RHS, Result);
   }
 
   // Reserve space for the struct members.
   if (!RD->isUnion() && Result.isUninit())
     Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
                      std::distance(RD->field_begin(), RD->field_end()));
 
   if (RD->isInvalidDecl()) return false;
   const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
 
   // A scope for temporaries lifetime-extended by reference members.
   BlockScopeRAII LifetimeExtendedScope(Info);
 
   bool Success = true;
   unsigned BasesSeen = 0;
 #ifndef NDEBUG
   CXXRecordDecl::base_class_const_iterator BaseIt = RD->bases_begin();
 #endif
   for (const auto *I : Definition->inits()) {
     LValue Subobject = This;
     APValue *Value = &Result;
 
     // Determine the subobject to initialize.
     FieldDecl *FD = nullptr;
     if (I->isBaseInitializer()) {
       QualType BaseType(I->getBaseClass(), 0);
 #ifndef NDEBUG
       // Non-virtual base classes are initialized in the order in the class
       // definition. We have already checked for virtual base classes.
       assert(!BaseIt->isVirtual() && "virtual base for literal type");
       assert(Info.Ctx.hasSameType(BaseIt->getType(), BaseType) &&
              "base class initializers not in expected order");
       ++BaseIt;
 #endif
       if (!HandleLValueDirectBase(Info, I->getInit(), Subobject, RD,
                                   BaseType->getAsCXXRecordDecl(), &Layout))
         return false;
       Value = &Result.getStructBase(BasesSeen++);
     } else if ((FD = I->getMember())) {
       if (!HandleLValueMember(Info, I->getInit(), Subobject, FD, &Layout))
         return false;
       if (RD->isUnion()) {
         Result = APValue(FD);
         Value = &Result.getUnionValue();
       } else {
         Value = &Result.getStructField(FD->getFieldIndex());
       }
     } else if (IndirectFieldDecl *IFD = I->getIndirectMember()) {
       // Walk the indirect field decl's chain to find the object to initialize,
       // and make sure we've initialized every step along it.
       for (auto *C : IFD->chain()) {
         FD = cast<FieldDecl>(C);
         CXXRecordDecl *CD = cast<CXXRecordDecl>(FD->getParent());
         // Switch the union field if it differs. This happens if we had
         // preceding zero-initialization, and we're now initializing a union
         // subobject other than the first.
         // FIXME: In this case, the values of the other subobjects are
         // specified, since zero-initialization sets all padding bits to zero.
         if (Value->isUninit() ||
             (Value->isUnion() && Value->getUnionField() != FD)) {
           if (CD->isUnion())
             *Value = APValue(FD);
           else
             *Value = APValue(APValue::UninitStruct(), CD->getNumBases(),
                              std::distance(CD->field_begin(), CD->field_end()));
         }
         if (!HandleLValueMember(Info, I->getInit(), Subobject, FD))
           return false;
         if (CD->isUnion())
           Value = &Value->getUnionValue();
         else
           Value = &Value->getStructField(FD->getFieldIndex());
       }
     } else {
       llvm_unreachable("unknown base initializer kind");
     }
 
     FullExpressionRAII InitScope(Info);
     if (!EvaluateInPlace(*Value, Info, Subobject, I->getInit()) ||
         (FD && FD->isBitField() && !truncateBitfieldValue(Info, I->getInit(),
                                                           *Value, FD))) {
       // If we're checking for a potential constant expression, evaluate all
       // initializers even if some of them fail.
       if (!Info.keepEvaluatingAfterFailure())
         return false;
       Success = false;
     }
   }
 
   return Success &&
          EvaluateStmt(Result, Info, Definition->getBody()) != ESR_Failed;
 }
 
 //===----------------------------------------------------------------------===//
 // Generic Evaluation
 //===----------------------------------------------------------------------===//
 namespace {
 
 template <class Derived>
 class ExprEvaluatorBase
   : public ConstStmtVisitor<Derived, bool> {
 private:
   bool DerivedSuccess(const APValue &V, const Expr *E) {
     return static_cast<Derived*>(this)->Success(V, E);
   }
   bool DerivedZeroInitialization(const Expr *E) {
     return static_cast<Derived*>(this)->ZeroInitialization(E);
   }
 
   // Check whether a conditional operator with a non-constant condition is a
   // potential constant expression. If neither arm is a potential constant
   // expression, then the conditional operator is not either.
   template<typename ConditionalOperator>
   void CheckPotentialConstantConditional(const ConditionalOperator *E) {
     assert(Info.checkingPotentialConstantExpression());
 
     // Speculatively evaluate both arms.
     {
       SmallVector<PartialDiagnosticAt, 8> Diag;
       SpeculativeEvaluationRAII Speculate(Info, &Diag);
 
       StmtVisitorTy::Visit(E->getFalseExpr());
       if (Diag.empty())
         return;
 
       Diag.clear();
       StmtVisitorTy::Visit(E->getTrueExpr());
       if (Diag.empty())
         return;
     }
 
     Error(E, diag::note_constexpr_conditional_never_const);
   }
 
 
   template<typename ConditionalOperator>
   bool HandleConditionalOperator(const ConditionalOperator *E) {
     bool BoolResult;
     if (!EvaluateAsBooleanCondition(E->getCond(), BoolResult, Info)) {
       if (Info.checkingPotentialConstantExpression())
         CheckPotentialConstantConditional(E);
       return false;
     }
 
     Expr *EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
     return StmtVisitorTy::Visit(EvalExpr);
   }
 
 protected:
   EvalInfo &Info;
   typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
   typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
 
   OptionalDiagnostic CCEDiag(const Expr *E, diag::kind D) {
     return Info.CCEDiag(E, D);
   }
 
   bool ZeroInitialization(const Expr *E) { return Error(E); }
 
 public:
   ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
 
   EvalInfo &getEvalInfo() { return Info; }
 
   /// Report an evaluation error. This should only be called when an error is
   /// first discovered. When propagating an error, just return false.
   bool Error(const Expr *E, diag::kind D) {
     Info.Diag(E, D);
     return false;
   }
   bool Error(const Expr *E) {
     return Error(E, diag::note_invalid_subexpr_in_const_expr);
   }
 
   bool VisitStmt(const Stmt *) {
     llvm_unreachable("Expression evaluator should not be called on stmts");
   }
   bool VisitExpr(const Expr *E) {
     return Error(E);
   }
 
   bool VisitParenExpr(const ParenExpr *E)
     { return StmtVisitorTy::Visit(E->getSubExpr()); }
   bool VisitUnaryExtension(const UnaryOperator *E)
     { return StmtVisitorTy::Visit(E->getSubExpr()); }
   bool VisitUnaryPlus(const UnaryOperator *E)
     { return StmtVisitorTy::Visit(E->getSubExpr()); }
   bool VisitChooseExpr(const ChooseExpr *E)
     { return StmtVisitorTy::Visit(E->getChosenSubExpr()); }
   bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
     { return StmtVisitorTy::Visit(E->getResultExpr()); }
   bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
     { return StmtVisitorTy::Visit(E->getReplacement()); }
   bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
     { return StmtVisitorTy::Visit(E->getExpr()); }
   bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
     // The initializer may not have been parsed yet, or might be erroneous.
     if (!E->getExpr())
       return Error(E);
     return StmtVisitorTy::Visit(E->getExpr());
   }
   // We cannot create any objects for which cleanups are required, so there is
   // nothing to do here; all cleanups must come from unevaluated subexpressions.
   bool VisitExprWithCleanups(const ExprWithCleanups *E)
     { return StmtVisitorTy::Visit(E->getSubExpr()); }
 
   bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E) {
     CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
     return static_cast<Derived*>(this)->VisitCastExpr(E);
   }
   bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
     CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
     return static_cast<Derived*>(this)->VisitCastExpr(E);
   }
 
   bool VisitBinaryOperator(const BinaryOperator *E) {
     switch (E->getOpcode()) {
     default:
       return Error(E);
 
     case BO_Comma:
       VisitIgnoredValue(E->getLHS());
       return StmtVisitorTy::Visit(E->getRHS());
 
     case BO_PtrMemD:
     case BO_PtrMemI: {
       LValue Obj;
       if (!HandleMemberPointerAccess(Info, E, Obj))
         return false;
       APValue Result;
       if (!handleLValueToRValueConversion(Info, E, E->getType(), Obj, Result))
         return false;
       return DerivedSuccess(Result, E);
     }
     }
   }
 
   bool VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) {
     // Evaluate and cache the common expression. We treat it as a temporary,
     // even though it's not quite the same thing.
     if (!Evaluate(Info.CurrentCall->createTemporary(E->getOpaqueValue(), false),
                   Info, E->getCommon()))
       return false;
 
     return HandleConditionalOperator(E);
   }
 
   bool VisitConditionalOperator(const ConditionalOperator *E) {
     bool IsBcpCall = false;
     // If the condition (ignoring parens) is a __builtin_constant_p call,
     // the result is a constant expression if it can be folded without
     // side-effects. This is an important GNU extension. See GCC PR38377
     // for discussion.
     if (const CallExpr *CallCE =
           dyn_cast<CallExpr>(E->getCond()->IgnoreParenCasts()))
       if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
         IsBcpCall = true;
 
     // Always assume __builtin_constant_p(...) ? ... : ... is a potential
     // constant expression; we can't check whether it's potentially foldable.
     if (Info.checkingPotentialConstantExpression() && IsBcpCall)
       return false;
 
     FoldConstant Fold(Info, IsBcpCall);
     if (!HandleConditionalOperator(E)) {
       Fold.keepDiagnostics();
       return false;
     }
 
     return true;
   }
 
   bool VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
     if (APValue *Value = Info.CurrentCall->getTemporary(E))
       return DerivedSuccess(*Value, E);
 
     const Expr *Source = E->getSourceExpr();
     if (!Source)
       return Error(E);
     if (Source == E) { // sanity checking.
       assert(0 && "OpaqueValueExpr recursively refers to itself");
       return Error(E);
     }
     return StmtVisitorTy::Visit(Source);
   }
 
   bool VisitCallExpr(const CallExpr *E) {
     const Expr *Callee = E->getCallee()->IgnoreParens();
     QualType CalleeType = Callee->getType();
 
     const FunctionDecl *FD = nullptr;
     LValue *This = nullptr, ThisVal;
     auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs());
     bool HasQualifier = false;
 
     // Extract function decl and 'this' pointer from the callee.
     if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
       const ValueDecl *Member = nullptr;
       if (const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
         // Explicit bound member calls, such as x.f() or p->g();
         if (!EvaluateObjectArgument(Info, ME->getBase(), ThisVal))
           return false;
         Member = ME->getMemberDecl();
         This = &ThisVal;
         HasQualifier = ME->hasQualifier();
       } else if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
         // Indirect bound member calls ('.*' or '->*').
         Member = HandleMemberPointerAccess(Info, BE, ThisVal, false);
         if (!Member) return false;
         This = &ThisVal;
       } else
         return Error(Callee);
 
       FD = dyn_cast<FunctionDecl>(Member);
       if (!FD)
         return Error(Callee);
     } else if (CalleeType->isFunctionPointerType()) {
       LValue Call;
       if (!EvaluatePointer(Callee, Call, Info))
         return false;
 
       if (!Call.getLValueOffset().isZero())
         return Error(Callee);
       FD = dyn_cast_or_null<FunctionDecl>(
                              Call.getLValueBase().dyn_cast<const ValueDecl*>());
       if (!FD)
         return Error(Callee);
 
       // Overloaded operator calls to member functions are represented as normal
       // calls with '*this' as the first argument.
       const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
       if (MD && !MD->isStatic()) {
         // FIXME: When selecting an implicit conversion for an overloaded
         // operator delete, we sometimes try to evaluate calls to conversion
         // operators without a 'this' parameter!
         if (Args.empty())
           return Error(E);
 
         if (!EvaluateObjectArgument(Info, Args[0], ThisVal))
           return false;
         This = &ThisVal;
         Args = Args.slice(1);
       }
 
       // Don't call function pointers which have been cast to some other type.
       if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType()))
         return Error(E);
     } else
       return Error(E);
 
     if (This && !This->checkSubobject(Info, E, CSK_This))
       return false;
 
     // DR1358 allows virtual constexpr functions in some cases. Don't allow
     // calls to such functions in constant expressions.
     if (This && !HasQualifier &&
         isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
       return Error(E, diag::note_constexpr_virtual_call);
 
     const FunctionDecl *Definition = nullptr;
     Stmt *Body = FD->getBody(Definition);
     APValue Result;
 
     if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition) ||
         !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body,
                             Info, Result))
       return false;
 
     return DerivedSuccess(Result, E);
   }
 
   bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
     return StmtVisitorTy::Visit(E->getInitializer());
   }
   bool VisitInitListExpr(const InitListExpr *E) {
     if (E->getNumInits() == 0)
       return DerivedZeroInitialization(E);
     if (E->getNumInits() == 1)
       return StmtVisitorTy::Visit(E->getInit(0));
     return Error(E);
   }
   bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
     return DerivedZeroInitialization(E);
   }
   bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
     return DerivedZeroInitialization(E);
   }
   bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
     return DerivedZeroInitialization(E);
   }
 
   /// A member expression where the object is a prvalue is itself a prvalue.
   bool VisitMemberExpr(const MemberExpr *E) {
     assert(!E->isArrow() && "missing call to bound member function?");
 
     APValue Val;
     if (!Evaluate(Val, Info, E->getBase()))
       return false;
 
     QualType BaseTy = E->getBase()->getType();
 
     const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
     if (!FD) return Error(E);
     assert(!FD->getType()->isReferenceType() && "prvalue reference?");
     assert(BaseTy->castAs<RecordType>()->getDecl()->getCanonicalDecl() ==
            FD->getParent()->getCanonicalDecl() && "record / field mismatch");
 
     CompleteObject Obj(&Val, BaseTy);
     SubobjectDesignator Designator(BaseTy);
     Designator.addDeclUnchecked(FD);
 
     APValue Result;
     return extractSubobject(Info, E, Obj, Designator, Result) &&
            DerivedSuccess(Result, E);
   }
 
   bool VisitCastExpr(const CastExpr *E) {
     switch (E->getCastKind()) {
     default:
       break;
 
     case CK_AtomicToNonAtomic: {
       APValue AtomicVal;
       if (!EvaluateAtomic(E->getSubExpr(), AtomicVal, Info))
         return false;
       return DerivedSuccess(AtomicVal, E);
     }
 
     case CK_NoOp:
     case CK_UserDefinedConversion:
       return StmtVisitorTy::Visit(E->getSubExpr());
 
     case CK_LValueToRValue: {
       LValue LVal;
       if (!EvaluateLValue(E->getSubExpr(), LVal, Info))
         return false;
       APValue RVal;
       // Note, we use the subexpression's type in order to retain cv-qualifiers.
       if (!handleLValueToRValueConversion(Info, E, E->getSubExpr()->getType(),
                                           LVal, RVal))
         return false;
       return DerivedSuccess(RVal, E);
     }
     }
 
     return Error(E);
   }
 
   bool VisitUnaryPostInc(const UnaryOperator *UO) {
     return VisitUnaryPostIncDec(UO);
   }
   bool VisitUnaryPostDec(const UnaryOperator *UO) {
     return VisitUnaryPostIncDec(UO);
   }
   bool VisitUnaryPostIncDec(const UnaryOperator *UO) {
     if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
       return Error(UO);
 
     LValue LVal;
     if (!EvaluateLValue(UO->getSubExpr(), LVal, Info))
       return false;
     APValue RVal;
     if (!handleIncDec(this->Info, UO, LVal, UO->getSubExpr()->getType(),
                       UO->isIncrementOp(), &RVal))
       return false;
     return DerivedSuccess(RVal, UO);
   }
 
   bool VisitStmtExpr(const StmtExpr *E) {
     // We will have checked the full-expressions inside the statement expression
     // when they were completed, and don't need to check them again now.
     if (Info.checkingForOverflow())
       return Error(E);
 
     BlockScopeRAII Scope(Info);
     const CompoundStmt *CS = E->getSubStmt();
+    if (CS->body_empty())
+      return true;
+
     for (CompoundStmt::const_body_iterator BI = CS->body_begin(),
                                            BE = CS->body_end();
          /**/; ++BI) {
       if (BI + 1 == BE) {
         const Expr *FinalExpr = dyn_cast<Expr>(*BI);
         if (!FinalExpr) {
           Info.Diag((*BI)->getLocStart(),
                     diag::note_constexpr_stmt_expr_unsupported);
           return false;
         }
         return this->Visit(FinalExpr);
       }
 
       APValue ReturnValue;
       EvalStmtResult ESR = EvaluateStmt(ReturnValue, Info, *BI);
       if (ESR != ESR_Succeeded) {
         // FIXME: If the statement-expression terminated due to 'return',
         // 'break', or 'continue', it would be nice to propagate that to
         // the outer statement evaluation rather than bailing out.
         if (ESR != ESR_Failed)
           Info.Diag((*BI)->getLocStart(),
                     diag::note_constexpr_stmt_expr_unsupported);
         return false;
       }
     }
+
+    llvm_unreachable("Return from function from the loop above.");
   }
 
   /// Visit a value which is evaluated, but whose value is ignored.
   void VisitIgnoredValue(const Expr *E) {
     EvaluateIgnoredValue(Info, E);
   }
 };
 
 }
 
 //===----------------------------------------------------------------------===//
 // Common base class for lvalue and temporary evaluation.
 //===----------------------------------------------------------------------===//
 namespace {
 template<class Derived>
 class LValueExprEvaluatorBase
   : public ExprEvaluatorBase<Derived> {
 protected:
   LValue &Result;
   typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
   typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
 
   bool Success(APValue::LValueBase B) {
     Result.set(B);
     return true;
   }
 
 public:
   LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result) :
     ExprEvaluatorBaseTy(Info), Result(Result) {}
 
   bool Success(const APValue &V, const Expr *E) {
     Result.setFrom(this->Info.Ctx, V);
     return true;
   }
 
   bool VisitMemberExpr(const MemberExpr *E) {
     // Handle non-static data members.
     QualType BaseTy;
     if (E->isArrow()) {
       if (!EvaluatePointer(E->getBase(), Result, this->Info))
         return false;
       BaseTy = E->getBase()->getType()->castAs<PointerType>()->getPointeeType();
     } else if (E->getBase()->isRValue()) {
       assert(E->getBase()->getType()->isRecordType());
       if (!EvaluateTemporary(E->getBase(), Result, this->Info))
         return false;
       BaseTy = E->getBase()->getType();
     } else {
       if (!this->Visit(E->getBase()))
         return false;
       BaseTy = E->getBase()->getType();
     }
 
     const ValueDecl *MD = E->getMemberDecl();
     if (const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) {
       assert(BaseTy->getAs<RecordType>()->getDecl()->getCanonicalDecl() ==
              FD->getParent()->getCanonicalDecl() && "record / field mismatch");
       (void)BaseTy;
       if (!HandleLValueMember(this->Info, E, Result, FD))
         return false;
     } else if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
       if (!HandleLValueIndirectMember(this->Info, E, Result, IFD))
         return false;
     } else
       return this->Error(E);
 
     if (MD->getType()->isReferenceType()) {
       APValue RefValue;
       if (!handleLValueToRValueConversion(this->Info, E, MD->getType(), Result,
                                           RefValue))
         return false;
       return Success(RefValue, E);
     }
     return true;
   }
 
   bool VisitBinaryOperator(const BinaryOperator *E) {
     switch (E->getOpcode()) {
     default:
       return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
 
     case BO_PtrMemD:
     case BO_PtrMemI:
       return HandleMemberPointerAccess(this->Info, E, Result);
     }
   }
 
   bool VisitCastExpr(const CastExpr *E) {
     switch (E->getCastKind()) {
     default:
       return ExprEvaluatorBaseTy::VisitCastExpr(E);
 
     case CK_DerivedToBase:
     case CK_UncheckedDerivedToBase:
       if (!this->Visit(E->getSubExpr()))
         return false;
 
       // Now figure out the necessary offset to add to the base LV to get from
       // the derived class to the base class.
       return HandleLValueBasePath(this->Info, E, E->getSubExpr()->getType(),
                                   Result);
     }
   }
 };
 }
 
 //===----------------------------------------------------------------------===//
 // LValue Evaluation
 //
 // This is used for evaluating lvalues (in C and C++), xvalues (in C++11),
 // function designators (in C), decl references to void objects (in C), and
 // temporaries (if building with -Wno-address-of-temporary).
 //
 // LValue evaluation produces values comprising a base expression of one of the
 // following types:
 // - Declarations
 //  * VarDecl
 //  * FunctionDecl
 // - Literals
 //  * CompoundLiteralExpr in C
 //  * StringLiteral
 //  * CXXTypeidExpr
 //  * PredefinedExpr
 //  * ObjCStringLiteralExpr
 //  * ObjCEncodeExpr
 //  * AddrLabelExpr
 //  * BlockExpr
 //  * CallExpr for a MakeStringConstant builtin
 // - Locals and temporaries
 //  * MaterializeTemporaryExpr
 //  * Any Expr, with a CallIndex indicating the function in which the temporary
 //    was evaluated, for cases where the MaterializeTemporaryExpr is missing
 //    from the AST (FIXME).
 //  * A MaterializeTemporaryExpr that has static storage duration, with no
 //    CallIndex, for a lifetime-extended temporary.
 // plus an offset in bytes.
 //===----------------------------------------------------------------------===//
 namespace {
 class LValueExprEvaluator
   : public LValueExprEvaluatorBase<LValueExprEvaluator> {
 public:
   LValueExprEvaluator(EvalInfo &Info, LValue &Result) :
     LValueExprEvaluatorBaseTy(Info, Result) {}
 
   bool VisitVarDecl(const Expr *E, const VarDecl *VD);
   bool VisitUnaryPreIncDec(const UnaryOperator *UO);
 
   bool VisitDeclRefExpr(const DeclRefExpr *E);
   bool VisitPredefinedExpr(const PredefinedExpr *E) { return Success(E); }
   bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
   bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
   bool VisitMemberExpr(const MemberExpr *E);
   bool VisitStringLiteral(const StringLiteral *E) { return Success(E); }
   bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { return Success(E); }
   bool VisitCXXTypeidExpr(const CXXTypeidExpr *E);
   bool VisitCXXUuidofExpr(const CXXUuidofExpr *E);
   bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
   bool VisitUnaryDeref(const UnaryOperator *E);
   bool VisitUnaryReal(const UnaryOperator *E);
   bool VisitUnaryImag(const UnaryOperator *E);
   bool VisitUnaryPreInc(const UnaryOperator *UO) {
     return VisitUnaryPreIncDec(UO);
   }
   bool VisitUnaryPreDec(const UnaryOperator *UO) {
     return VisitUnaryPreIncDec(UO);
   }
   bool VisitBinAssign(const BinaryOperator *BO);
   bool VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
 
   bool VisitCastExpr(const CastExpr *E) {
     switch (E->getCastKind()) {
     default:
       return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
 
     case CK_LValueBitCast:
       this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
       if (!Visit(E->getSubExpr()))
         return false;
       Result.Designator.setInvalid();
       return true;
 
     case CK_BaseToDerived:
       if (!Visit(E->getSubExpr()))
         return false;
       return HandleBaseToDerivedCast(Info, E, Result);
     }
   }
 };
 } // end anonymous namespace
 
 /// Evaluate an expression as an lvalue. This can be legitimately called on
 /// expressions which are not glvalues, in two cases:
 ///  * function designators in C, and
 ///  * "extern void" objects
 static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info) {
   assert(E->isGLValue() || E->getType()->isFunctionType() ||
          E->getType()->isVoidType());
   return LValueExprEvaluator(Info, Result).Visit(E);
 }
 
 bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl()))
     return Success(FD);
   if (const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
     return VisitVarDecl(E, VD);
   return Error(E);
 }
 
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
   CallStackFrame *Frame = nullptr;
   if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
     Frame = Info.CurrentCall;
 
   if (!VD->getType()->isReferenceType()) {
     if (Frame) {
       Result.set(VD, Frame->Index);
       return true;
     }
     return Success(VD);
   }
 
   APValue *V;
   if (!evaluateVarDeclInit(Info, E, VD, Frame, V))
     return false;
   if (V->isUninit()) {
     if (!Info.checkingPotentialConstantExpression())
       Info.Diag(E, diag::note_constexpr_use_uninit_reference);
     return false;
   }
   return Success(*V, E);
 }
 
 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
     const MaterializeTemporaryExpr *E) {
   // Walk through the expression to find the materialized temporary itself.
   SmallVector<const Expr *, 2> CommaLHSs;
   SmallVector<SubobjectAdjustment, 2> Adjustments;
   const Expr *Inner = E->GetTemporaryExpr()->
       skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
 
   // If we passed any comma operators, evaluate their LHSs.
   for (unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
     if (!EvaluateIgnoredValue(Info, CommaLHSs[I]))
       return false;
 
   // A materialized temporary with static storage duration can appear within the
   // result of a constant expression evaluation, so we need to preserve its
   // value for use outside this evaluation.
   APValue *Value;
   if (E->getStorageDuration() == SD_Static) {
     Value = Info.Ctx.getMaterializedTemporaryValue(E, true);
     *Value = APValue();
     Result.set(E);
   } else {
     Value = &Info.CurrentCall->
         createTemporary(E, E->getStorageDuration() == SD_Automatic);
     Result.set(E, Info.CurrentCall->Index);
   }
 
   QualType Type = Inner->getType();
 
   // Materialize the temporary itself.
   if (!EvaluateInPlace(*Value, Info, Result, Inner) ||
       (E->getStorageDuration() == SD_Static &&
        !CheckConstantExpression(Info, E->getExprLoc(), Type, *Value))) {
     *Value = APValue();
     return false;
   }
 
   // Adjust our lvalue to refer to the desired subobject.
   for (unsigned I = Adjustments.size(); I != 0; /**/) {
     --I;
     switch (Adjustments[I].Kind) {
     case SubobjectAdjustment::DerivedToBaseAdjustment:
       if (!HandleLValueBasePath(Info, Adjustments[I].DerivedToBase.BasePath,
                                 Type, Result))
         return false;
       Type = Adjustments[I].DerivedToBase.BasePath->getType();
       break;
 
     case SubobjectAdjustment::FieldAdjustment:
       if (!HandleLValueMember(Info, E, Result, Adjustments[I].Field))
         return false;
       Type = Adjustments[I].Field->getType();
       break;
 
     case SubobjectAdjustment::MemberPointerAdjustment:
       if (!HandleMemberPointerAccess(this->Info, Type, Result,
                                      Adjustments[I].Ptr.RHS))
         return false;
       Type = Adjustments[I].Ptr.MPT->getPointeeType();
       break;
     }
   }
 
   return true;
 }
 
 bool
 LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
   assert(!Info.getLangOpts().CPlusPlus && "lvalue compound literal in c++?");
   // Defer visiting the literal until the lvalue-to-rvalue conversion. We can
   // only see this when folding in C, so there's no standard to follow here.
   return Success(E);
 }
 
 bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
   if (!E->isPotentiallyEvaluated())
     return Success(E);
 
   Info.Diag(E, diag::note_constexpr_typeid_polymorphic)
     << E->getExprOperand()->getType()
     << E->getExprOperand()->getSourceRange();
   return false;
 }
 
 bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
   return Success(E);
 }
 
 bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
   // Handle static data members.
   if (const VarDecl *VD = dyn_cast<VarDecl>(E->getMemberDecl())) {
     VisitIgnoredValue(E->getBase());
     return VisitVarDecl(E, VD);
   }
 
   // Handle static member functions.
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->getMemberDecl())) {
     if (MD->isStatic()) {
       VisitIgnoredValue(E->getBase());
       return Success(MD);
     }
   }
 
   // Handle non-static data members.
   return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
 }
 
 bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
   // FIXME: Deal with vectors as array subscript bases.
   if (E->getBase()->getType()->isVectorType())
     return Error(E);
 
   if (!EvaluatePointer(E->getBase(), Result, Info))
     return false;
 
   APSInt Index;
   if (!EvaluateInteger(E->getIdx(), Index, Info))
     return false;
 
   return HandleLValueArrayAdjustment(Info, E, Result, E->getType(),
                                      getExtValue(Index));
 }
 
 bool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) {
   return EvaluatePointer(E->getSubExpr(), Result, Info);
 }
 
 bool LValueExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
   if (!Visit(E->getSubExpr()))
     return false;
   // __real is a no-op on scalar lvalues.
   if (E->getSubExpr()->getType()->isAnyComplexType())
     HandleLValueComplexElement(Info, E, Result, E->getType(), false);
   return true;
 }
 
 bool LValueExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
   assert(E->getSubExpr()->getType()->isAnyComplexType() &&
          "lvalue __imag__ on scalar?");
   if (!Visit(E->getSubExpr()))
     return false;
   HandleLValueComplexElement(Info, E, Result, E->getType(), true);
   return true;
 }
 
 bool LValueExprEvaluator::VisitUnaryPreIncDec(const UnaryOperator *UO) {
   if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
     return Error(UO);
 
   if (!this->Visit(UO->getSubExpr()))
     return false;
 
   return handleIncDec(
       this->Info, UO, Result, UO->getSubExpr()->getType(),
       UO->isIncrementOp(), nullptr);
 }
 
 bool LValueExprEvaluator::VisitCompoundAssignOperator(
     const CompoundAssignOperator *CAO) {
   if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
     return Error(CAO);
 
   APValue RHS;
 
   // The overall lvalue result is the result of evaluating the LHS.
   if (!this->Visit(CAO->getLHS())) {
     if (Info.keepEvaluatingAfterFailure())
       Evaluate(RHS, this->Info, CAO->getRHS());
     return false;
   }
 
   if (!Evaluate(RHS, this->Info, CAO->getRHS()))
     return false;
 
   return handleCompoundAssignment(
       this->Info, CAO,
       Result, CAO->getLHS()->getType(), CAO->getComputationLHSType(),
       CAO->getOpForCompoundAssignment(CAO->getOpcode()), RHS);
 }
 
 bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) {
   if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
     return Error(E);
 
   APValue NewVal;
 
   if (!this->Visit(E->getLHS())) {
     if (Info.keepEvaluatingAfterFailure())
       Evaluate(NewVal, this->Info, E->getRHS());
     return false;
   }
 
   if (!Evaluate(NewVal, this->Info, E->getRHS()))
     return false;
 
   return handleAssignment(this->Info, E, Result, E->getLHS()->getType(),
                           NewVal);
 }
 
 //===----------------------------------------------------------------------===//
 // Pointer Evaluation
 //===----------------------------------------------------------------------===//
 
 namespace {
 class PointerExprEvaluator
   : public ExprEvaluatorBase<PointerExprEvaluator> {
   LValue &Result;
 
   bool Success(const Expr *E) {
     Result.set(E);
     return true;
   }
 public:
 
   PointerExprEvaluator(EvalInfo &info, LValue &Result)
     : ExprEvaluatorBaseTy(info), Result(Result) {}
 
   bool Success(const APValue &V, const Expr *E) {
     Result.setFrom(Info.Ctx, V);
     return true;
   }
   bool ZeroInitialization(const Expr *E) {
     return Success((Expr*)nullptr);
   }
 
   bool VisitBinaryOperator(const BinaryOperator *E);
   bool VisitCastExpr(const CastExpr* E);
   bool VisitUnaryAddrOf(const UnaryOperator *E);
   bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
       { return Success(E); }
   bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
       { return Success(E); }    
   bool VisitAddrLabelExpr(const AddrLabelExpr *E)
       { return Success(E); }
   bool VisitCallExpr(const CallExpr *E);
   bool VisitBlockExpr(const BlockExpr *E) {
     if (!E->getBlockDecl()->hasCaptures())
       return Success(E);
     return Error(E);
   }
   bool VisitCXXThisExpr(const CXXThisExpr *E) {
     // Can't look at 'this' when checking a potential constant expression.
     if (Info.checkingPotentialConstantExpression())
       return false;
     if (!Info.CurrentCall->This) {
       if (Info.getLangOpts().CPlusPlus11)
         Info.Diag(E, diag::note_constexpr_this) << E->isImplicit();
       else
         Info.Diag(E);
       return false;
     }
     Result = *Info.CurrentCall->This;
     return true;
   }
 
   // FIXME: Missing: @protocol, @selector
 };
 } // end anonymous namespace
 
 static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) {
   assert(E->isRValue() && E->getType()->hasPointerRepresentation());
   return PointerExprEvaluator(Info, Result).Visit(E);
 }
 
 bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
   if (E->getOpcode() != BO_Add &&
       E->getOpcode() != BO_Sub)
     return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
 
   const Expr *PExp = E->getLHS();
   const Expr *IExp = E->getRHS();
   if (IExp->getType()->isPointerType())
     std::swap(PExp, IExp);
 
   bool EvalPtrOK = EvaluatePointer(PExp, Result, Info);
   if (!EvalPtrOK && !Info.keepEvaluatingAfterFailure())
     return false;
 
   llvm::APSInt Offset;
   if (!EvaluateInteger(IExp, Offset, Info) || !EvalPtrOK)
     return false;
 
   int64_t AdditionalOffset = getExtValue(Offset);
   if (E->getOpcode() == BO_Sub)
     AdditionalOffset = -AdditionalOffset;
 
   QualType Pointee = PExp->getType()->castAs<PointerType>()->getPointeeType();
   return HandleLValueArrayAdjustment(Info, E, Result, Pointee,
                                      AdditionalOffset);
 }
 
 bool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
   return EvaluateLValue(E->getSubExpr(), Result, Info);
 }
 
 bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
   const Expr* SubExpr = E->getSubExpr();
 
   switch (E->getCastKind()) {
   default:
     break;
 
   case CK_BitCast:
   case CK_CPointerToObjCPointerCast:
   case CK_BlockPointerToObjCPointerCast:
   case CK_AnyPointerToBlockPointerCast:
   case CK_AddressSpaceConversion:
     if (!Visit(SubExpr))
       return false;
     // Bitcasts to cv void* are static_casts, not reinterpret_casts, so are
     // permitted in constant expressions in C++11. Bitcasts from cv void* are
     // also static_casts, but we disallow them as a resolution to DR1312.
     if (!E->getType()->isVoidPointerType()) {
       Result.Designator.setInvalid();
       if (SubExpr->getType()->isVoidPointerType())
         CCEDiag(E, diag::note_constexpr_invalid_cast)
           << 3 << SubExpr->getType();
       else
         CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
     }
     return true;
 
   case CK_DerivedToBase:
   case CK_UncheckedDerivedToBase:
     if (!EvaluatePointer(E->getSubExpr(), Result, Info))
       return false;
     if (!Result.Base && Result.Offset.isZero())
       return true;
 
     // Now figure out the necessary offset to add to the base LV to get from
     // the derived class to the base class.
     return HandleLValueBasePath(Info, E, E->getSubExpr()->getType()->
                                   castAs<PointerType>()->getPointeeType(),
                                 Result);
 
   case CK_BaseToDerived:
     if (!Visit(E->getSubExpr()))
       return false;
     if (!Result.Base && Result.Offset.isZero())
       return true;
     return HandleBaseToDerivedCast(Info, E, Result);
 
   case CK_NullToPointer:
     VisitIgnoredValue(E->getSubExpr());
     return ZeroInitialization(E);
 
   case CK_IntegralToPointer: {
     CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
 
     APValue Value;
     if (!EvaluateIntegerOrLValue(SubExpr, Value, Info))
       break;
 
     if (Value.isInt()) {
       unsigned Size = Info.Ctx.getTypeSize(E->getType());
       uint64_t N = Value.getInt().extOrTrunc(Size).getZExtValue();
       Result.Base = (Expr*)nullptr;
       Result.Offset = CharUnits::fromQuantity(N);
       Result.CallIndex = 0;
       Result.Designator.setInvalid();
       return true;
     } else {
       // Cast is of an lvalue, no need to change value.
       Result.setFrom(Info.Ctx, Value);
       return true;
     }
   }
   case CK_ArrayToPointerDecay:
     if (SubExpr->isGLValue()) {
       if (!EvaluateLValue(SubExpr, Result, Info))
         return false;
     } else {
       Result.set(SubExpr, Info.CurrentCall->Index);
       if (!EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr, false),
                            Info, Result, SubExpr))
         return false;
     }
     // The result is a pointer to the first element of the array.
     if (const ConstantArrayType *CAT
           = Info.Ctx.getAsConstantArrayType(SubExpr->getType()))
       Result.addArray(Info, E, CAT);
     else
       Result.Designator.setInvalid();
     return true;
 
   case CK_FunctionToPointerDecay:
     return EvaluateLValue(SubExpr, Result, Info);
   }
 
   return ExprEvaluatorBaseTy::VisitCastExpr(E);
 }
 
 static CharUnits GetAlignOfType(EvalInfo &Info, QualType T) {
   // C++ [expr.alignof]p3:
   //     When alignof is applied to a reference type, the result is the
   //     alignment of the referenced type.
   if (const ReferenceType *Ref = T->getAs<ReferenceType>())
     T = Ref->getPointeeType();
 
   // __alignof is defined to return the preferred alignment.
   return Info.Ctx.toCharUnitsFromBits(
     Info.Ctx.getPreferredTypeAlign(T.getTypePtr()));
 }
 
 static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E) {
   E = E->IgnoreParens();
 
   // The kinds of expressions that we have special-case logic here for
   // should be kept up to date with the special checks for those
   // expressions in Sema.
 
   // alignof decl is always accepted, even if it doesn't make sense: we default
   // to 1 in those cases.
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
     return Info.Ctx.getDeclAlign(DRE->getDecl(),
                                  /*RefAsPointee*/true);
 
   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
     return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
                                  /*RefAsPointee*/true);
 
   return GetAlignOfType(Info, E->getType());
 }
 
 bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
   if (IsStringLiteralCall(E))
     return Success(E);
 
   switch (E->getBuiltinCallee()) {
   case Builtin::BI__builtin_addressof:
     return EvaluateLValue(E->getArg(0), Result, Info);
   case Builtin::BI__builtin_assume_aligned: {
     // We need to be very careful here because: if the pointer does not have the
     // asserted alignment, then the behavior is undefined, and undefined
     // behavior is non-constant.
     if (!EvaluatePointer(E->getArg(0), Result, Info))
       return false;
 
     LValue OffsetResult(Result);
     APSInt Alignment;
     if (!EvaluateInteger(E->getArg(1), Alignment, Info))
       return false;
     CharUnits Align = CharUnits::fromQuantity(getExtValue(Alignment));
 
     if (E->getNumArgs() > 2) {
       APSInt Offset;
       if (!EvaluateInteger(E->getArg(2), Offset, Info))
         return false;
 
       int64_t AdditionalOffset = -getExtValue(Offset);
       OffsetResult.Offset += CharUnits::fromQuantity(AdditionalOffset);
     }
 
     // If there is a base object, then it must have the correct alignment.
     if (OffsetResult.Base) {
       CharUnits BaseAlignment;
       if (const ValueDecl *VD =
           OffsetResult.Base.dyn_cast<const ValueDecl*>()) {
         BaseAlignment = Info.Ctx.getDeclAlign(VD);
       } else {
         BaseAlignment =
           GetAlignOfExpr(Info, OffsetResult.Base.get<const Expr*>());
       }
 
       if (BaseAlignment < Align) {
         Result.Designator.setInvalid();
 	// FIXME: Quantities here cast to integers because the plural modifier
 	// does not work on APSInts yet.
         CCEDiag(E->getArg(0),
                 diag::note_constexpr_baa_insufficient_alignment) << 0
           << (int) BaseAlignment.getQuantity()
           << (unsigned) getExtValue(Alignment);
         return false;
       }
     }
 
     // The offset must also have the correct alignment.
     if (OffsetResult.Offset.RoundUpToAlignment(Align) != OffsetResult.Offset) {
       Result.Designator.setInvalid();
       APSInt Offset(64, false);
       Offset = OffsetResult.Offset.getQuantity();
 
       if (OffsetResult.Base)
         CCEDiag(E->getArg(0),
                 diag::note_constexpr_baa_insufficient_alignment) << 1
           << (int) getExtValue(Offset) << (unsigned) getExtValue(Alignment);
       else
         CCEDiag(E->getArg(0),
                 diag::note_constexpr_baa_value_insufficient_alignment)
           << Offset << (unsigned) getExtValue(Alignment);
 
       return false;
     }
 
     return true;
   }
   default:
     return ExprEvaluatorBaseTy::VisitCallExpr(E);
   }
 }
 
 //===----------------------------------------------------------------------===//
 // Member Pointer Evaluation
 //===----------------------------------------------------------------------===//
 
 namespace {
 class MemberPointerExprEvaluator
   : public ExprEvaluatorBase<MemberPointerExprEvaluator> {
   MemberPtr &Result;
 
   bool Success(const ValueDecl *D) {
     Result = MemberPtr(D);
     return true;
   }
 public:
 
   MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
     : ExprEvaluatorBaseTy(Info), Result(Result) {}
 
   bool Success(const APValue &V, const Expr *E) {
     Result.setFrom(V);
     return true;
   }
   bool ZeroInitialization(const Expr *E) {
     return Success((const ValueDecl*)nullptr);
   }
 
   bool VisitCastExpr(const CastExpr *E);
   bool VisitUnaryAddrOf(const UnaryOperator *E);
 };
 } // end anonymous namespace
 
 static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result,
                                   EvalInfo &Info) {
   assert(E->isRValue() && E->getType()->isMemberPointerType());
   return MemberPointerExprEvaluator(Info, Result).Visit(E);
 }
 
 bool MemberPointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
   switch (E->getCastKind()) {
   default:
     return ExprEvaluatorBaseTy::VisitCastExpr(E);
 
   case CK_NullToMemberPointer:
     VisitIgnoredValue(E->getSubExpr());
     return ZeroInitialization(E);
 
   case CK_BaseToDerivedMemberPointer: {
     if (!Visit(E->getSubExpr()))
       return false;
     if (E->path_empty())
       return true;
     // Base-to-derived member pointer casts store the path in derived-to-base
     // order, so iterate backwards. The CXXBaseSpecifier also provides us with
     // the wrong end of the derived->base arc, so stagger the path by one class.
     typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
     for (ReverseIter PathI(E->path_end() - 1), PathE(E->path_begin());
          PathI != PathE; ++PathI) {
       assert(!(*PathI)->isVirtual() && "memptr cast through vbase");
       const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
       if (!Result.castToDerived(Derived))
         return Error(E);
     }
     const Type *FinalTy = E->getType()->castAs<MemberPointerType>()->getClass();
     if (!Result.castToDerived(FinalTy->getAsCXXRecordDecl()))
       return Error(E);
     return true;
   }
 
   case CK_DerivedToBaseMemberPointer:
     if (!Visit(E->getSubExpr()))
       return false;
     for (CastExpr::path_const_iterator PathI = E->path_begin(),
          PathE = E->path_end(); PathI != PathE; ++PathI) {
       assert(!(*PathI)->isVirtual() && "memptr cast through vbase");
       const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
       if (!Result.castToBase(Base))
         return Error(E);
     }
     return true;
   }
 }
 
 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
   // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
   // member can be formed.
   return Success(cast<DeclRefExpr>(E->getSubExpr())->getDecl());
 }
 
 //===----------------------------------------------------------------------===//
 // Record Evaluation
 //===----------------------------------------------------------------------===//
 
 namespace {
   class RecordExprEvaluator
   : public ExprEvaluatorBase<RecordExprEvaluator> {
     const LValue &This;
     APValue &Result;
   public:
 
     RecordExprEvaluator(EvalInfo &info, const LValue &This, APValue &Result)
       : ExprEvaluatorBaseTy(info), This(This), Result(Result) {}
 
     bool Success(const APValue &V, const Expr *E) {
       Result = V;
       return true;
     }
     bool ZeroInitialization(const Expr *E);
 
     bool VisitCastExpr(const CastExpr *E);
     bool VisitInitListExpr(const InitListExpr *E);
     bool VisitCXXConstructExpr(const CXXConstructExpr *E);
     bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);
   };
 }
 
 /// Perform zero-initialization on an object of non-union class type.
 /// C++11 [dcl.init]p5:
 ///  To zero-initialize an object or reference of type T means:
 ///    [...]
 ///    -- if T is a (possibly cv-qualified) non-union class type,
 ///       each non-static data member and each base-class subobject is
 ///       zero-initialized
 static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E,
                                           const RecordDecl *RD,
                                           const LValue &This, APValue &Result) {
   assert(!RD->isUnion() && "Expected non-union class type");
   const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
   Result = APValue(APValue::UninitStruct(), CD ? CD->getNumBases() : 0,
                    std::distance(RD->field_begin(), RD->field_end()));
 
   if (RD->isInvalidDecl()) return false;
   const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
 
   if (CD) {
     unsigned Index = 0;
     for (CXXRecordDecl::base_class_const_iterator I = CD->bases_begin(),
            End = CD->bases_end(); I != End; ++I, ++Index) {
       const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
       LValue Subobject = This;
       if (!HandleLValueDirectBase(Info, E, Subobject, CD, Base, &Layout))
         return false;
       if (!HandleClassZeroInitialization(Info, E, Base, Subobject,
                                          Result.getStructBase(Index)))
         return false;
     }
   }
 
   for (const auto *I : RD->fields()) {
     // -- if T is a reference type, no initialization is performed.
     if (I->getType()->isReferenceType())
       continue;
 
     LValue Subobject = This;
     if (!HandleLValueMember(Info, E, Subobject, I, &Layout))
       return false;
 
     ImplicitValueInitExpr VIE(I->getType());
     if (!EvaluateInPlace(
           Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
       return false;
   }
 
   return true;
 }
 
 bool RecordExprEvaluator::ZeroInitialization(const Expr *E) {
   const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl();
   if (RD->isInvalidDecl()) return false;
   if (RD->isUnion()) {
     // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
     // object's first non-static named data member is zero-initialized
     RecordDecl::field_iterator I = RD->field_begin();
     if (I == RD->field_end()) {
       Result = APValue((const FieldDecl*)nullptr);
       return true;
     }
 
     LValue Subobject = This;
     if (!HandleLValueMember(Info, E, Subobject, *I))
       return false;
     Result = APValue(*I);
     ImplicitValueInitExpr VIE(I->getType());
     return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
   }
 
   if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
     Info.Diag(E, diag::note_constexpr_virtual_base) << RD;
     return false;
   }
 
   return HandleClassZeroInitialization(Info, E, RD, This, Result);
 }
 
 bool RecordExprEvaluator::VisitCastExpr(const CastExpr *E) {
   switch (E->getCastKind()) {
   default:
     return ExprEvaluatorBaseTy::VisitCastExpr(E);
 
   case CK_ConstructorConversion:
     return Visit(E->getSubExpr());
 
   case CK_DerivedToBase:
   case CK_UncheckedDerivedToBase: {
     APValue DerivedObject;
     if (!Evaluate(DerivedObject, Info, E->getSubExpr()))
       return false;
     if (!DerivedObject.isStruct())
       return Error(E->getSubExpr());
 
     // Derived-to-base rvalue conversion: just slice off the derived part.
     APValue *Value = &DerivedObject;
     const CXXRecordDecl *RD = E->getSubExpr()->getType()->getAsCXXRecordDecl();
     for (CastExpr::path_const_iterator PathI = E->path_begin(),
          PathE = E->path_end(); PathI != PathE; ++PathI) {
       assert(!(*PathI)->isVirtual() && "record rvalue with virtual base");
       const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
       Value = &Value->getStructBase(getBaseIndex(RD, Base));
       RD = Base;
     }
     Result = *Value;
     return true;
   }
   }
 }
 
 bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
   const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl();
   if (RD->isInvalidDecl()) return false;
   const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
 
   if (RD->isUnion()) {
     const FieldDecl *Field = E->getInitializedFieldInUnion();
     Result = APValue(Field);
     if (!Field)
       return true;
 
     // If the initializer list for a union does not contain any elements, the
     // first element of the union is value-initialized.
     // FIXME: The element should be initialized from an initializer list.
     //        Is this difference ever observable for initializer lists which
     //        we don't build?
     ImplicitValueInitExpr VIE(Field->getType());
     const Expr *InitExpr = E->getNumInits() ? E->getInit(0) : &VIE;
 
     LValue Subobject = This;
     if (!HandleLValueMember(Info, InitExpr, Subobject, Field, &Layout))
       return false;
 
     // Temporarily override This, in case there's a CXXDefaultInitExpr in here.
     ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
                                   isa<CXXDefaultInitExpr>(InitExpr));
 
     return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
   }
 
   assert((!isa<CXXRecordDecl>(RD) || !cast<CXXRecordDecl>(RD)->getNumBases()) &&
          "initializer list for class with base classes");
   Result = APValue(APValue::UninitStruct(), 0,
                    std::distance(RD->field_begin(), RD->field_end()));
   unsigned ElementNo = 0;
   bool Success = true;
   for (const auto *Field : RD->fields()) {
     // Anonymous bit-fields are not considered members of the class for
     // purposes of aggregate initialization.
     if (Field->isUnnamedBitfield())
Index: test/Sema/const-eval.c
===================================================================
--- test/Sema/const-eval.c	(revision 238723)
+++ test/Sema/const-eval.c	(working copy)
@@ -1,136 +1,139 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux %s -Wno-tautological-pointer-compare
 
 #define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];});
 int x;
 EVAL_EXPR(1, (_Bool)&x)
 EVAL_EXPR(2, (int)(1.0+(double)4))
 EVAL_EXPR(3, (int)(1.0+(float)4.0))
 EVAL_EXPR(4, (_Bool)(1 ? (void*)&x : 0))
 EVAL_EXPR(5, (_Bool)(int[]){0})
 struct y {int x,y;};
 EVAL_EXPR(6, (int)(1+(struct y*)0))
 EVAL_EXPR(7, (int)&((struct y*)0)->y)
 EVAL_EXPR(8, (_Bool)"asdf")
 EVAL_EXPR(9, !!&x)
 EVAL_EXPR(10, ((void)1, 12))
 void g0(void);
 EVAL_EXPR(11, (g0(), 12)) // expected-error {{must have a constant size}}
 EVAL_EXPR(12, 1.0&&2.0)
 EVAL_EXPR(13, x || 3.0) // expected-error {{must have a constant size}}
 
 unsigned int l_19 = 1;
 EVAL_EXPR(14, (1 ^ l_19) && 1); // expected-error {{fields must have a constant size}}
 
 void f()
 {
   int a;
   EVAL_EXPR(15, (_Bool)&a);
 }
 
 // FIXME: Turn into EVAL_EXPR test once we have more folding.
 _Complex float g16 = (1.0f + 1.0fi);
 
 // ?: in constant expressions.
 int g17[(3?:1) - 2]; 
 
 EVAL_EXPR(18, ((int)((void*)10 + 10)) == 20 ? 1 : -1);
 
 struct s {
   int a[(int)-1.0f]; // expected-error {{'a' declared as an array with a negative size}}
 };
 
 EVAL_EXPR(19, ((int)&*(char*)10 == 10 ? 1 : -1));
 
 EVAL_EXPR(20, __builtin_constant_p(*((int*) 10)));
 
 EVAL_EXPR(21, (__imag__ 2i) == 2 ? 1 : -1);
 
 EVAL_EXPR(22, (__real__ (2i+3)) == 3 ? 1 : -1);
 
 int g23[(int)(1.0 / 1.0)] = { 1 };
 int g24[(int)(1.0 / 1.0)] = { 1 , 2 }; // expected-warning {{excess elements in array initializer}}
 int g25[(int)(1.0 + 1.0)], g26 = sizeof(g25);
 
 EVAL_EXPR(26, (_Complex double)0 ? -1 : 1)
 EVAL_EXPR(27, (_Complex int)0 ? -1 : 1)
 EVAL_EXPR(28, (_Complex double)1 ? 1 : -1)
 EVAL_EXPR(29, (_Complex int)1 ? 1 : -1)
 
 
 // PR4027 + rdar://6808859
 struct a { int x, y; };
 static struct a V2 = (struct a)(struct a){ 1, 2};
 static const struct a V1 = (struct a){ 1, 2};
 
 EVAL_EXPR(30, (int)(_Complex float)((1<<30)-1) == (1<<30) ? 1 : -1)
 EVAL_EXPR(31, (int*)0 == (int*)0 ? 1 : -1)
 EVAL_EXPR(32, (int*)0 != (int*)0 ? -1 : 1)
 EVAL_EXPR(33, (void*)0 - (void*)0 == 0 ? 1 : -1)
 void foo(void) {}
 EVAL_EXPR(34, (foo == (void *)0) ? -1 : 1)
 
 // No PR. Mismatched bitwidths lead to a crash on second evaluation.
 const _Bool constbool = 0;
 EVAL_EXPR(35, constbool)
 EVAL_EXPR(36, constbool)
 
 EVAL_EXPR(37, (1,2.0) == 2.0 ? 1 : -1)
 EVAL_EXPR(38, __builtin_expect(1,1) == 1 ? 1 : -1)
 
 // PR7884
 EVAL_EXPR(39, __real__(1.f) == 1 ? 1 : -1)
 EVAL_EXPR(40, __imag__(1.f) == 0 ? 1 : -1)
 
 // From gcc testsuite
 EVAL_EXPR(41, (int)(1+(_Complex unsigned)2))
 
 // rdar://8875946
 void rdar8875946() {
   double _Complex  P;
   float _Complex  P2 = 3.3f + P;
 }
 
 double d = (d = 0.0); // expected-error {{not a compile-time constant}}
 double d2 = ++d; // expected-error {{not a compile-time constant}}
 
 int n = 2;
 int intLvalue[*(int*)((long)&n ?: 1)] = { 1, 2 }; // expected-error {{variable length array}}
 
 union u { int a; char b[4]; };
 char c = ((union u)(123456)).b[0]; // expected-error {{not a compile-time constant}}
 
 extern const int weak_int __attribute__((weak));
 const int weak_int = 42;
 int weak_int_test = weak_int; // expected-error {{not a compile-time constant}}
 
 int literalVsNull1 = "foo" == 0;
 int literalVsNull2 = 0 == "foo";
 
 // PR11385.
 int castViaInt[*(int*)(unsigned long)"test"]; // expected-error {{variable length array}}
 
 // PR11391.
 struct PR11391 { _Complex float f; } pr11391;
 EVAL_EXPR(42, __builtin_constant_p(pr11391.f = 1))
 
 // PR12043
 float varfloat;
 const float constfloat = 0;
 EVAL_EXPR(43, varfloat && constfloat) // expected-error {{must have a constant size}}
 
 // <rdar://problem/11205586>
 // (Make sure we continue to reject this.)
 EVAL_EXPR(44, "x"[0]); // expected-error {{variable length array}}
 
 // <rdar://problem/10962435>
 EVAL_EXPR(45, ((char*)-1) + 1 == 0 ? 1 : -1)
 EVAL_EXPR(46, ((char*)-1) + 1 < (char*) -1 ? 1 : -1)
 EVAL_EXPR(47, &x < &x + 1 ? 1 : -1)
 EVAL_EXPR(48, &x != &x - 1 ? 1 : -1)
 EVAL_EXPR(49, &x < &x - 100 ? 1 : -1) // expected-error {{must have a constant size}}
 
 extern struct Test50S Test50;
 EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned)&Test50 + 10)) // expected-error {{must have a constant size}}
 
 // <rdar://problem/11874571>
 EVAL_EXPR(51, 0 != (float)1e99)
+
+// PR21945
+void PR21945() { int i = (({}), 0l); }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to