On 08/21/2018 10:35 AM, Martin Sebor wrote:
> On 08/21/2018 09:59 AM, Jeff Law wrote:
>> On 08/21/2018 09:57 AM, Martin Sebor wrote:
>>> On 08/21/2018 02:59 AM, Richard Biener wrote:
>>>> On Tue, 21 Aug 2018, Bernd Edlinger wrote:
>>>>
>>>>> gcc -S -O2 -Wall -Wformat-overflow -ftrack-macro-expansion=0
>>>>> -fshort-wchar builtin-sprintf-warn-20.c
>>>>> builtin-sprintf-warn-20.c: In function 'test':
>>>>> builtin-sprintf-warn-20.c:19:39: warning: hex escape sequence out of
>>>>> range
>>>>> 19 |     ? (char*)L"\x4142\x4344" : (char*)L"\x41424344\x45464748";
>>>>>     |                                       ^~~~~~~~~~~~~~~~~~~~~~~
>>>>>
>>>>> Hmm, this test might create some noise on short-wchar targets.
>>>>>
>>>>> I would prefer a warning here, about the wrong type of the parameter.
>>>>> The buffer overflow is only a secondary thing.
>>>>>
>>>>> For constant objects like those, the GIMPLE type is still guaranteed
>>>>> to be reliable,
>>>>> right?
>>>>
>>>> TREE_TYPE of tcc_declaration and tcc_constant trees should more-or-less
>>>> (minus qualifications not affecting semantics) be those set by
>>>> frontends.
>>>
>>> A warning for these cases should be relatively  straightforward
>>> to add to the sprintf pass.  It would require c_strlen() to return
>>> the type of the string argument to the caller.  That way sprintf's
>>> format_string() function could compare the string type to the
>>> expected type of the directive.
>> Umm, why would c_strlen need to return that?  We should be able to get
>> to it directly from the argument?!?  What am I missing here?
> 
> The sprintf pass sees the type of the argument.  In the literal
> case above the cast is folded away and so sprintf does see
> the type of the argument.  In more interesting cases like
> the one below it sees the type of the argument (i.e., wchar_t*)
> but c_strlen() has the smarts to get at the underlying object:
> 
>   const char a[] = "1234";
> 
>   int f (int i)
>   {
>     __WCHAR_TYPE__ *p = a;
> 
>     return __builtin_snprintf (0, 0, "%ls", &p[i]);
Presumably it'd have to be bubbled up from string_constant, right?

Jeff

Reply via email to