This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] set range for strlen(array) to avoid spurious -Wstringop-overflow (PR 83373 , PR 78450)


On Thu, Dec 14, 2017 at 5:01 PM, Martin Sebor <msebor@gmail.com> wrote:
> On 12/14/2017 03:43 AM, Richard Biener wrote:
>>
>> On Wed, Dec 13, 2017 at 4:47 AM, Martin Sebor <msebor@gmail.com> wrote:
>>>
>>> On 12/12/2017 05:35 PM, Jeff Law wrote:
>>>>
>>>>
>>>> On 12/12/2017 01:15 PM, Martin Sebor wrote:
>>>>>
>>>>>
>>>>> Bug 83373 - False positive reported by -Wstringop-overflow, is
>>>>> another example of warning triggered by a missed optimization
>>>>> opportunity, this time in the strlen pass.  The optimization
>>>>> is discussed in pr78450 - strlen(s) return value can be assumed
>>>>> to be less than the size of s.  The gist of it is that the result
>>>>> of strlen(array) can be assumed to be less than the size of
>>>>> the array (except in the corner case of last struct members).
>>>>>
>>>>> To avoid the false positive the attached patch adds this
>>>>> optimization to the strlen pass.  Although the patch passes
>>>>> bootstrap and regression tests for all front-ends I'm not sure
>>>>> the way it determines the upper bound of the range is 100%
>>>>> correct for languages with arrays with a non-zero lower bound.
>>>>> Maybe it's just not as tight as it could be.
>>>>
>>>>
>>>> What about something hideous like
>>>>
>>>> struct fu {
>>>>   char x1[10];
>>>>   char x2[10];
>>>>   int avoid_trailing_array;
>>>> }
>>>>
>>>> Where objects stored in x1 are not null terminated.  Are we in the realm
>>>> of undefined behavior at that point (I hope so)?
>>>
>>>
>>>
>>> Yes, this is undefined.  Pointer arithmetic (either direct or
>>> via standard library functions) is only defined for pointers
>>> to the same object or subobject.  So even something like
>>>
>>>  memcpy (pfu->x1, pfu->x1 + 10, 10);
>>>
>>> is undefined.
>>
>>
>> There's nothing undefined here - computing the pointer pointing
>> to one-after-the-last element of an array is valid (you are just
>> not allowed to dereference it).
>
>
> Right, and memcpy dereferences it, so it's undefined.

That's interpretation of the standard that I don't share.

Also, if I have struct f { int i; int j; };  and a int * that points
to the j member you say I have no standard conforming way
to get at a pointer to the i member from this, right?  Because
the pointer points to an 'int' object.  But it also points within
a struct f object!  So at least maybe (int *)((char *)p - offsetof
(struct f, j))
should be valid?  This means that pfu->x1 + 10 is a valid pointer
into *pfu no matter what you say and you can dereference it.

Richard.

> Martin
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]