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 @@ -2888,6 +2888,9 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef, const Expr **Culprit) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + // This function is attempting whether an expression is an initializer // which can be evaluated at compile-time. It very closely parallels // ConstExprEmitter in CGExprConstant.cpp; if they don't match, it 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 @@ -11088,6 +11088,8 @@ /// will be applied to the result. bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects); Info.InConstantContext = InConstantContext; return ::EvaluateAsRValue(this, Result, Ctx, Info); @@ -11095,6 +11097,8 @@ bool Expr::EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); EvalResult Scratch; return EvaluateAsRValue(Scratch, Ctx) && HandleConversionToBool(Scratch.Val, Result); @@ -11102,18 +11106,25 @@ bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects); return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info); } bool Expr::EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects); return ::EvaluateAsFixedPoint(this, Result, Ctx, AllowSideEffects, Info); } bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + if (!getType()->isRealFloatingType()) return false; @@ -11127,6 +11138,9 @@ } bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold); LValue LV; @@ -11142,6 +11156,9 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage, const ASTContext &Ctx) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression; EvalInfo Info(Ctx, Result, EM); Info.InConstantContext = true; @@ -11156,6 +11173,9 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl &Notes) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + // FIXME: Evaluating initializers for large array and record types can cause // performance problems. Only do so in C++11 for now. if (isRValue() && (getType()->isArrayType() || getType()->isRecordType()) && @@ -11198,6 +11218,9 @@ /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be /// constant folded, but discard the result. bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + EvalResult Result; return EvaluateAsRValue(Result, Ctx, /* in constant context */ true) && !hasUnacceptableSideEffect(Result, SEK); @@ -11205,6 +11228,9 @@ APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl *Diag) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + EvalResult EVResult; EVResult.Diag = Diag; EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects); @@ -11220,6 +11246,9 @@ APSInt Expr::EvaluateKnownConstIntCheckOverflow( const ASTContext &Ctx, SmallVectorImpl *Diag) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + EvalResult EVResult; EVResult.Diag = Diag; EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow); @@ -11234,6 +11263,9 @@ } void Expr::EvaluateForOverflow(const ASTContext &Ctx) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + bool IsConst; EvalResult EVResult; if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) { @@ -11715,6 +11747,9 @@ bool Expr::isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + if (Ctx.getLangOpts().CPlusPlus11) return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, nullptr, Loc); @@ -11728,6 +11763,9 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, const ASTContext &Ctx, SourceLocation *Loc, bool isEvaluated) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + if (Ctx.getLangOpts().CPlusPlus11) return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, &Value, Loc); @@ -11751,11 +11789,17 @@ } bool Expr::isCXX98IntegralConstantExpr(const ASTContext &Ctx) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + return CheckICE(this, Ctx).Kind == IK_ICE; } bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result, SourceLocation *Loc) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + // We support this checking in C++98 mode in order to diagnose compatibility // issues. assert(Ctx.getLangOpts().CPlusPlus); @@ -11784,6 +11828,9 @@ const FunctionDecl *Callee, ArrayRef Args, const Expr *This) const { + assert(!isValueDependent() && !isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + Expr::EvalStatus Status; EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated); Info.InConstantContext = true; @@ -11805,7 +11852,7 @@ ArgVector ArgValues(Args.size()); for (ArrayRef::iterator I = Args.begin(), E = Args.end(); I != E; ++I) { - if ((*I)->isValueDependent() || + if ((*I)->isValueDependent() || (*I)->isTypeDependent() || !Evaluate(ArgValues[I - Args.begin()], Info, *I)) // If evaluation fails, throw away the argument entirely. ArgValues[I - Args.begin()] = APValue(); @@ -11865,6 +11912,9 @@ const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt> &Diags) { + assert(!E->isValueDependent() && !E->isTypeDependent() && + "Expression evaluator can't be called on a dependent expression."); + Expr::EvalStatus Status; Status.Diag = &Diags; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -12452,7 +12452,7 @@ CheckImplicitConversions(E, CheckLoc); if (!E->isInstantiationDependent()) CheckUnsequencedOperations(E); - if (!IsConstexpr && !E->isValueDependent()) + if (!IsConstexpr && !E->isValueDependent() && !E->isTypeDependent()) CheckForIntOverflow(E); DiagnoseMisalignedMembers(); } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5781,14 +5781,19 @@ if (CollapseLoopCountExpr) { // Found 'collapse' clause - calculate collapse number. Expr::EvalResult Result; - if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) + if (!CollapseLoopCountExpr->isValueDependent() && + !CollapseLoopCountExpr->isTypeDependent() && + CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) NestedLoopCount = Result.Val.getInt().getLimitedValue(); } unsigned OrderedLoopCount = 1; if (OrderedLoopCountExpr) { // Found 'ordered' clause - calculate collapse number. Expr::EvalResult EVResult; - if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { + if (!OrderedLoopCountExpr->isValueDependent() && + !OrderedLoopCountExpr->isTypeDependent() && + OrderedLoopCountExpr->EvaluateAsInt(EVResult, + SemaRef.getASTContext())) { llvm::APSInt Result = EVResult.Val.getInt(); if (Result.getLimitedValue() < NestedLoopCount) { SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -6366,7 +6366,9 @@ APValue Result; // FIXME: This doesn't consider value-dependent cases, because doing so is // very difficult. Ideally, we should handle them more gracefully. - if (!EIA->getCond()->EvaluateWithSubstitution( + if (EIA->getCond()->isValueDependent() || + EIA->getCond()->isTypeDependent() || + !EIA->getCond()->EvaluateWithSubstitution( Result, Context, Function, llvm::makeArrayRef(ConvertedArgs))) return EIA; @@ -9547,7 +9549,9 @@ const FunctionDecl *FD) { for (auto *EnableIf : FD->specific_attrs()) { bool AlwaysTrue; - if (!EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx)) + if (EnableIf->getCond()->isValueDependent() || + EnableIf->getCond()->isTypeDependent() || + !EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx)) return false; if (!AlwaysTrue) return false;