[cfe-dev] cfe-dev Digest, Vol 48, Issue 10
Peter Lawrence
peterl95124 at sbcglobal.net
Sun Jun 5 16:03:30 PDT 2011
Jordy,
using "L" for the value of strlen(),
and "min(L,10)" for the value of strnlen(,10)
in general we know
L >= 0
in the then-clause of the if-statement we know this additional relation
min(L,10) != L
from which a good algebraic system might choose to simplify to
L > 10
and that's about all. its a constraint, not a value.
I am guessing you already knew that, and your post results from the
static analyzer trying use a different form of reasoning, a different
algorithm. But I believe the above is the most mathematically complete
information that can be derived from the situation, anything else (like
"conjured values", what ever that means) will necessarily involve
creating and propagating false information.
for the second example, being after the first if-statement is like being
in its else-clause, so we have
min(L,10) >= 5
again a good algebraic system might want to simplify this to
L >= 5
feeding that into the second if-statement conditional we get
min( (L >= 5), 10 ) < 5
which a good algebraic system should evaluate to false, which
should eliminate the false-positive null-pointer warning. Notice that
this conclusion is arrived at without any "conjured values" (whatever
that
means).
but that is only if your system propagates "constraints", not just
"values",
and as I have spent most of my recent past working with llvm-ir rather
than clang, I await your enlightened response...
sincerely,
Peter Lawrence.
On Jun 4, 2011, at 10:00 AM, cfe-dev-request at cs.uiuc.edu wrote:
> ------------------------------
>
> Message: 2
> Date: Fri, 3 Jun 2011 16:45:14 -0700
> From: Jordy Rose <jediknil at belkadan.com>
> Subject: [cfe-dev] Fixes for strnlen() in CStringChecker
> Cc: cfe-dev at cs.uiuc.edu
> Message-ID: <4486B9B8-A35C-4266-A396-A3DB1518A567 at belkadan.com>
> Content-Type: text/plain; charset="us-ascii"
>
> [originally to Lenny and Ted]
>
> So I started cleaning up strLengthCommon() in CStringChecker and
> ran into a problem concerning strnlen(). The code that's in there
> now handles the case where the limit argument is less than the
> string length, and works when it's greater. But when you can't say
> either with certainty, it's returning the string length by default
> right now. That then allows mistaken assumptions about the length
> of the string from then on.
>
> Basically, this test fails:
>
> void strnlen_is_not_strlen(char *x) {
> if (strnlen(x, 10) != strlen(x))
> (void)*(char*)0; // expected-warning{{null}}
> }
>
> The problem is, fixing this breaks a number of other tests, like
> this one:
>
> void strnlen_liveness(const char *x) {
> if (strnlen(x, 10) < 5)
> return;
> if (strnlen(x, 10) < 5)
> (void)*(char*)0; // no-warning
> }
>
> This is because this tells us nothing about the actual length of x,
> and we get two independent conjured values here. I don't know how
> we'd want to go about fixing this, or if we should at all.
>
> Attached: the patch, including the new tests but without removing
> the now-broken ones. What's the best thing to do here?
>
> Jordy
>
> -------------- next part --------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110605/6beef3b8/attachment.html>
More information about the cfe-dev
mailing list