summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-02-18 00:47:45 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-02-18 00:47:45 +0000
commit4750e634866f6bc8d90eba91cd1771594b5a8304 (patch)
treeecbd1f6f3c0293409be1791b3e590a60ae680e0e /clang/lib/AST
parent62347a0c55e2a9872cb8ad2771c4ef94052e025b (diff)
downloadbcm5719-llvm-4750e634866f6bc8d90eba91cd1771594b5a8304.tar.gz
bcm5719-llvm-4750e634866f6bc8d90eba91cd1771594b5a8304.zip
isICE was evaluating ?: incorrectly with missing-gcc-LHS extension.
Add assert to isICE that, on success, result must be the same as EvaluateAsInt()... this enforces a minimum level of sanity. llvm-svn: 64865
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/Expr.cpp19
1 files changed, 16 insertions, 3 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index c1117e8c884..0cd68ce3b8a 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -871,6 +871,15 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const {
/// cast+dereference.
bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc, bool isEvaluated) const {
+ if (!isIntegerConstantExprInternal(Result, Ctx, Loc, isEvaluated))
+ return false;
+ assert(Result == EvaluateAsInt(Ctx) && "Inconsistent Evaluate() result!");
+ return true;
+}
+
+bool Expr::isIntegerConstantExprInternal(llvm::APSInt &Result, ASTContext &Ctx,
+ SourceLocation *Loc, bool isEvaluated) const {
+
// Pretest for integral type; some parts of the code crash for types that
// can't be sized.
if (!getType()->isIntegralType()) {
@@ -885,6 +894,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
return cast<ParenExpr>(this)->getSubExpr()->
isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
case IntegerLiteralClass:
+ // NOTE: getValue() returns an APInt, we must set sign.
Result = cast<IntegerLiteral>(this)->getValue();
Result.setIsUnsigned(getType()->isUnsignedIntegerType());
break;
@@ -1107,7 +1117,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
// The result of the constant expr is the RHS.
Result = RHS;
- return true;
+ break;
}
assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
@@ -1208,9 +1218,12 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
}
// Evaluate the false one first, discard the result.
- if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))
+ llvm::APSInt Tmp;
+ if (FalseExp && !FalseExp->isIntegerConstantExpr(Tmp, Ctx, Loc, false))
return false;
- // Evalute the true one, capture the result.
+ // Evalute the true one, capture the result. Note that if TrueExp
+ // is False then this is an instant of the gcc missing LHS
+ // extension, and we will just reuse Result.
if (TrueExp &&
!TrueExp->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
return false;
OpenPOWER on IntegriCloud