[PATCH] - improve sprintf buffer overflow detection (middle-end/49905)

Joseph Myers joseph@codesourcery.com
Thu Oct 6 21:30:00 GMT 2016

On Thu, 6 Oct 2016, Martin Sebor wrote:

> > The problem is that extracting via an integer of the opposite signedness
> > is *not* defined unless the argument has a value representable in both
> > types - both as a matter of ISO C rules on variadic functions, and as a
> > practical matter of what various ABIs say about how sub-word arguments are
> > extended when passed as function arguments.
> No, sign mismatch is not the problem we're discussing.  GCC doesn't
> warn for %lc when wchar_t and wint_t differ in signedness except
> with -Wformat-signedness.  The cause of the warning is that wchar_t
> is a distinct type from wint_t such as long from int (irrespective
> of their sign), even if the two have the same size, and the checker
> doesn't distinguish the typedefs from the underlying types.

For most configurations of GCC, wint_t is unsigned int (the default from 
defaults.h).  Only a few specific (OS, CPU) pairs make a different choice.

> I did say, however, that the warning might have some merit even
> in this case if there also were a target to which the code could
> be ported where wchar_t and wint_t had different sizes (i.e., as
> a portability warning).  But for such a portability warning to
> be useful it would need to be issued by all GCC compilers, not
> just when compiling for the target with that property.  (But
> since neither of us knows(*) of such a target this is a moot
> point.)

As I pointed out, wint_t and wchar_t are ABI-incompatible when passed to 
functions on powerpc64-linux-gnu, because of the different signedness, 
even though they have the same size.

Thus, diagnosing the wrong choice of type is useful as a portability 
warning.  Unfortunately, it's hard to diagnose it on architectures where 
wchar_t and wint_t are the same type or too similar, but by diagnosing 
where they are sufficiently different at the C level (but possibly not at 
the ABI level), code can be fixed so it doesn't break in cases where the 
difference matters.

> The text of the warning itself indicates that even suggesting how
> to fix it isn't trivial.  GCC warns for just for the %lc directive
> (not for the sign mismatch) and suggests to fix it by replacing
> the %lc directive with %ld.  That's clearly wrong.  Printing

It's true the hint is wrong, but the warning is right.

Joseph S. Myers

More information about the Gcc-patches mailing list