[cfe-dev] Relaxing format specifier checks
James Y Knight via cfe-dev
cfe-dev at lists.llvm.org
Thu May 17 07:52:09 PDT 2018
This is a convincing point, but the reasoning here is somewhat different,
since it's dealing with pointer-types, and then an actual
pointer-dereference of the incorrect type. That's certainly a bad idea -- I
agree it'd be quite unwise to change the behavior when dealing with
pointers, either in the scanf specifiers or for the expected pointee-type
of %n in printf.
I think the question at hand is whether a type-mismatch of the value itself
is a problem you should be worried about. E.g., calling "va_arg(long)" when
passing a value of type int to the call, where int and long are "the same".
On Thu, May 17, 2018 at 1:16 AM 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.
> _______________________________________________
> 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/a0b9c0a1/attachment.html>
More information about the cfe-dev
mailing list