summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-03-24 01:14:50 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-03-24 01:14:50 +0000
commit94c25c66b5ed45f579953e5efaaa4a11ac47d847 (patch)
treeb625ddfa03cc2a1519dc426adac56052300dde3b
parent703a77f31346d1d3ee98cd6bfa527f7cac1934c3 (diff)
downloadbcm5719-llvm-94c25c66b5ed45f579953e5efaaa4a11ac47d847.tar.gz
bcm5719-llvm-94c25c66b5ed45f579953e5efaaa4a11ac47d847.zip
Fix PR3868 by making Evaluate handle cases like "(long)&a + 4".
llvm-svn: 67593
-rw-r--r--clang/lib/AST/ExprConstant.cpp33
-rw-r--r--clang/test/Sema/init.c3
2 files changed, 30 insertions, 6 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index c2449166fc6..b0954e149c4 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -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);
diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c
index 6f592b80e60..73c6887889b 100644
--- a/clang/test/Sema/init.c
+++ b/clang/test/Sema/init.c
@@ -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;
OpenPOWER on IntegriCloud