diff options
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 101 |
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; |