[cfe-commits] r56482 - in /cfe/trunk: lib/AST/Expr.cpp test/CodeGen/2008-09-22-bad-switch-type.c

Daniel Dunbar daniel at zuster.org
Mon Sep 22 16:53:31 PDT 2008


Author: ddunbar
Date: Mon Sep 22 18:53:24 2008
New Revision: 56482

URL: http://llvm.org/viewvc/llvm-project?rev=56482&view=rev
Log:
Bug fix, result of isIntegerConstantExpr could be of incorrect width
for type.
  - PR2817

Added:
    cfe/trunk/test/CodeGen/2008-09-22-bad-switch-type.c
Modified:
    cfe/trunk/lib/AST/Expr.cpp

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=56482&r1=56481&r2=56482&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Mon Sep 22 18:53:24 2008
@@ -867,22 +867,25 @@
   }
   case BinaryOperatorClass: {
     const BinaryOperator *Exp = cast<BinaryOperator>(this);
+    llvm::APSInt LHS, RHS;
+
+    // Initialize result to have correct signedness and width.
+    Result = llvm::APSInt(static_cast<uint32_t>(Ctx.getTypeSize(getType())),
+                          !getType()->isSignedIntegerType());                          
     
     // The LHS of a constant expr is always evaluated and needed.
-    if (!Exp->getLHS()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
+    if (!Exp->getLHS()->isIntegerConstantExpr(LHS, Ctx, Loc, isEvaluated))
       return false;
     
-    llvm::APSInt RHS(Result);
-    
     // The short-circuiting &&/|| operators don't necessarily evaluate their
     // RHS.  Make sure to pass isEvaluated down correctly.
     if (Exp->isLogicalOp()) {
       bool RHSEval;
       if (Exp->getOpcode() == BinaryOperator::LAnd)
-        RHSEval = Result != 0;
+        RHSEval = LHS != 0;
       else {
         assert(Exp->getOpcode() == BinaryOperator::LOr &&"Unexpected logical");
-        RHSEval = Result == 0;
+        RHSEval = LHS == 0;
       }
       
       if (!Exp->getRHS()->isIntegerConstantExpr(RHS, Ctx, Loc,
@@ -898,7 +901,7 @@
       if (Loc) *Loc = getLocStart();
       return false;
     case BinaryOperator::Mul:
-      Result *= RHS;
+      Result = LHS * RHS;
       break;
     case BinaryOperator::Div:
       if (RHS == 0) {
@@ -906,7 +909,7 @@
         if (Loc) *Loc = getLocStart();
         return false;
       }
-      Result /= RHS;
+      Result = LHS / RHS;
       break;
     case BinaryOperator::Rem:
       if (RHS == 0) {
@@ -914,32 +917,32 @@
         if (Loc) *Loc = getLocStart();
         return false;
       }
-      Result %= RHS;
+      Result = LHS % RHS;
       break;
-    case BinaryOperator::Add: Result += RHS; break;
-    case BinaryOperator::Sub: Result -= RHS; break;
+    case BinaryOperator::Add: Result = LHS + RHS; break;
+    case BinaryOperator::Sub: Result = LHS - RHS; break;
     case BinaryOperator::Shl:
-      Result <<= 
-        static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
-      break;
+      Result = LHS << 
+        static_cast<uint32_t>(RHS.getLimitedValue(LHS.getBitWidth()-1));
+    break;
     case BinaryOperator::Shr:
-      Result >>= 
-        static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1));
+      Result = LHS >>
+        static_cast<uint32_t>(RHS.getLimitedValue(LHS.getBitWidth()-1));
       break;
-    case BinaryOperator::LT:  Result = Result < RHS; break;
-    case BinaryOperator::GT:  Result = Result > RHS; break;
-    case BinaryOperator::LE:  Result = Result <= RHS; break;
-    case BinaryOperator::GE:  Result = Result >= RHS; break;
-    case BinaryOperator::EQ:  Result = Result == RHS; break;
-    case BinaryOperator::NE:  Result = Result != RHS; break;
-    case BinaryOperator::And: Result &= RHS; break;
-    case BinaryOperator::Xor: Result ^= RHS; break;
-    case BinaryOperator::Or:  Result |= RHS; break;
+    case BinaryOperator::LT:  Result = LHS < RHS; break;
+    case BinaryOperator::GT:  Result = LHS > RHS; break;
+    case BinaryOperator::LE:  Result = LHS <= RHS; break;
+    case BinaryOperator::GE:  Result = LHS >= RHS; break;
+    case BinaryOperator::EQ:  Result = LHS == RHS; break;
+    case BinaryOperator::NE:  Result = LHS != RHS; break;
+    case BinaryOperator::And: Result = LHS & RHS; break;
+    case BinaryOperator::Xor: Result = LHS ^ RHS; break;
+    case BinaryOperator::Or:  Result = LHS | RHS; break;
     case BinaryOperator::LAnd:
-      Result = Result != 0 && RHS != 0;
+      Result = LHS != 0 && RHS != 0;
       break;
     case BinaryOperator::LOr:
-      Result = Result != 0 || RHS != 0;
+      Result = LHS != 0 || RHS != 0;
       break;
       
     case BinaryOperator::Comma:

Added: cfe/trunk/test/CodeGen/2008-09-22-bad-switch-type.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/2008-09-22-bad-switch-type.c?rev=56482&view=auto

==============================================================================
--- cfe/trunk/test/CodeGen/2008-09-22-bad-switch-type.c (added)
+++ cfe/trunk/test/CodeGen/2008-09-22-bad-switch-type.c Mon Sep 22 18:53:24 2008
@@ -0,0 +1,34 @@
+// RUN: clang -emit-llvm -o %t %s
+// PR2817
+
+void f0(void) {
+  switch (0) {
+  case (unsigned long long) 0 < 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 > 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 <= 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 >= 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 == 0: 
+    break;
+  }
+
+  switch (0) {
+  case (unsigned long long) 0 != 0: 
+    break;
+  }
+}





More information about the cfe-commits mailing list