On March 5, 2020 4:53:43 PM GMT+01:00, Martin Sebor <mse...@gmail.com> wrote:
>On 3/5/20 12:51 AM, Richard Biener wrote:
>> On Thu, Mar 5, 2020 at 12:49 AM Jeff Law <l...@redhat.com> wrote:
>>>
>>> On Wed, 2020-03-04 at 09:22 -0700, Martin Sebor wrote:
>>>>
>>>> I don't remember why the code in -Wrestrict unconditionally
>overwrites
>>>> the statement location rather than only when it's not available,
>but
>>>> I do remember adding conditional code like in your patch in r277076
>>>> to deal with missing location on the statement.  So either your fix
>>>> or something like the hunk below might be the right solution (if we
>>>> go with the code below, abstracting it into a utility function
>might
>>>> be nice).
>>> So there's several chunks that are fairly similar to what you
>referenced in
>>> maybe_warn_pointless_strcmp.  Factoring all of them into a single
>location is
>>> pretty easy.
>>>
>>> That also gives us a nice place where we can experiment with "does
>extraction of
>>> location information from the expression ever help".  The answer is,
>it doesn't,
>>> at least not within our testsuite when run on x86_64.
>>>
>>> I'm hesitant to remove the code that extracts the location out of
>the expression,
>>> but could be convinced to do so.
>>>
>>> Thoughts?
>> 
>> Using anything but the actual stmt location is prone to end up at
>random places
>> due to tree sharing issues, CSE and copy propagation.  Simply
>consider
>> 
>> char one[50];
>> char two[50];
>> 
>> void
>> test_strncat (void)
>> {
>>    char *p = one;
>>    (void) __builtin_strcpy (p, "gh");
>>    (void) __builtin_strcpy (two, "ef");
>> 
>> #pragma GCC diagnostic push
>> #pragma GCC diagnostic ignored "-Wstringop-overflow="
>> #pragma GCC diagnostic ignored "-Warray-bounds"
>>    (void) __builtin_strncat (p, two, 99);
>
>Interestingly, while the expression location points to p, the warning
>points to the statement:
>
>warning: ‘__builtin_strncat’ forming offset [50, 98] is out of the 
>bounds [0, 50] of object ‘one’ with type ‘char[50]’ [-Warray-bounds]
>    14 |   (void) __builtin_strncat (p, two, 99);
>       |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>As it happens, the %G directive in the warning_at() call replaces
>the location passed to it with that of the Gimple call argument to
>the %G directive.  Removing the %G directive turns the warning into:
>
>warning: ‘__builtin_strncat’ forming offset [50, 98] is out of the 
>bounds [0, 50] of object ‘one’ with type ‘char[50]’ [-Warray-bounds]
>     7 |   char *p = one;
>       |             ^~~
>
>But the code that checks the scope of #pragma GCC diagnostic uses
>the original location passed to warning_at, not the location set
>subsequently by the %G directive, and so the two are out of synch.

Ah, I see. 

>We've discussed removing the %G/%K directives before and having
>the diagnostic machinery always print the inlining context instead.
>Let me look into it for GCC 11.
>
>Martin
>
>> #pragma GCC diagnostic pop
>> }
>> 
>> where we happily forward p = &one[0] to both uses injecting
>> a "faulty" location.  Well, it's actually the correct location
>> computing &one[0] but irrelevant for the actual call.
>> 
>> So the question is why we end up with UNKNOWN_LOCATION
>> for such call and if why we need to bother emit a diagnostic
>> at all (and why emitting it for another possibly random location is a
>good idea
>> instead of maybe simply emitting it without location).
>> 
>> Richard.
>> 
>>> Jeff

Reply via email to