[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#377416: libc6-dev: __THROW defined in <sys/cdefs.h> is broken with GCC 3.3



Pierre HABOUZIT <madcoder@debian.org> writes:

> tag 377416 + moreinfo
> thanks
>
> On Sat, Jul 08, 2006 at 08:14:35PM +0100, Roger Leigh wrote:
>> Package: libc6-dev
>> Version: 2.3.6-15
>> Severity: important
>> 
>> # if !defined __cplusplus && __GNUC_PREREQ (3, 3)
>> #  define __THROW       __attribute__ ((__nothrow__))          XXXX
>> #  define __NTH(fct)    __attribute__ ((__nothrow__)) fct
>> # else
>> #  if defined __cplusplus && __GNUC_PREREQ (2,8)
>> #   define __THROW      throw ()
>> #   define __NTH(fct)   fct throw ()
>> #  else
>> #   define __THROW
>> #   define __NTH(fct)   fct
>> #  endif
>> # endif
>> 
>> The line marked with XXXX expands incorrectly:
>> 
>> void f() __THROW
>> ==> void f() __attribute__ ((__nothrow__))
>> 
>> instead of void __attribute__ ((__nothrow__)) f()
>
>   I'm not sure to understand where the problem is.

I thought I explained the problem adequately in the bug report.  Look
at the example in the very first entry.  The versions for GCC >= 3.3
are totally different from >= 2.8.  GCC function attributes are
specified *before* the function name, and yet the GCC >= 2.8 variation
uses throw() which is used *after* the function name and arguments.
As a result, it it will break depending upon the compiler version,
because wherever you put __THROW it will always be broken on one
compiler.

You'll see __NTH gets it right, because you give it the function name
and it can place the expansion on the correct side.

For further information:

Check for all the definitions of __THROW and __NTH in /usr/include:

hardknott% rgrep 'define[[:space:]]*__THROW' /usr/include
/usr/include/argp.h:# define __THROW
/usr/include/malloc.h:#   define __THROW        throw ()
/usr/include/malloc.h:#   define __THROW
/usr/include/malloc.h:# define __THROW
/usr/include/getopt.h:#  define __THROW throw ()
/usr/include/getopt.h:#  define __THROW
/usr/include/sys/cdefs.h:#  define __THROW      __attribute__ ((__nothrow__))
/usr/include/sys/cdefs.h:#   define __THROW     throw ()
/usr/include/sys/cdefs.h:#   define __THROW
/usr/include/sys/cdefs.h:# define __THROW

hardknott% rgrep 'define[[:space:]]*__NTH' /usr/include
/usr/include/argp.h:# define __NTH(fct) fct __THROW
/usr/include/sys/cdefs.h:#  define __NTH(fct)   __attribute__ ((__nothrow__)) fct
/usr/include/sys/cdefs.h:#   define __NTH(fct)  fct throw ()
/usr/include/sys/cdefs.h:#   define __NTH(fct)  fct
/usr/include/sys/cdefs.h:# define __NTH(fct)    fct

Next, check each one and compare them.  You'll see that each is
different, so depending upon the header include order, you'll get a
different definition.  Some include version checks for different GCC
versions, and others include /different/ version checks and
definitions.  This is a mess.  Some, as this bug report highlights,
are broken under some circumstances, so the programmer is screwed
however they use __THROW.  The circumstances resulting in this bug
report are in fact building glibc itself.

In some cases, this can cause severe problems.  See #340871 for an
extreme example, where it broke the m68k build.  The patch that fixed
it required inserting *yet another* __THROW definition due to the
above problems.  See

http://bugs.debian.org/cgi-bin/bugreport.cgi/local-mathinline_h.diff?bug=340871;msg=137;att=2


Ideally, glibc should provide one (and one only) definition of __THROW
and __NTH, which all the other headers can include.  The current
situation is that __THROW and __NTH can randomly break, because you
can't be sure which definition got defined first.  As a result, this
brokenness really needs cleaning up.


Regards,
Roger

-- 
  .''`.  Roger Leigh
 : :' :  Debian GNU/Linux             http://people.debian.org/~rleigh/
 `. `'   Printing on GNU/Linux?       http://gutenprint.sourceforge.net/
   `-    GPG Public Key: 0x25BFB848   Please GPG sign your mail.

Attachment: pgpFUDZTrpUrj.pgp
Description: PGP signature


Reply to: