Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Zero-length VLA test doesn't do adequate range propagation #9560

Open Quuxplusone opened 13 years ago

Quuxplusone commented 13 years ago
Bugzilla Link PR9200
Status NEW
Importance P normal
Reported by David Chisnall (csdavec@swan.ac.uk)
Reported on 2011-02-11 06:23:12 -0800
Last modified on 2011-06-06 16:38:07 -0700
Version trunk
Hardware PC All
CC jrose@belkadan.com, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
The analyser is reporting incorrectly in this instance

2092       if (ptr == end)
3 Taking false branch

2093        {
2094          return 0;
2095        }
2096      else
2097        {
2098          unsigned  len = (end - ptr) < 32 ? (end - ptr) : 31;
4 '?' condition is true

2099          char  buf[len+1];
5 Declared variable-length array (VLA) has zero size

From line 2092, it knows that ptr != end, therefore ptr - end is not 0.  On
line 2098, it is taking the condition as true, therefore end - ptr < 32.  This
means that end-ptr is guaranteed to be in the range 1-31.  Therefore, the size
of the VLA is 2-32.

Note that even without the original case being propagated, the condition tells
us that len is in the range 0-31, therefore len + 1 can not be 0.
Quuxplusone commented 13 years ago
Well, no, in theory "end - ptr" could be -1, which then gets implicitly
converted to an unsigned after the comparison has finished. If you cast "end -
ptr" to unsigned before the comparison, or even test that ptr < end instead of
==, there should be no warning. But with just your example I can't reproduce
the warning.

// This analyzes cleanly...am I missing something?
void x (int *y, int *z) {
    if (y == z) return;
    unsigned len = (y - z) < 32 ? (y - z) : 31;
    char buf[len+1];
}

(I believe the analyzer still assumes -fwrapv semantics all the time, so
converting -1 into unsigned can still give a zero value when you add 1.)