PR4351: Add constant evaluation for constructs like "foo == NULL", where

foo has a constant address.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73321 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2009-06-14 02:17:33 +00:00
Родитель 1b63e4f732
Коммит 5bc8610376
2 изменённых файлов: 31 добавлений и 8 удалений

Просмотреть файл

@ -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();

Просмотреть файл

@ -66,3 +66,5 @@ 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)
EVAL_EXPR(33, (void*)0 - (void*)0 == 0 ? 1 : -1)
void foo(void) {}
EVAL_EXPR(34, (foo == (void *)0) ? -1 : 1)