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 | 2d6744ff04c1690a1485178d550d2fab84a0270b (patch) | |
tree | 226683ac647b25752dccba33b4f96882d10ee876 | |
parent | a135975d4257ccc83f13b607b29d882bb00c80b6 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64865 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 5 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 19 | ||||
-rw-r--r-- | test/Sema/const-eval.c | 3 |
3 files changed, 23 insertions, 4 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 6579b595e5..cb1400c079 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -180,6 +180,9 @@ public: bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, SourceLocation *Loc = 0, bool isEvaluated = true) const; + bool isIntegerConstantExprInternal(llvm::APSInt &Result, ASTContext &Ctx, + SourceLocation *Loc = 0, + bool isEvaluated = true) const; bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const { llvm::APSInt X; return isIntegerConstantExpr(X, Ctx, Loc); @@ -190,7 +193,7 @@ public: /// EvalResult is a struct with detailed info about an evaluated expression. struct EvalResult { - /// Val - This is the scalar value the expression can be folded to. + /// Val - This is the value the expression can be folded to. APValue Val; /// HasSideEffects - Whether the evaluated expression has side effects. diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index c1117e8c88..0cd68ce3b8 100644 --- a/lib/AST/Expr.cpp +++ b/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; diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c index 71f76228d1..7307aea791 100644 --- a/test/Sema/const-eval.c +++ b/test/Sema/const-eval.c @@ -29,3 +29,6 @@ void f() // FIXME: Turn into EVAL_EXPR test once we have more folding. _Complex float g16 = (1.0f + 1.0fi); + +// ?: in constant expressions. +int g17[(3?:1) - 2]; |