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.cpp101
1 files changed, 42 insertions, 59 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 231a8c3..56181bb 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1819,8 +1819,7 @@ static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info);
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
EvalInfo &Info);
-static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
- bool &Dependent);
+static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
/// Evaluate an integer or fixed point expression into an APResult.
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
@@ -2108,8 +2107,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
QualType Type, const APValue &Value,
ConstantExprKind Kind,
SourceLocation SubobjectLoc,
- CheckedTemporaries &CheckedTemps,
- bool &Dependent);
+ CheckedTemporaries &CheckedTemps);
/// Check that this reference or pointer core constant expression is a valid
/// value for an address or reference constant expression. Return true if we
@@ -2117,8 +2115,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
QualType Type, const LValue &LVal,
ConstantExprKind Kind,
- CheckedTemporaries &CheckedTemps,
- bool &Dependent) {
+ CheckedTemporaries &CheckedTemps) {
bool IsReferenceType = Type->isReferenceType();
APValue::LValueBase Base = LVal.getLValueBase();
@@ -2203,8 +2200,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
}
if (BaseVD) {
- Dependent |= BaseVD->isTemplated();
-
if (const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
// Check if this is a thread-local variable.
if (Var->getTLSKind())
@@ -2235,9 +2230,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
}
} else if (const auto *MTE =
dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
- if (auto *Extending = MTE->getExtendingDecl())
- Dependent |= Extending->isTemplated();
-
if (CheckedTemps.insert(MTE).second) {
QualType TempType = getType(Base);
if (TempType.isDestructedType()) {
@@ -2250,8 +2242,8 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
APValue *V = MTE->getOrCreateValue(false);
assert(V && "evasluation result refers to uninitialised temporary");
if (!CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
- Info, MTE->getExprLoc(), TempType, *V, Kind,
- SourceLocation(), CheckedTemps, Dependent))
+ Info, MTE->getExprLoc(), TempType, *V,
+ Kind, SourceLocation(), CheckedTemps))
return false;
}
}
@@ -2280,15 +2272,13 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
/// Member pointers are constant expressions unless they point to a
/// non-virtual dllimport member function.
-static bool
-CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc,
- QualType Type, const APValue &Value,
- ConstantExprKind Kind, bool &Dependent) {
+static bool CheckMemberPointerConstantExpression(EvalInfo &Info,
+ SourceLocation Loc,
+ QualType Type,
+ const APValue &Value,
+ ConstantExprKind Kind) {
const ValueDecl *Member = Value.getMemberPointerDecl();
- if (!Member)
- return true;
- Dependent |= Member->isTemplated();
- const auto *FD = dyn_cast<CXXMethodDecl>(Member);
+ const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
if (!FD)
return true;
if (FD->isConsteval()) {
@@ -2337,8 +2327,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
QualType Type, const APValue &Value,
ConstantExprKind Kind,
SourceLocation SubobjectLoc,
- CheckedTemporaries &CheckedTemps,
- bool &Dependent) {
+ CheckedTemporaries &CheckedTemps) {
if (!Value.hasValue()) {
Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
<< true << Type;
@@ -2360,20 +2349,20 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
for (unsigned I = 0, N = Value.getArrayInitializedElts(); I != N; ++I) {
if (!CheckEvaluationResult(CERK, Info, DiagLoc, EltTy,
Value.getArrayInitializedElt(I), Kind,
- SubobjectLoc, CheckedTemps, Dependent))
+ SubobjectLoc, CheckedTemps))
return false;
}
if (!Value.hasArrayFiller())
return true;
return CheckEvaluationResult(CERK, Info, DiagLoc, EltTy,
Value.getArrayFiller(), Kind, SubobjectLoc,
- CheckedTemps, Dependent);
+ CheckedTemps);
}
if (Value.isUnion() && Value.getUnionField()) {
return CheckEvaluationResult(
CERK, Info, DiagLoc, Value.getUnionField()->getType(),
Value.getUnionValue(), Kind, Value.getUnionField()->getLocation(),
- CheckedTemps, Dependent);
+ CheckedTemps);
}
if (Value.isStruct()) {
RecordDecl *RD = Type->castAs<RecordType>()->getDecl();
@@ -2382,7 +2371,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
for (const CXXBaseSpecifier &BS : CD->bases()) {
if (!CheckEvaluationResult(CERK, Info, DiagLoc, BS.getType(),
Value.getStructBase(BaseIndex), Kind,
- BS.getBeginLoc(), CheckedTemps, Dependent))
+ BS.getBeginLoc(), CheckedTemps))
return false;
++BaseIndex;
}
@@ -2392,8 +2381,8 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
continue;
if (!CheckEvaluationResult(CERK, Info, DiagLoc, I->getType(),
- Value.getStructField(I->getFieldIndex()), Kind,
- I->getLocation(), CheckedTemps, Dependent))
+ Value.getStructField(I->getFieldIndex()),
+ Kind, I->getLocation(), CheckedTemps))
return false;
}
}
@@ -2403,13 +2392,12 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
LValue LVal;
LVal.setFrom(Info.Ctx, Value);
return CheckLValueConstantExpression(Info, DiagLoc, Type, LVal, Kind,
- CheckedTemps, Dependent);
+ CheckedTemps);
}
if (Value.isMemberPointer() &&
CERK == CheckEvaluationResultKind::ConstantExpression)
- return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value,
- Kind, Dependent);
+ return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value, Kind);
// Everything else is fine.
return true;
@@ -2420,7 +2408,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
/// check that the expression is of literal type.
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
QualType Type, const APValue &Value,
- ConstantExprKind Kind, bool &Dependent) {
+ ConstantExprKind Kind) {
// Nothing to check for a constant expression of type 'cv void'.
if (Type->isVoidType())
return true;
@@ -2428,18 +2416,17 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
CheckedTemporaries CheckedTemps;
return CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
Info, DiagLoc, Type, Value, Kind,
- SourceLocation(), CheckedTemps, Dependent);
+ SourceLocation(), CheckedTemps);
}
/// Check that this evaluated value is fully-initialized and can be loaded by
/// an lvalue-to-rvalue conversion.
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc,
QualType Type, const APValue &Value) {
- bool Dependent = false;
CheckedTemporaries CheckedTemps;
return CheckEvaluationResult(
CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc, Type, Value,
- ConstantExprKind::Normal, SourceLocation(), CheckedTemps, Dependent);
+ ConstantExprKind::Normal, SourceLocation(), CheckedTemps);
}
/// Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless
@@ -11111,9 +11098,7 @@ static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) {
ArgType->isAnyComplexType() || ArgType->isPointerType() ||
ArgType->isNullPtrType()) {
APValue V;
- bool Dependent = false;
- if (!::EvaluateAsRValue(Info, Arg, V, Dependent) ||
- Info.EvalStatus.HasSideEffects) {
+ if (!::EvaluateAsRValue(Info, Arg, V) || Info.EvalStatus.HasSideEffects) {
Fold.keepDiagnostics();
return false;
}
@@ -11415,8 +11400,7 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
// It's possible for us to be given GLValues if we're called via
// Expr::tryEvaluateObjectSize.
APValue RVal;
- bool Dependent = false;
- if (!EvaluateAsRValue(Info, E, RVal, Dependent))
+ if (!EvaluateAsRValue(Info, E, RVal))
return false;
LVal.setFrom(Info.Ctx, RVal);
} else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info,
@@ -12845,9 +12829,8 @@ bool RecordExprEvaluator::VisitBinCmp(const BinaryOperator *E) {
LV.set(VD);
if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result))
return false;
- bool Dependent = false;
return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
- ConstantExprKind::Normal, Dependent);
+ ConstantExprKind::Normal);
};
return EvaluateComparisonBinaryOperator(Info, E, OnSuccess, [&]() {
return ExprEvaluatorBaseTy::VisitBinCmp(E);
@@ -14611,8 +14594,7 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
/// EvaluateAsRValue - Try to evaluate this expression, performing an implicit
/// lvalue-to-rvalue cast if it is an lvalue.
-static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
- bool &Dependent) {
+static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
assert(!E->isValueDependent());
if (Info.EnableNewConstInterp) {
if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
@@ -14637,7 +14619,7 @@ static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
// Check this core constant expression is a constant expression.
return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
- ConstantExprKind::Normal, Dependent) &&
+ ConstantExprKind::Normal) &&
CheckMemoryLeaks(Info);
}
@@ -14683,7 +14665,7 @@ static bool EvaluateAsRValue(const Expr *E, Expr::EvalResult &Result,
if (FastEvaluateAsRValue(E, Result, Ctx, IsConst))
return IsConst;
- return EvaluateAsRValue(Info, E, Result.Val, Result.Dependent);
+ return EvaluateAsRValue(Info, E, Result.Val);
}
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult,
@@ -14793,9 +14775,9 @@ bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx,
CheckedTemporaries CheckedTemps;
if (!EvaluateLValue(this, LV, Info) || !Info.discardCleanups() ||
Result.HasSideEffects ||
- !CheckLValueConstantExpression(
- Info, getExprLoc(), Ctx.getLValueReferenceType(getType()), LV,
- ConstantExprKind::Normal, CheckedTemps, Result.Dependent))
+ !CheckLValueConstantExpression(Info, getExprLoc(),
+ Ctx.getLValueReferenceType(getType()), LV,
+ ConstantExprKind::Normal, CheckedTemps))
return false;
LV.moveInto(Result.Val);
@@ -14854,7 +14836,7 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
llvm_unreachable("Unhandled cleanup; missing full expression marker?");
if (!CheckConstantExpression(Info, getExprLoc(), getStorageType(Ctx, this),
- Result.Val, Kind, Result.Dependent))
+ Result.Val, Kind))
return false;
if (!CheckMemoryLeaks(Info))
return false;
@@ -14918,9 +14900,8 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
if (!Info.discardCleanups())
llvm_unreachable("Unhandled cleanup; missing full expression marker?");
}
- bool Dependent = false;
return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
- ConstantExprKind::Normal, Dependent) &&
+ ConstantExprKind::Normal) &&
CheckMemoryLeaks(Info);
}
@@ -14987,7 +14968,7 @@ APSInt Expr::EvaluateKnownConstIntCheckOverflow(
Info.InConstantContext = true;
Info.CheckingForUndefinedBehavior = true;
- bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info);
+ bool Result = ::EvaluateAsRValue(Info, this, EVResult.Val);
(void)Result;
assert(Result && "Could not evaluate expression");
assert(EVResult.Val.isInt() && "Expression did not evaluate to integer");
@@ -14999,10 +14980,13 @@ void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
assert(!isValueDependent() &&
"Expression evaluator can't be called on a dependent expression.");
+ bool IsConst;
EvalResult EVResult;
- EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
- Info.CheckingForUndefinedBehavior = true;
- (void)::EvaluateAsRValue(this, EVResult, Ctx, Info);
+ if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
+ EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
+ Info.CheckingForUndefinedBehavior = true;
+ (void)::EvaluateAsRValue(Info, this, EVResult.Val);
+ }
}
bool Expr::EvalResult::isGlobalLValue() const {
@@ -15552,9 +15536,8 @@ bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result,
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
APValue Scratch;
- bool Dependent = false;
bool IsConstExpr =
- ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch, Dependent) &&
+ ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch) &&
// FIXME: We don't produce a diagnostic for this, but the callers that
// call us on arbitrary full-expressions should generally not care.
Info.discardCleanups() && !Status.HasSideEffects;