svn commit: r280700 - head/sys/sys

Bruce Evans brde at optusnet.com.au
Fri Mar 27 00:40:32 UTC 2015


On Thu, 26 Mar 2015, Pedro F. Giffuni wrote:

> Log:
>  Introduce some allocation function attributes.
>
>  Bring support for two gcc function attributes that are likely to be used
>  in our system headers:
> ...
>  The __alloc_size attribute required some workarounds for lint(1).
>  Both attributes are supported by clang.

It is broken for all non-C99 compilers, the same as __nonull().  lint
may be one of these, depending on implementation details and on how
well it supports non-C99 mode (I think it knows almost nothing of
C99, but uses cpp and is not careful to kill C99 features).

FreeBSD even has a non-C90 compiler (modulo bugs).  It is named c89. 
Even the compilers that implement most of C99 have a C90 mode.  This
is specifed by the compiler flag -std=c89 or -std=gnu89.

The follow breakage happens for ... and/or __VA_ARGS__:

- c89 -E on ... alone
     q.c:1:13: warning: variadic macros are a C99 feature [-Wvariadic-macros]
     #define foo(...)
                 ^
     foo(1, 2, 3) then expands to nothing.

- c89 -E on ... and __VA_ARGS__:
     Same warning.  __VA_ARGS__ then expands as in C99.

- clang -E -std=c89:
     Same as in C99.  -std=c89 is not very std.

- clang -E -std=c89 -pedantic
     Same as for c89.  c89 uses -pedantic so as to be more std.

- gcc295 -E -std=c89:
     z.c:1: warning: invalid character in macro parameter name
     z.c:1: badly punctuated parameter list in `#define'

     foo(1, 2, 3) then expands to nothing for the empty macro
     and __VA_ARGS__ expands as in C99.  -std=c89 actually works
     for gcc295

- gcc34 -E -std=c89 [-pedantic],
- gcc42 -E -std=c89 [-pedantic]:
     Like clang, but with a better error message:

     q.c:1:13: warning: anonymous variadic macros were introduced in C99

- gcc48 -E -std=c89 [-pedantic]:
     Like clang, except the error message has not regressed so far (it
     is verbose as in clang, but missing colorization).

- TenDRA 5.0.0 (an actual C90 compiler.  I sometimes use this for its
   better diagnostics.  Though very verbose, the references to C90
   section numbers are useful):

     "z4.c", line 1: Error:
       [ISO C90 6.8.3]: Badly punctuated parameters for macro 'foo'.

     "z4.c", line 3: Error:
       [ISO C90 6.8.3]: Macro 'foo' applied with 3 arguments, not 0.

    TenDRA has its own headers which are very clean, but to use it
    even to do syntax checks, you have to use the system headers
    (tcc -Ysystem).

> Modified: head/sys/sys/cdefs.h
> ==============================================================================
> --- head/sys/sys/cdefs.h	Thu Mar 26 15:54:54 2015	(r280699)
> +++ head/sys/sys/cdefs.h	Thu Mar 26 16:00:35 2015	(r280700)
> @@ -209,6 +212,7 @@
> #define	__unused
> #define	__packed
> #define	__aligned(x)
> +#define	__alloc_size(...)
> #define	__section(x)
> #define	__weak
> #else

The first bug is here.  This is for lint.  This is supposed to give a
null macro, but actually gives a syntax error except for C99 compilers.

> @@ -233,6 +237,11 @@
> #define	__aligned(x)	__attribute__((__aligned__(x)))
> #define	__section(x)	__attribute__((__section__(x)))
> #endif
> +#if __has_attribute(alloc_size) || __GNUC_PREREQ__(4, 3)
> +#define	__alloc_size(...)	__attribute__((alloc_size(__VA_ARGS__)))

This is broken by namespace pollution.  alloc_size is in the application
namespace.  It must be spelled with underscores like all the other
attributes in the macros.

The "..." in this is broken in c89 mode.  Passing the #if only guarantees
that the attribute is supported.  It doesn't guarantee that "..." is
supported.  The name of the attribute may be relevant here too.  We want
most the special macros to work in c89 and other strict standard modes.
Their names are spelled with underscores to make this possible.  Standard
modes turn off gcc features like asm() and even "inline".  Perhaps they
do the same for alloc_size().

> +#else
> +#define	__alloc_size(...)
> +#endif

Similarly for all hard-coded uses of "...".  This #else clause is supposed
to give compatibility for all compilers that don't support alloc_size().
But most of these compilers also don't support "...", so this almost
never works.

> @@ -363,8 +372,10 @@
>
> #if __GNUC_PREREQ__(3, 4)
> #define	__fastcall	__attribute__((__fastcall__))
> +#define	__result_use_check	__attribute__((__warn_unused_result__))
> #else
> #define	__fastcall
> +#define	__result_use_check
> #endif

Changes like this are correct since they don't depend on compiler-[option]-
dependent syntactic features.

Bruce


More information about the svn-src-head mailing list