Bug 158418 - [includes] /usr/include librarys broken by unnecessary extra macro indirection.
Summary: [includes] /usr/include librarys broken by unnecessary extra macro indirection.
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 8.2-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-29 08:10 UTC by Alan Larson
Modified: 2017-12-31 22:32 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alan Larson 2011-06-29 08:10:05 UTC
	
  The macro  __aligned(x)  is used several places in files in /usr/include, but is only
defined if using a sufficiently new version of GCC, or an Intel compiler.
The definitions are inside an  #if __GNUC_PREREQ__(2, 7)  and  #if defined(__INTEL_COMPILER)

  This breaks things when compiled with PCC or TCC.  ( http://pcc.ludd.ltu.se/jira/browse/PCC-18 )

Fix: 

Two likely fixes come to mind:

    1.  Don't use these macro shortcuts, use the __attribute__ form directly.
        Many of the files in /usr/include do this, so fixing the remaining ones
        would simplify things.  It should only take a few minutes to fix them.
        There are still lots of places using the __attribute__ form, so this
        is a proven safe and reasonable solution.

    2.  If you absolutely must include macros for this, define the macro all the
        time.
        But seriously, you should take solution #1.
How-To-Repeat: 	
  Attempt to compile something that has an #include <signal.h> with TCC (or presumably, PCC).

  Inspection of the code indicates that the same problem is true for __packed  .

  Other values are also redefined in those same conditionals, and they probably have
the same problems.
Comment 1 Bruce Evans freebsd_committer freebsd_triage 2011-06-30 00:55:47 UTC
On Tue, 28 Jun 2011, Alan Larson wrote:

>> Description:
>
>  The macro  __aligned(x)  is used several places in files in /usr/include, but is only
> defined if using a sufficiently new version of GCC, or an Intel compiler.
> The definitions are inside an  #if __GNUC_PREREQ__(2, 7)  and  #if defined(__INTEL_COMPILER)
>
>  This breaks things when compiled with PCC or TCC.  ( http://pcc.ludd.ltu.se/jira/browse/PCC-18 )

Unfortunately, breaking is the correct behaviour since the ABI depends on
the struct layout, so only compilers that support packing and alignment
can work.  Structs should be layed out more carefully so that packing and
alignment directives are never needed, but this is sometimes impossible.

>> How-To-Repeat:
>
>  Attempt to compile something that has an #include <signal.h> with TCC (or presumably, PCC).
>
>  Inspection of the code indicates that the same problem is true for __packed  .
>
>  Other values are also redefined in those same conditionals, and they probably have
> the same problems.

The problem outside the kernel doesn't seem to affect much more than
<signal.h>, though relatively recently it has spread to some networking
headers, especially ipv6 ones.

>> Fix:
>
>
>  Two likely fixes come to mind:
>
>    1.  Don't use these macro shortcuts, use the __attribute__ form directly.
>        Many of the files in /usr/include do this, so fixing the remaining ones
>        would simplify things.  It should only take a few minutes to fix them.
>        There are still lots of places using the __attribute__ form, so this
>        is a proven safe and reasonable solution.

That would enlarge the bug.  Doing it for an old version of tcc -Ysystem
gives:

% "/usr/include/machine/signal.h", line 122: Error:
%   [Syntax]: Parse error before '__attribute__'.
%   [Syntax]: Can't recover from this error.

since old versions of tcc don't support __attribute__ any more than they
support the newer types of attributes like the one for alignment.

>    2.  If you absolutely must include macros for this, define the macro all the
>        time.
>        But seriously, you should take solution #1.

The macros are not just shortcuts, but exist primarily to avoid hard-coding
gccisms like __attribute__ in lots of places.

Bruce
Comment 2 Alan Larson 2011-07-01 01:14:04 UTC
  Thanks for your reply.  Perhaps I need to clarify a few details.


> On Tue, 28 Jun 2011, Alan Larson wrote:
>
> >> Description:
> >
> >  The macro  __aligned(x)  is used several places in files in /usr/include, but is only
> > defined if using a sufficiently new version of GCC, or an Intel compiler.
> > The definitions are inside an  #if __GNUC_PREREQ__(2, 7)  and  #if defined(__INTEL_COMPILER)
> >
> >  This breaks things when compiled with PCC or TCC.  ( http://pcc.ludd.ltu.se/jira/browse/PCC-18 )
>
> Unfortunately, breaking is the correct behaviour since the ABI depends on
> the struct layout, so only compilers that support packing and alignment
> can work.  Structs should be layed out more carefully so that packing and
> alignment directives are never needed, but this is sometimes impossible.


  Fortunately, both PCC and TCC do support packing and alignment.


> >> How-To-Repeat:
> >
> >  Attempt to compile something that has an #include <signal.h> with TCC (or presumably, PCC).
> >
> >  Inspection of the code indicates that the same problem is true for __packed  .
> >
> >  Other values are also redefined in those same conditionals, and they probably have
> > the same problems.
>
> The problem outside the kernel doesn't seem to affect much more than
> <signal.h>, though relatively recently it has spread to some networking
> headers, especially ipv6 ones.


> >  Two likely fixes come to mind:
> >
> >    1.  Don't use these macro shortcuts, use the __attribute__ form directly.
> >        Many of the files in /usr/include do this, so fixing the remaining ones
> >        would simplify things.  It should only take a few minutes to fix them.
> >        There are still lots of places using the __attribute__ form, so this
> >        is a proven safe and reasonable solution.
>
> That would enlarge the bug.  Doing it for an old version of tcc -Ysystem
> gives:
>
> % "/usr/include/machine/signal.h", line 122: Error:
> %   [Syntax]: Parse error before '__attribute__'.
> %   [Syntax]: Can't recover from this error.
>
> since old versions of tcc don't support __attribute__ any more than they
> support the newer types of attributes like the one for alignment.


  This is actually not a problem, or at least not *the* problem.  tcc supports
these __attribute__ options, and in the many cases where they are used without
the conditional definitions, is happy with them.

  I checked with the November 2004 version 0.9.22 of tcc.



> The macros are not just shortcuts, but exist primarily to avoid hard-coding
> gccisms like __attribute__ in lots of places.

  Well, it seemed easier than including the macos for every possible compiler, but
if you prefer, please add this to sys/cdefs.h


#ifdef __TINYC__
#define	__dead2		__attribute__((__noreturn__))
#define	__pure2		__attribute__((__const__))
#define	__unused	__attribute__((__unused__))
#define	__used		__attribute__((__used__))
#define	__packed	__attribute__((__packed__))
#define	__aligned(x)	__attribute__((__aligned__(x)))
#define	__section(x)	__attribute__((__section__(x)))
#endif


  Actually, it may make more sense to just define them unless you know the compiler cannot
handle them, and it would probably be a shorter .h file, too.


	Alan

p.s. is there are reason that the intel compiler version says #define<space>__blah
while the GCC one says #define<tab>_blah ?  As you can see, I used the tab version
because I know that worked with TINYC.
Comment 3 Bruce Evans freebsd_committer freebsd_triage 2011-07-01 08:01:19 UTC
On Thu, 30 Jun 2011, Alan Larson wrote:

>  Thanks for your reply.  Perhaps I need to clarify a few details.
>
>> On Tue, 28 Jun 2011, Alan Larson wrote:
>>
>>>> Description:
>>>
>>>  The macro  __aligned(x)  is used several places in files in /usr/include, but is only
>>> defined if using a sufficiently new version of GCC, or an Intel compiler.
>>> The definitions are inside an  #if __GNUC_PREREQ__(2, 7)  and  #if defined(__INTEL_COMPILER)
>>>
>>>  This breaks things when compiled with PCC or TCC.  ( http://pcc.ludd.ltu.se/jira/browse/PCC-18 )
> ...
>>>  Two likely fixes come to mind:
>>>
>>>    1.  Don't use these macro shortcuts, use the __attribute__ form directly.
>>>        Many of the files in /usr/include do this, so fixing the remaining ones
>>>        would simplify things.  It should only take a few minutes to fix them.
>>>        There are still lots of places using the __attribute__ form, so this
>>>        is a proven safe and reasonable solution.
>>
>> That would enlarge the bug.  Doing it for an old version of tcc -Ysystem
>> gives:
>>
>> % "/usr/include/machine/signal.h", line 122: Error:
>> %   [Syntax]: Parse error before '__attribute__'.
>> %   [Syntax]: Can't recover from this error.
>>
>> since old versions of tcc don't support __attribute__ any more than they
>> support the newer types of attributes like the one for alignment.
>
>  This is actually not a problem, or at least not *the* problem.  tcc supports
> these __attribute__ options, and in the many cases where they are used without
> the conditional definitions, is happy with them.
>
>  I checked with the November 2004 version 0.9.22 of tcc.

Perhaps a different tcc.  I checked with an old version of TenDRA which is
actually less old than the above:
(tcc: Version: 4.0, Machine: freebsd-*-80x86, Release: TenDRA-5.0.0-dev)
but which is tool old to support much more than C90 (and 1990's (?) C++).

>> The macros are not just shortcuts, but exist primarily to avoid hard-coding
>> gccisms like __attribute__ in lots of places.
>
>  Well, it seemed easier than including the macos for every possible compiler, but
> if you prefer, please add this to sys/cdefs.h
>
> #ifdef __TINYC__
> #define	__dead2		__attribute__((__noreturn__))
> #define	__pure2		__attribute__((__const__))
> #define	__unused	__attribute__((__unused__))
> #define	__used		__attribute__((__used__))
> #define	__packed	__attribute__((__packed__))
> #define	__aligned(x)	__attribute__((__aligned__(x)))
> #define	__section(x)	__attribute__((__section__(x)))
> #endif

You need to get this added undef suitable ifdefs in sys/cdefs.h.  __TINYC__
might be OK, but does it need a version ifdef?  Perhaps it should be
organized differently, but that should be left to the committer.

>  Actually, it may make more sense to just define them unless you know the compiler cannot
> handle them, and it would probably be a shorter .h file, too.

That would be fail-unsafe.

> p.s. is there are reason that the intel compiler version says #define<space>__blah
> while the GCC one says #define<tab>_blah ?  As you can see, I used the tab version
> because I know that worked with TINYC.

It is because the committer of the Intel compiler version didn't follow
the style of the rest of the file :-(.  The organization of the intel
compiler ifdefs isn't very good either.  The __INTEL_COMPILER section
for most attributes just duplicates the __GNUC_PREREQ(2, 7) for these
attributes, except for adding the style bug.  It could have just
expanded the ifdef's conditional.  The above __TINYC__ ifdef could do
the same -- just add " || __TINYC__" to the ifdef conditional.  But
this only works well if there is a large group of macros that are all
supported by most compilers of interest.  New and old features like
attributes will in general require different version-dependent ifdefs,
depending on when the compilers introduced them.  This only matters
much at the time when the features are introduced.  I think half of
the attributes under the __GNUC_PREREQ(2, 7) attributes ifdef weren't
actually available until gcc-3 (especially __used), but the bugs weren't
noticed because the ifdef wasn't added until long after the features
became standard, and no one cares now since it is hard to even find
any gcc-2.7's to test what it didn't have.  Ifdefs for older features
are more accurate but could be deleted without much loss now for the
same reason.

The second round of Intel compiler ifdefs also brought another style of
ifdefs in which every single feature has its own feature test macro.
E.g., there is __GNUCLIKE___TYPEOF for gcc __typeof(), and
__CC_SUPPORTS_INLINE for Standard C99 inline.  With macros like these,
users of foocc could possibly enable the definitions using the features
by #defining the macros in their source code if the system doesn't.
But this style of ifdefs is not used for most attributes, and is only
honored in a few system header files (mainly i386 ones, since
__INTEL_COMPILER only works for i386), and it seems to give an even
larger ifdef tangle when used.

Note than the Intel compiler support is rarely used and incompletely
maintained.  Replacing it by Other compiler support for a compiler
that is used would be could.  At least if it doesn't enlarge the
ifdef tangle.  Now the alternative compiler is usually clang, but
clang's compatibility with gcc is too good for it to need many ifdefs.

Bruce
Comment 4 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:00:09 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped