Change the binary operator data recursive evaluator to not stop at the first

non-constant value encountered.  This allows the evaluator to deduce that
expressions like (x < 5 || true) is equal to true.  Previously, it would visit
x and determined that the entire expression is could not evaluated to a
constant.

This fixes PR12318.

llvm-svn: 153226
This commit is contained in:
Richard Trieu 2012-03-21 23:30:30 +00:00
parent 39fb408fd3
commit ba4d0871f7
2 changed files with 23 additions and 16 deletions

View File

@ -4510,12 +4510,10 @@ public:
bool Traverse(const BinaryOperator *E) {
enqueue(E);
EvalResult PrevResult;
while (!Queue.empty()) {
if (!process(PrevResult)) {
Queue.clear();
return false;
}
}
while (!Queue.empty())
process(PrevResult);
if (PrevResult.Failed) return false;
FinalResult.swap(PrevResult.Val);
return true;
@ -4552,7 +4550,7 @@ private:
Result.Val = APValue();
}
bool process(EvalResult &Result);
void process(EvalResult &Result);
void enqueue(const Expr *E) {
E = E->IgnoreParens();
@ -4785,7 +4783,7 @@ bool DataRecursiveIntBinOpEvaluator::
}
}
bool DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
Job &job = Queue.back();
switch (job.Kind) {
@ -4794,13 +4792,13 @@ bool DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
if (shouldEnqueue(Bop)) {
job.Kind = Job::BinOpKind;
enqueue(Bop->getLHS());
return true;
return;
}
}
EvaluateExpr(job.E, Result);
Queue.pop_back();
return true;
return;
}
case Job::BinOpKind: {
@ -4808,26 +4806,26 @@ bool DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
job.LHSResult.swap(Result);
bool IgnoreRHS = false;
bool SuppressRHSDiags = false;
bool ret = VisitBinOpLHSOnly(job.LHSResult, Bop, IgnoreRHS, Result.Val,
SuppressRHSDiags);
Result.Failed = !VisitBinOpLHSOnly(job.LHSResult, Bop, IgnoreRHS,
Result.Val, SuppressRHSDiags);
if (IgnoreRHS) {
Queue.pop_back();
return ret;
return;
}
if (SuppressRHSDiags)
job.startSpeculativeEval(Info);
job.Kind = Job::BinOpVisitedLHSKind;
enqueue(Bop->getRHS());
return ret;
return;
}
case Job::BinOpVisitedLHSKind: {
const BinaryOperator *Bop = cast<BinaryOperator>(job.E);
EvalResult RHS;
RHS.swap(Result);
bool ret = VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
Queue.pop_back();
return ret;
return;
}
}

View File

@ -255,3 +255,12 @@ int test_enum_cases(enum Cases C) {
case C3: return 4;
}
} // no-warning
// PR12318 - Don't give a may reach end of non-void function warning.
int test34(int x) {
if (x == 1) {
return 3;
} else if ( x == 2 || 1) {
return 5;
}
}