VRP: rewrite the division code (to handle corner cases including 0)

Aldy Hernandez aldyh@redhat.com
Wed Aug 15 01:33:00 GMT 2018


Howdy!

In auditing the *_DIV_EXPR code I noticed that we were really botching 
some divisions where the divisor included 0.

Particularly interesting was that we were botching something as simple 
as dividing by [0,0].  We were also incorrectly calculating things like 
[-2,-2] / [0, 5555], where we should have removed the 0 from the divisor.

Also, the symbolic special casing could be handled by just treating 
symbolic ranges as [-MIN, +MAX] and letting the common code handle then. 
  Similarly for anti ranges, which actually never happen except for the 
constant case, since they've been normalized earlier.

All in all, it was much easier to normalize all the symbolic ranges and 
treat everything generically by performing the division in two chunks... 
the negative numbers and the (non-zero) positive numbers.  And finally, 
unioning the results.  This makes everything much simpler to read with 
minimal special casing.

Finally, my apologies for including a tiny change to the 
POINTER_PLUS_EXPR handling code as well.  It came about the same set of 
auditing tests.

It turns out we can handle POINTER_PLUS_EXPR(~[0,0], [X,Y]) without 
bailing as VR_VARYING in extract_range_from_binary_expr_1.  In doing so, 
I also noticed that ~[0,0] is not the only non-null.  We could also have 
~[0,2] and still know that the pointer is not zero.  I have adjusted 
range_is_nonnull accordingly.

(Yes, we can get something like ~[0,2] for a pointer for things like the 
following in libgcc:

   if (segment_arg == (void *) (uintptr_type) 1)
     ...
   else if (segment_arg == (void *) (uintptr_type) 2)
     return NULL;
   else if (segment_arg != NULL)
     segment = (struct stack_segment *) segment_arg;
)

BTW, I am still not happy with the entire interface to wide-int-range.*, 
and have another pending patchset that will simplify things even 
further.  I think everyone will be pleased ;-).

OK pending another round of tests?

Aldy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: curr.patch
Type: text/x-patch
Size: 14762 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20180815/f204bd7a/attachment.bin>


More information about the Gcc-patches mailing list