diff options
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 8797ead..0d12161 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9346,9 +9346,13 @@ bool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) { // [C++26][expr.unary.op] // If the operand points to an object or function, the result // denotes that object or function; otherwise, the behavior is undefined. - return Success && - (!E->getType().getNonReferenceType()->isObjectType() || - findCompleteObject(Info, E, AK_Dereference, Result, E->getType())); + // Because &(*(type*)0) is a common pattern, we do not fail the evaluation + // immediately. + if (!Success || !E->getType().getNonReferenceType()->isObjectType()) + return Success; + return bool(findCompleteObject(Info, E, AK_Dereference, Result, + E->getType())) || + Info.noteUndefinedBehavior(); } bool LValueExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { @@ -18018,6 +18022,11 @@ bool Expr::isPotentialConstantExprUnevaluated(Expr *E, Info.InConstantContext = true; Info.CheckingPotentialConstantExpression = true; + if (Info.EnableNewConstInterp) { + Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD); + return Diags.empty(); + } + // Fabricate a call stack frame to give the arguments a plausible cover story. CallStackFrame Frame(Info, SourceLocation(), FD, /*This=*/nullptr, /*CallExpr=*/nullptr, CallRef()); @@ -18175,6 +18184,10 @@ bool Expr::EvaluateCharRangeAsString(APValue &Result, bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const { Expr::EvalStatus Status; EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold); + + if (Info.EnableNewConstInterp) + return Info.Ctx.getInterpContext().evaluateStrlen(Info, this, Result); + return EvaluateBuiltinStrLen(this, Result, Info); } |