NetBSD-Bugs archive

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

lib/60618: <sys/stddef.h> breaks LLVM and GCC builds



>Number:         60618
>Category:       lib
>Synopsis:       <sys/stddef.h> breaks LLVM and GCC builds
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Aug 18 08:00:00 +0000 2026
>Originator:     Rainer Orth
>Release:        NetBSD 11.0
>Organization:
Bielefeld University, Center for Biotechnology
	<organization of PR author (multiple lines)>
>Environment:
	<The following information is extracted from your kernel. Please>
	<append output of "ldd", "ident" where relevant (multiple lines).>
System: NetBSD nbsd-amd64.gcc 11.0 NetBSD 11.0 (GENERIC) #0: Thu Jul 30 15:23:12 UTC 2026 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
The introduction of <sys/stddef.h> in NetBSD 11.0, with <stddef.h>
replaced by a symlink, breaks the builds of both LLVM and GCC.  This
happens because the different definitions of max_align_t in
<sys/stddef.h> and the compiler-supplied versions of <stddef.h> can now
conflict, causing compilation failures.
>How-To-Repeat:
The original testcase, extracted from LLVM
compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp
(or its GCC libsanitizer equivalent) is like

$ cat stddef-kmemuser.c
#define _KMEMUSER
#include <sys/sysctl.h>
#include <stddef.h>

Compiliation with either clang (both the /usr/pkg/bin one and a
self-compiled clang-24) fails:

$ clang -c stddef-kmemuser.c
In file included from stddef-kmemuser.c:2:
In file included from /usr/include/sys/sysctl.h:60:
In file included from /usr/pkg/lib/clang/21/include/stddef.h:123:
/usr/pkg/lib/clang/21/include/__stddef_max_align_t.h:24:3: error: 
      typedef redefinition with different types ('struct max_align_t' vs
      'union max_align_t')
   24 | } max_align_t;
      |   ^
/usr/include/sys/stddef.h:105:3: note: previous definition
      is here
  105 | } max_align_t;
      |   ^
1 error generated.

GCC trunk is similar:

$ gcc -c stddef.c
In file included from stddef.c:2:
/usr/include/sys/stddef.h:105:3: error: conflicting types for 'max_align_t'; have 'union <anonymous>'
  105 | } max_align_t;
      |   ^~~~~~~~~~~
In file included from stddef.c:1:
/vol/gcc-17/lib/gcc/amd64-pc-netbsd10.1/17.0.0/include/stddef.h:451:3: note: previous declaration of 'max_align_t' with type 'max_align_t'
  451 | } max_align_t;
      |   ^~~~~~~~~~~

This doesn't happen with the bundled gcc 12.5.0 because, unlike
upstream, that version doesn't install the gcc-supplied stddef.h.

Both GCC stddef.h (from gcc/ginclude/stdef.h in the source tree) and
LLVM stddef.h (from clang/lib/Headers/stddef.h in the source tree)
exist to always provide a fully standard-conformant version of
<stddef.h> even if the system headers violate the standard in some
way, overriding the system header.

AFAICS that's not necessary on NetBSD 11.0, but is done
unconditionally by both compilers.

In both cases the compiler stddef.h definition of max_align_t differs
from the system header: the compiler headers use

typedef struct { ... } max_align_t;

while <sys/stddef.h> uses

typedef union { ... } max_align_t;

Both definitions comply with the C standard and have been like this
forever AFAICS.

However, when both defitions are present in the same compilation, the
errors above happen.  In the original example, this happens because with
_KMEMUSER defined <sys/sysctl.h> indirectly includes <machine/pcb.h>.
That one, along with <sys/container_of.h>, include <sys/stdef.h> instead
of <stddef.h>, so both the compiler and system versions of <stddef.h>
are present.

While this is the (admittedly somewhat contrieved) real-live example,
the same error obvious occurs with the trivial

$ cat stddef.c
#include <stddef.h>
#include <sys/stddef.h>

>Fix:
For the original testcase, I've worked around this like so:

#include <stddef.h>
// Inhibit the inclusion of the NetBSD 11 <sys/stddef.h> which clashes with
// Clang <stddef.h> max_align_t.
#define _SYS_STDDEF_H_

before including <sys/sysctl.h>.

A real solution would consist of:

* Change <machine/pcb.h> and <sys/container_of.h> to just include
  <stddef.h> like all other system headers.

* Maybe undo the introduction of <sys/stddef.h> and move the header
  back to <stddef.h> so no conflict is possible.

* If that's not going to happen, GCC'S stddef.h would need to account
  for the changed multiple-inclusion guard (_STDDEF_H_ ->
  _SYS_STDDEF_H_) to avoid the conflict on its own.

  Clang stddef.h would still be left out in the cold, though.

IMO there needs to be some solution that works with unmodified upstream
GCC and LLVM, not something that's just done for the bundled versions.
This allows for GCC and LLVM developers to build the code without having
to hunt down NetBSD-private patches.

>Unformatted:
 	<Please check that the above is correct for the bug being reported,>
 	<and append source date of snapshot, if applicable (one line).>



Home | Main Index | Thread Index | Old Index