> On Nov 17, 2017, at 1:50 AM, Jakub Jelinek <ja...@redhat.com> 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

Reply via email to