Index: clang/include/clang/AST/Expr.h =================================================================== --- clang/include/clang/AST/Expr.h +++ clang/include/clang/AST/Expr.h @@ -1063,6 +1063,9 @@ bool isImmediateInvocation() const { return ConstantExprBits.IsImmediateInvocation; } + bool hasAPValueResult() const { + return ConstantExprBits.APValueKind != APValue::None; + } APValue getAPValueResult() const; APValue &getResultAsAPValue() const { return APValueResult(); } llvm::APSInt getResultAsAPSInt() const; Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -356,6 +356,8 @@ } APValue ConstantExpr::getAPValueResult() const { + assert(hasAPValueResult()); + switch (ConstantExprBits.ResultKind) { case ConstantExpr::RSK_APValue: return APValueResult(); @@ -2870,9 +2872,6 @@ return CE->getChosenSubExpr(); } - else if (auto *CE = dyn_cast(E)) - return CE->getSubExpr(); - return E; } Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -6751,8 +6751,13 @@ return Error(E); } - bool VisitConstantExpr(const ConstantExpr *E) - { return StmtVisitorTy::Visit(E->getSubExpr()); } + bool VisitConstantExpr(const ConstantExpr *E) { + if (E->hasAPValueResult()) + return DerivedSuccess(E->getAPValueResult(), E); + + return StmtVisitorTy::Visit(E->getSubExpr()); + } + bool VisitParenExpr(const ParenExpr *E) { return StmtVisitorTy::Visit(E->getSubExpr()); } bool VisitUnaryExtension(const UnaryOperator *E) @@ -7317,6 +7322,13 @@ return true; } + // Override to perform additional checks to ensure the cached APValue + // is actually an LValue. + bool VisitConstantExpr(const ConstantExpr *E) { + assert(!E->hasAPValueResult() || E->getAPValueResult().isLValue()); + return ExprEvaluatorBaseTy::VisitConstantExpr(E); + } + bool VisitMemberExpr(const MemberExpr *E) { // Handle non-static data members. QualType BaseTy; Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -15167,6 +15167,12 @@ return ExprError(); } + ExprResult RValueExpr = DefaultLvalueConversion(E); + if (RValueExpr.isInvalid()) + return ExprError(); + + E = RValueExpr.get(); + // Circumvent ICE checking in C++11 to avoid evaluating the expression twice // in the non-ICE case. if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {