[PATCH] Remove NOTHROW from {,v}{,f}{print,scan}f, {,f}printf_unlocked and __{,v}{,f}printf_chk builtins

Mark Mitchell mark@codesourcery.com
Wed Sep 5 00:16:00 GMT 2007

Jakub Jelinek wrote:
> On Tue, Sep 04, 2007 at 10:07:00AM -0700, Mark Mitchell wrote:
>>> What we could do is when we see a prototype, update the NOTHROW state
>>> not only of the DECL_ANTICIPATED builtin, but also its __builtin_* variant.
>> That seems like it might be an improvement.  I guess the problem is if
>> __builtin_printf decides to go call "puts", and "puts" is declared to
>> throw exceptions, even though "printf" is not.  So, presumably we don't
>> set the bit on the builtin because we can't be sure it's safe.
> Well, TREE_NOTHROW __builtin_printf and __builtin_puts with !TREE_NOTHROW
> is what we had for the last 3 years, I don't remember any ICEs with it.

I was just trying to justify why we don't presently mark the builtins.
I wouldn't expect an ICE, it's just that we could get wrong code in a
situation like that.

> As long as we don't ICE here, I think we are fine, libraries that
> have puts that can throw and printf that can't are IMHO broken.
> Either both of them can throw, or neither can.

If you say so. :-)  I certainly understand your logic, but we're
definitely wandering around outside the standard.  In ISO C++, neither
can throw.  In POSIX, with cancellation implemented as an exception,
both can.  I can imagine implementations where puts never throws, but
printf does -- for example, if it runs out of memory trying to format a
string.  That's not supposed to be an exception in C++, but that doesn't
mean someone's runtime library won't do it.

But, OK, I'm willing to concede this point.

> Ok, so how about following patch together with the earlier posted
> builtins.def fix (http://gcc.gnu.org/ml/gcc-patches/2007-09/msg00103.html).

I appreciate you working on this.  I guess this patch is OK; it seems
better than nothing.  But, it's not ideal.  For GNU/Linux we get the
throw-ness of builtins (e.g., "__builtin_printf") right by default,
without any declarations; why shouldn't we do just as well on other
systems?  Why should we expect that there's only one right answer to
whether or not these library functions throw exceptions?  Even on
GNU/Linux systems, wouldn't an -fno-threads compilation mode be a good
way for people to get smaller code in single-threaded programs?

As to the patch itself, I think this:

> +      /* When there is explicit declaration of builtin with throw(),
> +	 say printf, propagate TREE_NOTHROW even to the __builtin
> +	 variant (__builtin_printf in this case).  */

would be clearer as:

  /* If a function is explicitly declared "throw ()", propagate that to
     the corresponding builtin.  */

> +  else if (strncmp (name + 2, "builtin_", sizeof ("builtin_") - 1) != 0)

No need to be this clever; just strlen ("builtin") is fine.  (GCC will
of course optimize it, and we don't need to make our code more obscure
to get better code from non-GCC compilers used to build cross compilers.)

If the first patch goes in, then this second patch is OK with those
minor tweaks.  Thanks for working on it.


Mark Mitchell
(650) 331-3385 x713

More information about the Gcc-patches mailing list