diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-02-18 00:47:45 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-02-18 00:47:45 +0000 |
commit | 4750e634866f6bc8d90eba91cd1771594b5a8304 (patch) | |
tree | ecbd1f6f3c0293409be1791b3e590a60ae680e0e /clang/lib/AST/Expr.cpp | |
parent | 62347a0c55e2a9872cb8ad2771c4ef94052e025b (diff) | |
download | bcm5719-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/Expr.cpp')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 19 |
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; |