stddef.h: add support for musl typedef macro guards

Message ID 20211126165717.9729-1-soeren@soeren-tempel.net
State Committed
Commit 85a438fc78dd12249ca854a3e5c577fefeb1a5cd
Headers
Series stddef.h: add support for musl typedef macro guards |

Commit Message

Li, Pan2 via Gcc-patches Nov. 26, 2021, 4:57 p.m. UTC
  From: Sören Tempel <soeren+git@soeren-tempel.net>

The stddef.h header checks/sets various hardcoded toolchain/os specific
macro guards to prevent redefining types such as ptrdiff_t, wchar_t, or
size_t. However, without this patch, the file does not check/set the
typedef macro guards for musl libc. This causes types such as size_t to
be defined twice for files which include both musl's stddef.h as well as
GCC's ginclude/stddef.h. This is, for example, the case for
libgo/sysinfo.c. If libgo/sysinfo.c has multiple typedefs for size_t
this confuses -fdump-go-spec and causes size_t not to be included in the
generated type definitions thereby causing a gcc-go compilation failure
on Alpine Linux Edge (which uses musl libc) with the following error:

	sysinfo.go:7765:13: error: use of undefined type '_size_t'
	 7765 | type Size_t _size_t
	      |             ^
	libcall_posix.go:49:35: error: non-integer len argument in make
	   49 |                 b := make([]byte, len)
	      |

This commit fixes this issue by ensuring that ptrdiff_t, wchar_t, and size_t
are only defined once in the pre-processed libgo/sysinfo.c file by enhancing
gcc/ginclude/stddef.h with musl-specific typedef macro guards.

gcc/ChangeLog:

	* ginclude/stddef.h (__DEFINED_ptrdiff_t): Add support for musl
	libc typedef macro guard.
	(__DEFINED_size_t): Ditto.
	(__DEFINED_wchar_t): Ditto.
---
 gcc/ginclude/stddef.h | 9 +++++++++
 1 file changed, 9 insertions(+)
  

Comments

Jeff Law Dec. 2, 2021, 4:38 p.m. UTC | #1
On 11/26/2021 9:57 AM, soeren--- via Gcc-patches wrote:
> From: Sören Tempel <soeren+git@soeren-tempel.net>
>
> The stddef.h header checks/sets various hardcoded toolchain/os specific
> macro guards to prevent redefining types such as ptrdiff_t, wchar_t, or
> size_t. However, without this patch, the file does not check/set the
> typedef macro guards for musl libc. This causes types such as size_t to
> be defined twice for files which include both musl's stddef.h as well as
> GCC's ginclude/stddef.h. This is, for example, the case for
> libgo/sysinfo.c. If libgo/sysinfo.c has multiple typedefs for size_t
> this confuses -fdump-go-spec and causes size_t not to be included in the
> generated type definitions thereby causing a gcc-go compilation failure
> on Alpine Linux Edge (which uses musl libc) with the following error:
>
> 	sysinfo.go:7765:13: error: use of undefined type '_size_t'
> 	 7765 | type Size_t _size_t
> 	      |             ^
> 	libcall_posix.go:49:35: error: non-integer len argument in make
> 	   49 |                 b := make([]byte, len)
> 	      |
>
> This commit fixes this issue by ensuring that ptrdiff_t, wchar_t, and size_t
> are only defined once in the pre-processed libgo/sysinfo.c file by enhancing
> gcc/ginclude/stddef.h with musl-specific typedef macro guards.
>
> gcc/ChangeLog:
>
> 	* ginclude/stddef.h (__DEFINED_ptrdiff_t): Add support for musl
> 	libc typedef macro guard.
> 	(__DEFINED_size_t): Ditto.
> 	(__DEFINED_wchar_t): Ditto.
So what doesn't make sense here is how both stddef.h files get 
included.  That's the core problem I think you need to resolve.

Jeff
  
Sören Tempel Dec. 3, 2021, 6:24 a.m. UTC | #2
Hi,

Jeff Law <jeffreyalaw@gmail.com> wrote:
> So what doesn't make sense here is how both stddef.h files get 
> included.  That's the core problem I think you need to resolve.

The libgo/sysinfo.c file includes stddef.h (for which the GCC version in
ginclude is used on my system) and stdlib.h which, on musl, causes an
include of /usr/include/bits/alltypes.h [1] which then defines size_t
and other types, which were already defined by GCC's stddef.h, again [2].

As such, both stddef.h files are actually not included, i.e. only the
GCC one is used. The alternative here would be to have libgo/sysinfo.c
include the stddef.h provide by the systemc libc but not sure if that is
intended here. I am personally not very familiar with the GCC codebase.

I can send you a pre-processed version of sysinfo.c if you want to
reproduce this yourself.

Greetings,
Sören

[1]: https://git.musl-libc.org/cgit/musl/tree/include/stdlib.h?id=b76f37fd5625d038141b52184956fb4b7838e9a5#n19
[2]: https://git.musl-libc.org/cgit/musl/tree/include/alltypes.h.in?id=b76f37fd5625d038141b52184956fb4b7838e9a5#n5
  
