aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 8797ead..9808298 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) {
@@ -14632,7 +14636,9 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
bool WasArrayIndex;
unsigned Mismatch = FindDesignatorMismatch(
- getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
+ LHSValue.Base.isNull() ? QualType()
+ : getType(LHSValue.Base).getNonReferenceType(),
+ LHSDesignator, RHSDesignator, WasArrayIndex);
// At the point where the designators diverge, the comparison has a
// specified value if:
// - we are comparing array indices
@@ -14676,7 +14682,7 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
// compare pointers within the object in question; otherwise, the result
// depends on where the object is located in memory.
if (!LHSValue.Base.isNull() && IsRelational) {
- QualType BaseTy = getType(LHSValue.Base);
+ QualType BaseTy = getType(LHSValue.Base).getNonReferenceType();
if (BaseTy->isIncompleteType())
return Error(E);
CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
@@ -18018,6 +18024,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 +18186,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);
}