[cfe-dev] PR16833 - Analyzer hangs trying to analyze large case ranges

Zach Davis zdavkeos at gmail.com
Mon Aug 18 07:41:53 PDT 2014

Let me see if I understand what you are saying:

We are able to symbolically evaluate (correctly) the "x >= lower && x
<= upper" expression with SVal's. However, we can't 'remember' this
result because we don't construct a Constraint on the expression, and
even if we did the existing RangeConstraint manager doesn't support

I feel like the RangeConstraint manager is really the best way to fix
this, even if it's not easy.  It doesn't seem to be a huge issue
anyway, if someone _really_ wants to analyse a file with such an
expression, they can use the patch i supplied in the mean time.

Unfortunately, looking through the Constraint manager(s) code, I have
no idea where to start.


On Tue, Aug 12, 2014 at 9:38 PM, Jordan Rose <jordan_rose at apple.com> wrote:
> That FIXME, and indeed the code to support case ranges, actually predates
> RangeConstraintManager, which implements most of what the FIXME is referring
> to. (That is, the technical/historical reason we couldn't do it symbolically
> is "it wasn't implemented yet".) So your change is in fact on the right
> track.
> However, what you've done is construct the expression "$x >= LOWER && $x <=
> UPPER". This is correct, but it's not a form that RangeConstraintManager
> will actually handle right now:
> void clang_analyzer_eval(int);
> void test(int i) {
> switch (i) {
> case 1 ... 5:
> return;
> }
> clang_analyzer_eval(x == 2); // should print FALSE, but will print UNKNOWN
> with your patch.
> }
> (clang_analyzer_eval is a special function used to probe the analyzer state,
> handled by the debug.ExprInspection checker.)
> The easiest way to fix this would be to use assumeDual on each expression
> individually. Then you end up with three cases: $x < LOWER, $x is in range,
> and $x > UPPER. Unfortunately, you'd then have to restructure the whole
> function, which currently assumes that you end up with exactly one state
> that can end up in the "default" branch. That wouldn't be too hard.
> The harder way to solve this is to actually teach [Range]ConstraintManager
> to recognize constraints like this, and do the right thing. The
> implementation is already set up to handle disjoint sets of ranges, so you
> could actually do this without changing everything. It's probably more messy
> than you'd like, though.
> The sneaky way to do this is to realize that "$x >= LOWER && $x <= UPPER" is
> actually equivalent to "$x - (LOWER - MIN) <= UPPER - (LOWER - MIN)", where
> MIN is the minimum value for the integer type, for integers with wraparound
> semantics. (RangeConstraintManager actually takes advantage of this in
> reverse to translate "$x - OFFSET <= VALUE" back into a pair of range
> disjunctions.) The only trouble with doing something like this is that
> wraparound is Hardâ„¢ and you/we will want to be very careful that this
> actually handles everything correctly, for all the integer types we care
> about. A definite benefit of this is that we're back to only having one
> state, which prevents potential exponential explosion as analysis continues.
> What do you think we should do here?
> Jordan
> On Aug 12, 2014, at 12:39 , Zach Davis <zdavkeos at gmail.com> wrote:
> All-
> I was looking over 16833 and had a few questions.
> The issue is the analyzer tries to concretize all the values in a case
> statement with a range value:
>    switch (a) {
>        case 1 ... 0xfffff: // hang's trying each value in the range
>           return 1;
>        default:
>           return 0;
>    }
> Is there any reason we can't symbolically evaluate 1 <= a <= 0xfffff,
> rather than trying each 'a == v for v in 1..0xfffff'? I've attached a
> patch that attempts to do this and it seems to work (it no longer
> hangs anyway).  Is there a technical/historical reason for doing it
> the current way?
> The FIXME above the block mentions using '"ranges" for NonLVals'. I'm
> not sure what this means, or if any work has been done toward this.
> If not, would there be any value in pursing a patch like this in the
> meantime to resolve the performance issue?
> Thanks,
> Zach
> <16833_hang_on_large_case_range.patch>_______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

More information about the cfe-dev mailing list