[cfe-commits] [Patch] Warn about non-standard format strings (PR12017)

Joerg Sonnenberger joerg at britannica.bec.de
Mon Feb 20 12:21:53 PST 2012


On Mon, Feb 20, 2012 at 12:05:41PM -0800, Ted Kremenek wrote:
> On Feb 20, 2012, at 11:51 AM, Joerg Sonnenberger <joerg at britannica.bec.de> wrote:
> 
> > The default behavior for -Wformat would be "check that the format string
> > is standard compliant". I think that's a perfectively sane default and
> > if someone wants to use non-standard format extensions, clang tells them
> > how to get them.
> 
> There's "non-standard" and then there's completely unportable.  Warnings like:
> 
> +  // Combining 'L' with an integer conversion specifier.
> +  printf("%Li", (long long)42); // expected-warning{{using the length modifier 'L' with the conversion specifier 'i' is non-standard}}
> +  printf("%Lo", (long long)42); // expected-warning{{using the length modifier 'L' with the conversion specifier 'o' is non-standard}}
> 
> are likely going to just irritate people.  What's the value in that?

What is that supposed to mean? From looking at analyze_format_string,
that should give a warning because (a) L doesn't make sense for integers
and (b) because the argument isn't int. Or do you mean the Microsoft
extension for dealing with 64bit integers? Note that this is part of the
reason why silently accepting them is bad -- I need to have a printf(3)
man page for the platform you had in mind when writing this code to even
understand what it is really supposed to do.

> Consider '%S' and and '%C'.  For OS X developers, it may be perfectly
> reasonable to use those, especially if they aren't using printf (there
> are other printf-like APIs on OS X).

Actually, you are pointing to a bigger bug here. I mentioned it in an
earlier discussion on the list. At the moment, the GCC attributes for
format string checking are very course. It is impossible to distinguish
between syslog(3) format strings and printf(3) format strings for
example. The former allows '%m', for the latter it is a glibc extension.
Other APIs like sqlite_mprint are similar -- they allow an extended
subset of the printf(3) formatting, but they don't provide the same set.
I am perfectly fine with allowing all kinds of extensions if the
function is tagged as having those. That would of course still require
glibc to accept patches to tag printf(3) as
__attribute__((__format__(__printf__ | __gnuprintf__, 1, 2))) or
whatever the syntax should look like, but it would work for the other
users of format strings.

Joerg



More information about the cfe-commits mailing list