summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-04-28 19:17:36 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-04-28 19:17:36 +0000
commitad02d7debd03ff275ac8ea27891a4ecccdb78068 (patch)
tree582f9362f324510c5e001cf37b57bb76b409ab7e
parente721f95069d42b899c20c1caabdc6184dd42b820 (diff)
downloadclang-ad02d7debd03ff275ac8ea27891a4ecccdb78068.tar.gz
PR4097: add logic to Evaluate to handle pointer equality comparisons.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70317 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ExprConstant.cpp23
-rw-r--r--test/Sema/const-eval.c2
2 files changed, 18 insertions, 7 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 1ea252fecb..45cf24b963 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -900,8 +900,8 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
}
}
- if (E->getOpcode() == BinaryOperator::Sub) {
- if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
+ if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
+ if (E->getOpcode() == BinaryOperator::Sub || E->isEqualityOp()) {
APValue LHSValue;
if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
return false;
@@ -915,13 +915,22 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
if (LHSValue.getLValueBase() || RHSValue.getLValueBase())
return false;
- const QualType Type = E->getLHS()->getType();
- const QualType ElementType = Type->getAsPointerType()->getPointeeType();
+ if (E->getOpcode() == BinaryOperator::Sub) {
+ const QualType Type = E->getLHS()->getType();
+ const QualType ElementType = Type->getAsPointerType()->getPointeeType();
- uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
- D /= Info.Ctx.getTypeSize(ElementType) / 8;
+ uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
+ D /= Info.Ctx.getTypeSize(ElementType) / 8;
- return Success(D, E);
+ return Success(D, E);
+ }
+ bool Result;
+ if (E->getOpcode() == BinaryOperator::EQ) {
+ Result = LHSValue.getLValueOffset() == RHSValue.getLValueOffset();
+ } else if (E->getOpcode() == BinaryOperator::NE) {
+ Result = LHSValue.getLValueOffset() != RHSValue.getLValueOffset();
+ }
+ return Success(Result, E);
}
}
if (!LHSTy->isIntegralType() ||
diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c
index ce1aacd274..79f96b9c39 100644
--- a/test/Sema/const-eval.c
+++ b/test/Sema/const-eval.c
@@ -63,3 +63,5 @@ static struct a V2 = (struct a)(struct a){ 1, 2};
static const struct a V1 = (struct a){ 1, 2};
EVAL_EXPR(30, (int)(_Complex float)((1<<30)-1) == (1<<30) ? 1 : -1)
+EVAL_EXPR(31, (int*)0 == (int*)0 ? 1 : -1)
+EVAL_EXPR(32, (int*)0 != (int*)0 ? -1 : 1)