Jeff Law Dec. 14, 2021, 11:10 p.m. UTC | #3
On 12/2/2021 11:24 PM, Sören Tempel wrote:
> Hi,
>
> Jeff Law <jeffreyalaw@gmail.com> wrote:
>> So what doesn't make sense here is how both stddef.h files get
>> included.  That's the core problem I think you need to resolve.
> The libgo/sysinfo.c file includes stddef.h (for which the GCC version in
> ginclude is used on my system) and stdlib.h which, on musl, causes an
> include of /usr/include/bits/alltypes.h [1] which then defines size_t
> and other types, which were already defined by GCC's stddef.h, again [2].
>
> As such, both stddef.h files are actually not included, i.e. only the
> GCC one is used. The alternative here would be to have libgo/sysinfo.c
> include the stddef.h provide by the systemc libc but not sure if that is
> intended here. I am personally not very familiar with the GCC codebase.
>
> I can send you a pre-processed version of sysinfo.c if you want to
> reproduce this yourself.
Thanks.  What was confusing was the original explanation indicated it 
was two different versions of stddef.h being included, when in fact it 
was stddef.h (from gcc) and stdlib.h (from musl) getting included that 
caused the problem.

I replaced the instance of stddef.h with stdlib.h in the original 
explanation and included that in the commit log when I pushed this fix 
to the trunk.

Thanks for your patience,
Jeff
  

Patch

diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
index 9d67eac4947..770a6d321b3 100644
--- a/gcc/ginclude/stddef.h
+++ b/gcc/ginclude/stddef.h
@@ -128,6 +128,7 @@  _TYPE_wchar_t;
 #ifndef ___int_ptrdiff_t_h
 #ifndef _GCC_PTRDIFF_T
 #ifndef _PTRDIFF_T_DECLARED /* DragonFly */
+#ifndef __DEFINED_ptrdiff_t /* musl libc */
 #define _PTRDIFF_T
 #define _T_PTRDIFF_
 #define _T_PTRDIFF
@@ -137,10 +138,12 @@  _TYPE_wchar_t;
 #define ___int_ptrdiff_t_h
 #define _GCC_PTRDIFF_T
 #define _PTRDIFF_T_DECLARED
+#define __DEFINED_ptrdiff_t
 #ifndef __PTRDIFF_TYPE__
 #define __PTRDIFF_TYPE__ long int
 #endif
 typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#endif /* __DEFINED_ptrdiff_t */
 #endif /* _PTRDIFF_T_DECLARED */
 #endif /* _GCC_PTRDIFF_T */
 #endif /* ___int_ptrdiff_t_h */
@@ -174,6 +177,7 @@  typedef __PTRDIFF_TYPE__ ptrdiff_t;
 #ifndef _SIZE_T_DEFINED
 #ifndef _BSD_SIZE_T_DEFINED_	/* Darwin */
 #ifndef _SIZE_T_DECLARED	/* FreeBSD 5 */
+#ifndef __DEFINED_size_t	/* musl libc */
 #ifndef ___int_size_t_h
 #ifndef _GCC_SIZE_T
 #ifndef _SIZET_
@@ -191,6 +195,7 @@  typedef __PTRDIFF_TYPE__ ptrdiff_t;
 #define _SIZE_T_DEFINED
 #define _BSD_SIZE_T_DEFINED_	/* Darwin */
 #define _SIZE_T_DECLARED	/* FreeBSD 5 */
+#define __DEFINED_size_t	/* musl libc */
 #define ___int_size_t_h
 #define _GCC_SIZE_T
 #define _SIZET_
@@ -215,6 +220,7 @@  typedef long ssize_t;
 #endif /* _SIZET_ */
 #endif /* _GCC_SIZE_T */
 #endif /* ___int_size_t_h */
+#endif /* __DEFINED_size_t */
 #endif /* _SIZE_T_DECLARED */
 #endif /* _BSD_SIZE_T_DEFINED_ */
 #endif /* _SIZE_T_DEFINED */
@@ -251,6 +257,7 @@  typedef long ssize_t;
 #ifndef _BSD_WCHAR_T_DEFINED_    /* Darwin */
 #ifndef _BSD_RUNE_T_DEFINED_	/* Darwin */
 #ifndef _WCHAR_T_DECLARED /* FreeBSD 5 */
+#ifndef __DEFINED_wchar_t /* musl libc */
 #ifndef _WCHAR_T_DEFINED_
 #ifndef _WCHAR_T_DEFINED
 #ifndef _WCHAR_T_H
@@ -272,6 +279,7 @@  typedef long ssize_t;
 #define __INT_WCHAR_T_H
 #define _GCC_WCHAR_T
 #define _WCHAR_T_DECLARED
+#define __DEFINED_wchar_t
 
 /* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_
    instead of _WCHAR_T_, and _BSD_RUNE_T_ (which, unlike the other
@@ -326,6 +334,7 @@  typedef __WCHAR_TYPE__ wchar_t;
 #endif
 #endif
 #endif
+#endif /* __DEFINED_wchar_t */
 #endif /* _WCHAR_T_DECLARED */
 #endif /* _BSD_RUNE_T_DEFINED_ */
 #endif