Index: lib/ARCMigrate/ObjCMT.cpp =================================================================== --- lib/ARCMigrate/ObjCMT.cpp +++ lib/ARCMigrate/ObjCMT.cpp @@ -799,6 +799,8 @@ AllHexdecimalEnumerator = false; continue; } + if (auto *CE = dyn_cast(InitExpr)) + InitExpr = CE->getSubExpr(); InitExpr = InitExpr->IgnoreParenCasts(); if (const BinaryOperator *BO = dyn_cast(InitExpr)) if (BO->isShiftOp() || BO->isBitwiseOp()) Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -579,6 +579,7 @@ ExpectedStmt VisitCompoundLiteralExpr(CompoundLiteralExpr *E); ExpectedStmt VisitAtomicExpr(AtomicExpr *E); ExpectedStmt VisitAddrLabelExpr(AddrLabelExpr *E); + ExpectedStmt VisitConstantExpr(ConstantExpr *E); ExpectedStmt VisitParenExpr(ParenExpr *E); ExpectedStmt VisitParenListExpr(ParenListExpr *E); ExpectedStmt VisitStmtExpr(StmtExpr *E); @@ -6362,6 +6363,10 @@ ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType); } +ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) { + return new (Importer.getToContext()) ConstantExpr(E); +} + ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) { auto Imp = importSeq(E->getLParen(), E->getRParen(), E->getSubExpr()); if (!Imp) Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -4718,6 +4718,8 @@ return Error(E); } + bool VisitConstantExpr(const ConstantExpr *E) + { return StmtVisitorTy::Visit(E->getSubExpr()); } bool VisitParenExpr(const ParenExpr *E) { return StmtVisitorTy::Visit(E->getSubExpr()); } bool VisitUnaryExtension(const UnaryOperator *E) @@ -5261,6 +5263,9 @@ bool VisitVarDecl(const Expr *E, const VarDecl *VD); bool VisitUnaryPreIncDec(const UnaryOperator *UO); + bool VisitConstantExpr(const ConstantExpr *E) { + return Visit(E->getSubExpr()); + } bool VisitDeclRefExpr(const DeclRefExpr *E); bool VisitPredefinedExpr(const PredefinedExpr *E) { return Success(E); } bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); @@ -5736,6 +5741,9 @@ return true; } + bool VisitConstantExpr(const ConstantExpr *E) { + return evaluateLValue(E->getSubExpr(), Result); + } bool VisitBinaryOperator(const BinaryOperator *E); bool VisitCastExpr(const CastExpr* E); bool VisitUnaryAddrOf(const UnaryOperator *E); Index: lib/Analysis/CFG.cpp =================================================================== --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -551,6 +551,7 @@ CFGBlock *VisitGotoStmt(GotoStmt *G); CFGBlock *VisitIfStmt(IfStmt *I); CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc); + CFGBlock *VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc); CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I); CFGBlock *VisitLabelStmt(LabelStmt *L); CFGBlock *VisitBlockExpr(BlockExpr *E, AddStmtChoice asc); @@ -2099,6 +2100,9 @@ case Stmt::ImplicitCastExprClass: return VisitImplicitCastExpr(cast(S), asc); + case Stmt::ConstantExprClass: + return VisitConstantExpr(cast(S), asc); + case Stmt::IndirectGotoStmtClass: return VisitIndirectGotoStmt(cast(S)); @@ -4376,6 +4380,10 @@ return Visit(E->getSubExpr(), AddStmtChoice()); } +CFGBlock *CFGBuilder::VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc) { + return Visit(E->getSubExpr(), AddStmtChoice()); +} + CFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) { // Lazily create the indirect-goto dispatch block if there isn't one already. CFGBlock *IBlock = cfg->getIndirectGotoBlock(); @@ -4432,6 +4440,10 @@ E = cast(E)->getSubExpr(); goto tryAgain; + case Stmt::ConstantExprClass: + E = cast(E)->getSubExpr(); + goto tryAgain; + case Stmt::ParenExprClass: E = cast(E)->getSubExpr(); goto tryAgain; Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1260,6 +1260,8 @@ return EmitVAArgExprLValue(cast(E)); case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast(E)); + case Expr::ConstantExprClass: + return EmitLValue(cast(E)->getSubExpr()); case Expr::ParenExprClass: return EmitLValue(cast(E)->getSubExpr()); case Expr::GenericSelectionExprClass: Index: lib/CodeGen/CGExprAgg.cpp =================================================================== --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -125,6 +125,10 @@ return Visit(E->getReplacement()); } + void VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } + // l-values. void VisitDeclRefExpr(DeclRefExpr *E) { EmitAggLoadOfLValue(E); } void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); } Index: lib/CodeGen/CGExprComplex.cpp =================================================================== --- lib/CodeGen/CGExprComplex.cpp +++ lib/CodeGen/CGExprComplex.cpp @@ -101,6 +101,9 @@ llvm_unreachable("Stmt can't have complex result type!"); } ComplexPairTy VisitExpr(Expr *S); + ComplexPairTy VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { return Visit(GE->getResultExpr()); Index: lib/CodeGen/CGExprConstant.cpp =================================================================== --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -723,6 +723,10 @@ return nullptr; } + llvm::Constant *VisitConstantExpr(ConstantExpr *CE, QualType T) { + return Visit(CE->getSubExpr(), T); + } + llvm::Constant *VisitParenExpr(ParenExpr *PE, QualType T) { return Visit(PE->getSubExpr(), T); } @@ -1601,6 +1605,7 @@ ConstantLValue tryEmitBase(const APValue::LValueBase &base); ConstantLValue VisitStmt(const Stmt *S) { return nullptr; } + ConstantLValue VisitConstantExpr(const ConstantExpr *E); ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); ConstantLValue VisitStringLiteral(const StringLiteral *E); ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E); @@ -1755,6 +1760,11 @@ return Visit(base.get()); } +ConstantLValue +ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *E) { + return Visit(E->getSubExpr()); +} + ConstantLValue ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E); Index: lib/CodeGen/CGExprScalar.cpp =================================================================== --- lib/CodeGen/CGExprScalar.cpp +++ lib/CodeGen/CGExprScalar.cpp @@ -398,6 +398,9 @@ } Value *VisitExpr(Expr *S); + Value *VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); } Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -16226,6 +16226,7 @@ EnumVal.setIsSigned(EltTy->isSignedIntegerOrEnumerationType()); } + if (Val) Val = new (Context) ConstantExpr(Val); return EnumConstantDecl::Create(Context, Enum, IdLoc, Id, EltTy, Val, EnumVal); } @@ -16338,6 +16339,8 @@ Expr *InitExpr = ECD->getInitExpr(); if (!InitExpr) return true; + if (auto *CE = dyn_cast(InitExpr)) + InitExpr = CE->getSubExpr(); InitExpr = InitExpr->IgnoreImpCasts(); if (BinaryOperator *BO = dyn_cast(InitExpr)) { @@ -16405,9 +16408,7 @@ // Null EnumConstantDecl means a previous diagnostic has been emitted for // this constant. Skip this enum since it may be ill-formed. - if (!ECD) { - return; - } + if (!ECD) return; // Constants with initalizers are handled in the next loop. if (ECD->getInitExpr()) @@ -16705,12 +16706,20 @@ // Adjust the Expr initializer and type. if (ECD->getInitExpr() && - !Context.hasSameType(NewTy, ECD->getInitExpr()->getType())) - ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy, - CK_IntegralCast, - ECD->getInitExpr(), - /*base paths*/ nullptr, - VK_RValue)); + !Context.hasSameType(NewTy, ECD->getInitExpr()->getType())) { + auto *Init = ECD->getInitExpr(); + auto *CE = dyn_cast(Init); + if (CE) Init = CE->getSubExpr(); + Init = ImplicitCastExpr::Create(Context, NewTy, + CK_IntegralCast, Init, + /*base paths*/ nullptr, + VK_RValue); + if (CE) { + CE->setSubExpr(Init); + Init = CE; + } + ECD->setInitExpr(Init); + } if (getLangOpts().CPlusPlus) // C++ [dcl.enum]p4: Following the closing brace of an // enum-specifier, each enumerator has the type of its Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -5784,9 +5784,9 @@ ? VK_RValue : VK_LValue; - return MaybeBindToTemporary( - new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, - VK, LiteralExpr, isFileScope)); + auto *CLE = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, + VK, LiteralExpr, isFileScope); + return MaybeBindToTemporary(new (Context) ConstantExpr(CLE)); } ExprResult Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -5503,7 +5503,8 @@ // array from a compound literal that creates an array of the same // type, so long as the initializer has no side effects. if (!S.getLangOpts().CPlusPlus && Initializer && - isa(Initializer->IgnoreParens()) && + (isa(Initializer->IgnoreParens()) || + isa(Initializer->IgnoreParens())) && Initializer->getType()->isArrayType()) { const ArrayType *SourceAT = Context.getAsArrayType(Initializer->getType()); Index: lib/StaticAnalyzer/Core/Environment.cpp =================================================================== --- lib/StaticAnalyzer/Core/Environment.cpp +++ lib/StaticAnalyzer/Core/Environment.cpp @@ -92,6 +92,7 @@ case Stmt::ExprWithCleanupsClass: case Stmt::GenericSelectionExprClass: case Stmt::OpaqueValueExprClass: + case Stmt::ConstantExprClass: case Stmt::ParenExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: llvm_unreachable("Should have been handled by ignoreTransparentExprs"); Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1267,9 +1267,6 @@ case Stmt::ObjCPropertyRefExprClass: llvm_unreachable("These are handled by PseudoObjectExpr"); - case Expr::ConstantExprClass: - return Visit(cast(S)->getSubExpr(), Pred, DstTop); - case Stmt::GNUNullExprClass: { // GNU __null is a pointer-width integer, not an actual pointer. ProgramStateRef state = Pred->getState(); @@ -1285,6 +1282,10 @@ Bldr.addNodes(Dst); break; + case Expr::ConstantExprClass: + // Handled due to it being a wrapper class. + break; + case Stmt::ExprWithCleanupsClass: // Handled due to fully linearised CFG. break; Index: test/Misc/ast-dump-decl.c =================================================================== --- test/Misc/ast-dump-decl.c +++ test/Misc/ast-dump-decl.c @@ -96,6 +96,7 @@ }; // CHECK: EnumConstantDecl{{.*}} TestEnumConstantDecl 'int' // CHECK: EnumConstantDecl{{.*}} TestEnumConstantDeclInit 'int' +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral struct testIndirectFieldDecl { Index: test/SemaCXX/compound-literal.cpp =================================================================== --- test/SemaCXX/compound-literal.cpp +++ test/SemaCXX/compound-literal.cpp @@ -37,13 +37,15 @@ void test() { (void)(POD){1, 2}; // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD' - // CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' + // CHECK: ConstantExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} (void)(HasDtor){1, 2}; // CHECK: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasDtor' + // CHECK-NEXT: ConstantExpr {{.*}} 'brace_initializers::HasDtor' // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasDtor' // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::HasDtor' // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} @@ -52,13 +54,15 @@ #if __cplusplus >= 201103L (void)(HasCtor){1, 2}; // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtor' - // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtor' + // CHECK-CXX11: ConstantExpr {{.*}} 'brace_initializers::HasCtor' + // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtor' // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtor' // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}} (void)(HasCtorDtor){1, 2}; // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtorDtor' + // CHECK-CXX11-NEXT: ConstantExpr {{.*}} 'brace_initializers::HasCtorDtor' // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor' // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtorDtor' // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}