[cfe-dev] Relaxing format specifier checks

Hubert Tong via cfe-dev cfe-dev at lists.llvm.org
Thu May 17 08:01:48 PDT 2018


On Thu, May 17, 2018 at 1:56 AM, JF Bastien <jfbastien at apple.com> wrote:

>
>
> On May 16, 2018, at 10:51 PM, Hubert Tong <hubert.reinterpretcast at gmail.
> com> wrote:
>
> On Thu, May 17, 2018 at 1:36 AM, JF Bastien <jfbastien at apple.com> wrote:
>
>>
>> On May 16, 2018, at 10:15 PM, Hubert Tong via cfe-dev <
>> cfe-dev at lists.llvm.org> wrote:
>>
>> On Fri, May 11, 2018 at 7:26 PM, Shoaib Meenai via cfe-dev <
>> cfe-dev at lists.llvm.org> wrote:
>>
>>> Of course, we should also ensure that the optimizer doesn't do anything
>>> surprising when there's a type mismatch between the specifier and the
>>> argument but both types have the same size and alignment (i.e., the case
>>> where the relaxed format warning won't fire), both now and in the future.
>>>
>> The "contract" for the format string and the corresponding argument is as
>> described elsewhere in the thread, and it is rather more interesting for
>> scanf than not. GCC's implementation technology is apparently able to
>> optimize (at -O2 and up, at least when targeting powerpc64le-linux-gnu) the
>> check feeding the abort() in the following to not observe the write
>> performed in the ersatz scanf():
>> #include <stdarg.h>
>> void abort(void);
>> int strcmp(const char *, const char *);
>>
>> typedef int Type;
>> typedef long NType;
>>
>> int myvscanf(const char *const fmt, va_list ap) {
>>   if (strcmp(fmt, "%ld") != 0) { return 0; }
>>
>>   NType *const p = va_arg(ap, NType *);
>>   *p = 42;
>>   return 1;
>> }
>>
>> __attribute__((__format__(__scanf__, 2, 3)))
>> __attribute__((__noinline__, __noclone__))
>> void updateStatusFromPipe(Type *statusp, const char *const fmt, ...) {
>>   va_list ap;
>>   va_start(ap, fmt);
>>   int ret = 0;
>>   if (*statusp == 0) {
>>     ret = myvscanf(fmt, ap);
>>   }
>>   va_end(ap);
>>   if (ret >= 1 && *statusp != 0) abort();
>> }
>>
>> int main(void) {
>>   Type status = 0;
>>   updateStatusFromPipe(&status, "%ld", &status);
>> }
>>
>> The "now or in the future" sounds like needing to do "worse" or "better"
>> than what GCC is doing to avoid "anything surprising", because "on par"
>> with GCC fits the bill for something "surprising". Which is to say that, in
>> my opinion, there is no avoiding "something surprising" "in the future" on
>> code that the proposed relaxation is letting slip through.
>>
>> TL;DR: Please don't change the default.
>>
>>
>> The default has changed recently. We’re making the case that parts should
>> be relegated to their own flag.
>>
>> Your argument ignores the prerogative that platforms have in providing
>> additional guarantees. NSInteger has that guarantee on Darwin platforms, it
>> should be honored. I further don’t see how optimizing printf as you seem to
>> suggest could be possible is ever useful or desirable.
>>
> Why is changing the behaviour for "everyone" for possible guarantees on
> some platforms the approach as opposed to adjusting the warning based on
> the guarantees that the target to known to provide?
>
>
> I suspect that reading https://reviews.llvm.org/D42933 would help
> understand the current proposal.
>
Okay, I needed the context in terms of how the proposal evolved. Thanks.


> If not, I’d like to understand which part of D42933 you don’t agree with.
>
Something Darwin-specific was considered to begin with in D42933; however,
the discussion has evolved, and the version being proposed in this thread
applies past the default that "recently changed". I am responding to this
proposal, not D42933 (which, at this point, is more a discussion than a
proposal).


> Specifically, is it about platform guarantees,
>
I understand that platforms may provide guarantees, and that software may
be written with those platforms in mind. Clang might not be limited to
platforms with certain specific guarantees, and so, I think that adjusting
for platform guarantees should be opt-in (by the target or otherwise).

Furthermore, the extent of the specific guarantee being mentioned might be
of interest. Is this a platform guarantee beyond having the same object
representation, same value representation for all values, and the same
alignment? A possible reading of the proposal with regards to conversion
specifications for pointers to integral types would say that the proposal
is talking about the type pointed to. Guarantees on the validity of using
glvalues of one type to access objects of the other would then be of
interest.

I agree that it is possible to read the proposal as not applying to pointer
arguments. I am hoping we are good with clarifying on taking the latter
interpretation.


> portability warnings,
>
The proposed change goes beyond nixing portability checking. It is a shift
in a contract between the caller providing a format string, and a callee
processing a format string. It assumes specific details about how variable
arguments work in the calling convention, how the attendant macros are
implemented, and limitations in optimizer technology. It may be weird, but
not prohibited, for types that cannot be differentiated when in memory to
have different treatment in the registers used to pass them.


> printf specifically versus other format-like warnings, etc?
>
I think the major use case for the proposal is covered by limiting the
scope to changing the checking of arguments of integral type to the
"system-provided" printf family of functions.


>
> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180517/f606aaee/attachment.html>


More information about the cfe-dev mailing list