diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h --- a/clang/include/clang/AST/Expr.h +++ b/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; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp --- a/clang/lib/AST/Expr.cpp +++ b/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; } diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/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,16 @@ return true; } + bool VisitConstantExpr(const ConstantExpr *E) { + if (E->hasAPValueResult()) { + APValue Result = E->getAPValueResult(); + if (Result.isLValue()) + return Success(Result, E); + } + + return ExprEvaluatorBaseTy::Visit(E->getSubExpr()); + } + bool VisitMemberExpr(const MemberExpr *E) { // Handle non-static data members. QualType BaseTy;