> On Nov 17, 2017, at 1:50 AM, Jakub Jelinek <[email protected]> wrote:
>
> On Thu, Nov 16, 2017 at 06:14:35PM -0700, Jeff Law wrote:
>>> However, this routine currently miss a very obvious case as the following:
>>>
>>> char s[100] = {'a','b','c','d’};
>>>
>>> __builtin_strcmp(s, "abc") != 0
>>>
>>> So, I have to change this routine to include such common case.
>>>
>>> do you think using this routine is good? or do you have other
>>> suggestions (since I am still not very familiar with the internals of
>>> GCC, might not find the best available one now…)
>> The range information attached to an SSA_NAME is global data. ie, it
>> must hold at all locations where the object in question might be
>> referenced. This implies that it will sometimes (often?) be less
>> precise than you might like.
>>
>> I am currently working towards an embeddable context sensitive range
>> analyzer that in theory could be used within tree-ssa-strlen pass to
>> give more precise range information. I'm hoping to wrap that work up in
>> the next day or so so that folks can use it in gcc-8.
>
> Well, one thing is a range of integral SSA_NAME at a certain point, the
> other is the length of the C string pointed by a certain pointer (that is
> something the strlen pass tracks), and another case is the content of that
> string, which you'd presumably need to optimize the strcmp at compile time.
> I think current strlen pass ought to find out that strlen (s) is 4 at that
> point, if it doesn't, please file a PR with a testcase.
for the safety checking purpose, when we try to convert
__builtin_strcmp(s, "abc") != 0
to
__builtin_memcmp (s, “abc”, 4) != 0
we have to make sure that the size of variable “s” is larger than “4”.
if “s” is declared as
char s[100];
currently, the “get_range_strlen” cannot determine its maximum length is 100.
(it just return UNKNOWN).
so, I have to update “get_range_strlen” for such simple case.
this does provide the information I want. However, since the routine
“get_range_strlen” is also used in other places,
for example, in gimple-ssa-sprintf.c, the implementation of the sprintf
overflow warning uses the routine “get_range_strlen”
to decide the string’s maximum size and buffer size.
my change in “get_range_strlen” triggered some new warnings for
-Werror=format-overflow (from gimple-ssa-sprintf.c
mentioned above) as following:
qinzhao@gcc116:~/Bugs/warning$ cat t.c
#include <stdio.h>
void foo(const char *macro)
{
char buf1[256], buf2[256];
sprintf (buf1, "%s=%s", macro, buf2);
return;
}
with my private GCC:
qinzhao@gcc116:~/Bugs/warning$ /home/qinzhao/Install/latest/bin/gcc t.c
-Werror=format-overflow -S
t.c: In function ‘foo’:
t.c:6:18: error: ‘sprintf’ may write a terminating nul past the end of the
destination [-Werror=format-overflow=]
sprintf (buf1, "%s=%s", macro, buf2);
^~~~~~~
t.c:6:3: note: ‘sprintf’ output 2 or more bytes (assuming 257) into a
destination of size 256
sprintf (buf1, "%s=%s", macro, buf2);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
At this time, I am really not sure whether it’s good to expose such new
warnings with my change? even though after some study,
I think that these new warning are correct warnings, maybe we should keep?
let me know your comments and suggestions.
thanks a lot.
Qing
> Jakub