diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2009-06-14 02:17:33 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2009-06-14 02:17:33 +0000 |
| commit | 334046a1340d7c70ac9c935a44cd56392a389d3a (patch) | |
| tree | 26239d65651ac7971fe97f303644c42b76c4ce4a /clang/lib/AST | |
| parent | f4ba1e62f941a4ac3881734926d1dbd1ef5ab555 (diff) | |
| download | bcm5719-llvm-334046a1340d7c70ac9c935a44cd56392a389d3a.tar.gz bcm5719-llvm-334046a1340d7c70ac9c935a44cd56392a389d3a.zip | |
PR4351: Add constant evaluation for constructs like "foo == NULL", where
foo has a constant address.
llvm-svn: 73321
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index ff00bc24b39..4815ae5c3b9 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -62,6 +62,13 @@ static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info); // Misc utilities //===----------------------------------------------------------------------===// +static bool EvalPointerValueAsBool(APValue& Value, bool& Result) { + // FIXME: Is this accurate for all kinds of bases? If not, what would + // the check look like? + Result = Value.getLValueBase() || Value.getLValueOffset(); + return true; +} + static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) { if (E->getType()->isIntegralType()) { APSInt IntResult; @@ -79,10 +86,7 @@ static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) { APValue PointerResult; if (!EvaluatePointer(E, PointerResult, Info)) return false; - // FIXME: Is this accurate for all kinds of bases? If not, what would - // the check look like? - Result = PointerResult.getLValueBase() || PointerResult.getLValueOffset(); - return true; + return EvalPointerValueAsBool(PointerResult, Result); } else if (E->getType()->isAnyComplexType()) { APValue ComplexResult; if (!EvaluateComplex(E, ComplexResult, Info)) @@ -937,10 +941,27 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (!EvaluatePointer(E->getRHS(), RHSValue, Info)) return false; - // Reject any bases; this is conservative, but good enough for - // common uses - if (LHSValue.getLValueBase() || RHSValue.getLValueBase()) - return false; + // Reject any bases from the normal codepath; we special-case comparisons + // to null. + if (LHSValue.getLValueBase()) { + if (!E->isEqualityOp()) + return false; + if (RHSValue.getLValueBase() || RHSValue.getLValueOffset()) + return false; + bool bres; + if (!EvalPointerValueAsBool(LHSValue, bres)) + return false; + return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E); + } else if (RHSValue.getLValueBase()) { + if (!E->isEqualityOp()) + return false; + if (LHSValue.getLValueBase() || LHSValue.getLValueOffset()) + return false; + bool bres; + if (!EvalPointerValueAsBool(RHSValue, bres)) + return false; + return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E); + } if (E->getOpcode() == BinaryOperator::Sub) { const QualType Type = E->getLHS()->getType(); |

