зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
1b63e4f732
Коммит
5bc8610376
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче