]> granicus.if.org Git - clang/commitdiff
isICE was evaluating ?: incorrectly with missing-gcc-LHS extension.
authorDaniel Dunbar <daniel@zuster.org>
Wed, 18 Feb 2009 00:47:45 +0000 (00:47 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 18 Feb 2009 00:47:45 +0000 (00:47 +0000)
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

include/clang/AST/Expr.h
lib/AST/Expr.cpp
test/Sema/const-eval.c

index 6579b595e561845fc3d0d131b72c9a859b4fb334..cb1400c0794182f74565ddde233e3790567ddfd8 100644 (file)
@@ -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.
index c1117e8c8841309c573e7ee05c79ff31bb8eff41..0cd68ce3b8aa910d0a6f4d840291895a847b3c12 100644 (file)
@@ -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;
index 71f76228d1b925c8a3124fa2fa63e8e1f6f01fda..7307aea791f4ce398d20b852cb6a54acff5b4bc6 100644 (file)
@@ -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];