]> granicus.if.org Git - clang/commitdiff
Fix PR3868 by making Evaluate handle cases like "(long)&a + 4".
authorEli Friedman <eli.friedman@gmail.com>
Tue, 24 Mar 2009 01:14:50 +0000 (01:14 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Tue, 24 Mar 2009 01:14:50 +0000 (01:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67593 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/Sema/init.c

index c2449166fc68da3faaed19b4c84b557aca818dc1..b0954e149c400f3125c46b459cee3219df95f603 100644 (file)
@@ -918,7 +918,6 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
       !RHSTy->isIntegralType()) {
     // We can't continue from here for non-integral types, and they
     // could potentially confuse the following operations.
-    // FIXME: Deal with EQ and friends.
     return false;
   }
 
@@ -926,14 +925,36 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
   if (!Visit(E->getLHS()))
     return false; // error in subexpression.
 
-  // Only support arithmetic on integers for now.
-  if (!Result.isInt())
+  APValue RHSVal;
+  if (!EvaluateIntegerOrLValue(E->getRHS(), RHSVal, Info))
     return false;
-  
-  llvm::APSInt RHS;
-  if (!EvaluateInteger(E->getRHS(), RHS, Info))
+
+  // Handle cases like (unsigned long)&a + 4.
+  if (E->isAdditiveOp() && Result.isLValue() && RHSVal.isInt()) {
+    uint64_t offset = Result.getLValueOffset();
+    if (E->getOpcode() == BinaryOperator::Add)
+      offset += RHSVal.getInt().getZExtValue();
+    else
+      offset -= RHSVal.getInt().getZExtValue();
+    Result = APValue(Result.getLValueBase(), offset);
+    return true;
+  }
+
+  // Handle cases like 4 + (unsigned long)&a
+  if (E->getOpcode() == BinaryOperator::Add &&
+        RHSVal.isLValue() && Result.isInt()) {
+    uint64_t offset = RHSVal.getLValueOffset();
+    offset += Result.getInt().getZExtValue();
+    Result = APValue(RHSVal.getLValueBase(), offset);
+    return true;
+  }
+
+  // All the following cases expect both operands to be an integer
+  if (!Result.isInt() || !RHSVal.isInt())
     return false;
 
+  APSInt& RHS = RHSVal.getInt();
+
   switch (E->getOpcode()) {
   default:
     return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
index 6f592b80e60eb8a89899a3f82d29f59358913f44..73c6887889b4066a51462be8724a54815c5ffcf1 100644 (file)
@@ -120,3 +120,6 @@ ivector4 vtest2 = __builtin_choose_expr(1, (ivector4){1}, (ivector4){1});
 ivector4 vtest3 = __real__ (ivector4){1};
 ivector4 vtest4 = __imag__ (ivector4){1};
 
+uintptr_t ptrasintadd1 = (uintptr_t)&a - 4;
+uintptr_t ptrasintadd2 = (uintptr_t)&a + 4;
+uintptr_t ptrasintadd3 = 4 + (uintptr_t)&a;