summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp3
-rw-r--r--clang/lib/AST/ExprConstant.cpp50
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp14
-rw-r--r--clang/lib/Sema/SemaOverload.cpp6
4 files changed, 69 insertions, 4 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index b7ebf318518..10829c70074 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2974,6 +2974,9 @@ bool Expr::hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs) {
bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
const Expr **Culprit) const {
+ assert(!isValueDependent() &&
+ "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
index 236827280ef..af332095ccf 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11642,6 +11642,8 @@ static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult,
/// will be applied to the result.
bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
bool InConstantContext) const {
+ assert(!isValueDependent() &&
+ "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);
@@ -11649,6 +11651,8 @@ bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
bool Expr::EvaluateAsBooleanCondition(bool &Result,
const ASTContext &Ctx) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
EvalResult Scratch;
return EvaluateAsRValue(Scratch, Ctx) &&
HandleConversionToBool(Scratch.Val, Result);
@@ -11656,18 +11660,25 @@ bool Expr::EvaluateAsBooleanCondition(bool &Result,
bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects) const {
+ assert(!isValueDependent() &&
+ "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() &&
+ "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() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
if (!getType()->isRealFloatingType())
return false;
@@ -11681,6 +11692,9 @@ bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx,
}
bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
LValue LV;
@@ -11696,6 +11710,9 @@ bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const {
bool Expr::EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage,
const ASTContext &Ctx) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
EvalInfo Info(Ctx, Result, EM);
Info.InConstantContext = true;
@@ -11710,6 +11727,9 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage,
bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
const VarDecl *VD,
SmallVectorImpl<PartialDiagnosticAt> &Notes) const {
+ assert(!isValueDependent() &&
+ "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()) &&
@@ -11752,6 +11772,9 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
/// 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() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
EvalResult Result;
return EvaluateAsRValue(Result, Ctx, /* in constant context */ true) &&
!hasUnacceptableSideEffect(Result, SEK);
@@ -11759,6 +11782,9 @@ bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const {
APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
SmallVectorImpl<PartialDiagnosticAt> *Diag) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
EvalResult EVResult;
EVResult.Diag = Diag;
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
@@ -11774,6 +11800,9 @@ APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
APSInt Expr::EvaluateKnownConstIntCheckOverflow(
const ASTContext &Ctx, SmallVectorImpl<PartialDiagnosticAt> *Diag) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
EvalResult EVResult;
EVResult.Diag = Diag;
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
@@ -11788,6 +11817,9 @@ APSInt Expr::EvaluateKnownConstIntCheckOverflow(
}
void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
bool IsConst;
EvalResult EVResult;
if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
@@ -12269,6 +12301,9 @@ static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx,
bool Expr::isIntegerConstantExpr(const ASTContext &Ctx,
SourceLocation *Loc) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
if (Ctx.getLangOpts().CPlusPlus11)
return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, nullptr, Loc);
@@ -12282,6 +12317,9 @@ bool Expr::isIntegerConstantExpr(const ASTContext &Ctx,
bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, const ASTContext &Ctx,
SourceLocation *Loc, bool isEvaluated) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
if (Ctx.getLangOpts().CPlusPlus11)
return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, &Value, Loc);
@@ -12305,11 +12343,17 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, const ASTContext &Ctx,
}
bool Expr::isCXX98IntegralConstantExpr(const ASTContext &Ctx) const {
+ assert(!isValueDependent() &&
+ "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() &&
+ "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);
@@ -12338,6 +12382,9 @@ bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
const FunctionDecl *Callee,
ArrayRef<const Expr*> Args,
const Expr *This) const {
+ assert(!isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
Expr::EvalStatus Status;
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
Info.InConstantContext = true;
@@ -12419,6 +12466,9 @@ bool Expr::isPotentialConstantExprUnevaluated(Expr *E,
const FunctionDecl *FD,
SmallVectorImpl<
PartialDiagnosticAt> &Diags) {
+ assert(!E->isValueDependent() &&
+ "Expression evaluator can't be called on a dependent expression.");
+
Expr::EvalStatus Status;
Status.Diag = &Diags;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index cc196219092..19a7d784c56 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5894,14 +5894,21 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
if (CollapseLoopCountExpr) {
// Found 'collapse' clause - calculate collapse number.
Expr::EvalResult Result;
- if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
+ if (!CollapseLoopCountExpr->isValueDependent() &&
+ CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
NestedLoopCount = Result.Val.getInt().getLimitedValue();
+ } else {
+ Built.clear(/*size=*/1);
+ return 1;
+ }
}
unsigned OrderedLoopCount = 1;
if (OrderedLoopCountExpr) {
// Found 'ordered' clause - calculate collapse number.
Expr::EvalResult EVResult;
- if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) {
+ if (!OrderedLoopCountExpr->isValueDependent() &&
+ OrderedLoopCountExpr->EvaluateAsInt(EVResult,
+ SemaRef.getASTContext())) {
llvm::APSInt Result = EVResult.Val.getInt();
if (Result.getLimitedValue() < NestedLoopCount) {
SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
@@ -5912,6 +5919,9 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
<< CollapseLoopCountExpr->getSourceRange();
}
OrderedLoopCount = Result.getLimitedValue();
+ } else {
+ Built.clear(/*size=*/1);
+ return 1;
}
}
// This is helper routine for loop directives (e.g., 'for', 'simd',
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 256c2343e51..eadc01e5efb 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -6376,7 +6376,8 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
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()->EvaluateWithSubstitution(
Result, Context, Function, llvm::makeArrayRef(ConvertedArgs)))
return EIA;
@@ -9562,7 +9563,8 @@ static bool isFunctionAlwaysEnabled(const ASTContext &Ctx,
const FunctionDecl *FD) {
for (auto *EnableIf : FD->specific_attrs<EnableIfAttr>()) {
bool AlwaysTrue;
- if (!EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx))
+ if (EnableIf->getCond()->isValueDependent() ||
+ !EnableIf->getCond()->EvaluateAsBooleanCondition(AlwaysTrue, Ctx))
return false;
if (!AlwaysTrue)
return false;
OpenPOWER on IntegriCloud