This is an archive of the discontinued LLVM Phabricator instance.

[clang][Headers] Do not define varargs macros for __need___va_list
ClosedPublic

Authored by zatrazz on Nov 2 2022, 10:04 AM.

Details

Summary

The glibc uses the define to avoid namespace polution on headers
that requires variadic argument, where the inclusion of stdarg.h is
required to obtain the va_list definition.

For such cases only __gnuc_va_list is required.

Diff Detail

Event Timeline

zatrazz created this revision.Nov 2 2022, 10:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 2 2022, 10:04 AM
zatrazz requested review of this revision.Nov 2 2022, 10:04 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptNov 2 2022, 10:04 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript
efriedma added inline comments.
clang/lib/Headers/stdarg.h
19

Maybe the following is a little more readable?

#ifndef __STDARG_H

#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST 1
typedef __builtin_va_list __gnuc_va_list;
#endif

#ifdef __need___va_list
#undef __need___va_list
#else
#define __STDARG_H
[...]
MaskRay added inline comments.Nov 3 2022, 6:04 PM
clang/lib/Headers/stdarg.h
15

To match gcc stdarg.h, #define __GNUC_VA_LIST

MaskRay requested changes to this revision.Nov 5 2022, 1:24 PM

LGTM, but changes are needed.

This revision now requires changes to proceed.Nov 5 2022, 1:24 PM
zatrazz marked 2 inline comments as done.Nov 8 2022, 9:21 AM
zatrazz added inline comments.
clang/lib/Headers/stdarg.h
15

Ack.

19

Ack.

zatrazz updated this revision to Diff 474028.Nov 8 2022, 9:21 AM
zatrazz marked 2 inline comments as done.

Update review based on reviewers comments.

MaskRay accepted this revision.Nov 8 2022, 9:24 AM

LGTM.

This revision is now accepted and ready to land.Nov 8 2022, 9:24 AM
uabelho added a subscriber: uabelho.Nov 9 2022, 6:09 AM
enh added a subscriber: enh.Jan 20 2023, 11:25 AM

is there a corresponding glibc change so that va_list is exported for _POSIX_SOURCE cases? see https://android-review.git.corp.google.com/c/platform/bionic/+/2397313 where i'm having to disable some bionic testing against glibc because the glibc (2.17!) <wchar.h> now no longer exports va_list. i did look for a ToT glibc patch to backport (until we've _actually_ switched from glibc to musl for the host), but couldn't obviously find it?

https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/wchar.h.html says:
"""
The <wchar.h> header shall define the following types:
...
va_list
[CX] As described in <stdarg.h>.
"""
which is why i think our "<wchar.h> exports va_list" test is correct. (Android doesn't support an "ISO only" mode --- you're effectively always in _POSIX_SOURCE mode, so we build the test against glibc with _POSIX_SOURCE defined.)

is there a corresponding glibc change so that va_list is exported for _POSIX_SOURCE cases? see https://android-review.git.corp.google.com/c/platform/bionic/+/2397313 where i'm having to disable some bionic testing against glibc because the glibc (2.17!) <wchar.h> now no longer exports va_list. i did look for a ToT glibc patch to backport (until we've _actually_ switched from glibc to musl for the host), but couldn't obviously find it?

https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/wchar.h.html says:
"""
The <wchar.h> header shall define the following types:
...
va_list
[CX] As described in <stdarg.h>.
"""
which is why i think our "<wchar.h> exports va_list" test is correct. (Android doesn't support an "ISO only" mode --- you're effectively always in _POSIX_SOURCE mode, so we build the test against glibc with _POSIX_SOURCE defined.)

I think I have caught this because your standard conformance tests checks for gnuc_va_list
on wchar.h, wich is always defined on on GCC (git log shows it was changed to fix XPG7
tests, but I am not sure exactly why the author has changed the va_list to
gnuc_va_list).

And it seems that glibc seems broken also using GCC stdarg.h if I fix the test to check for
va_list instead. I will take a look at this.

enh added a comment.Jan 20 2023, 12:13 PM

I think I have caught this because your standard conformance tests checks for gnuc_va_list
on wchar.h, wich is always defined on on GCC (git log shows it was changed to fix XPG7
tests, but I am not sure exactly why the author has changed the va_list to
gnuc_va_list).

bionic's tests check for va_list, because that's what POSIX says will be visible. ISO C doesn't say that, so i think the _intention_ for glibc -- musl seems to do this correctly -- is to say "if we're only compiling C source, you don't get va_list, but if we're compiling POSIX source, you do get va_list". so i think this __gnuc_va_list thing is their workaround to still export the _functions_ without exporting the _type_ for ISO C?

here's the bionic *POSIX* test: https://cs.android.com/android/platform/superproject/+/master:bionic/tests/headers/posix/wchar_h.c;l=38 (but note that you'll have to look at the corresponding Android.bp file to see us define _POSIX_SOURCE.) note that our tests pass against _bionic_ (and, i think, musl). it's just old-glibc-with-new-llvm they fail against.

And it seems that glibc seems broken also using GCC stdarg.h if I fix the test to check for
va_list instead. I will take a look at this.

thanks!

I think I have caught this because your standard conformance tests checks for gnuc_va_list
on wchar.h, wich is always defined on on GCC (git log shows it was changed to fix XPG7
tests, but I am not sure exactly why the author has changed the va_list to
gnuc_va_list).

bionic's tests check for va_list, because that's what POSIX says will be visible. ISO C doesn't say that, so i think the _intention_ for glibc -- musl seems to do this correctly -- is to say "if we're only compiling C source, you don't get va_list, but if we're compiling POSIX source, you do get va_list". so i think this __gnuc_va_list thing is their workaround to still export the _functions_ without exporting the _type_ for ISO C?

Indeed the gnuc_va_list is used when building for c99/c11, since va_list should not be defined in such cases. It seems also that glibc stdio.h does handle it by defining gnuc_va_list to va_list if POSIX2001 or POSIX2008 is used (-D_XOPEN_SOURCE=600 or -D_XOPEN_SOURCE=700), so I think we should do the same for wchar.h

here's the bionic *POSIX* test: https://cs.android.com/android/platform/superproject/+/master:bionic/tests/headers/posix/wchar_h.c;l=38 (but note that you'll have to look at the corresponding Android.bp file to see us define _POSIX_SOURCE.) note that our tests pass against _bionic_ (and, i think, musl). it's just old-glibc-with-new-llvm they fail against.

And it seems that glibc seems broken also using GCC stdarg.h if I fix the test to check for
va_list instead. I will take a look at this.

thanks!

Could you check if this fixes your issue? I am not sure if if applies cleans to the ancient glibc 2.17 you are using:

diff --git a/conform/data/wchar.h-data b/conform/data/wchar.h-data
index e414651a33..582a99c00b 100644
--- a/conform/data/wchar.h-data
+++ b/conform/data/wchar.h-data
@@ -15,6 +15,9 @@ type size_t
 type locale_t
 # endif
 tag {struct tm}
+#if !defined ISO && !defined ISO99 && !defined ISO11 && !defined POSIX && !defined UNIX98
+type va_list
+#endif

 function wint_t btowc (int)
 function int fwprintf (FILE*, const wchar_t*, ...)
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index 69e920b8c2..ca145bb8d2 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -37,6 +37,17 @@
 #define __need___va_list
 #include <stdarg.h>

+#if defined __USE_XOPEN2K || defined __USE_XOPEN2K8
+# ifdef __GNUC__
+#  ifndef _VA_LIST_DEFINED
+typedef __gnuc_va_list va_list;
+#   define _VA_LIST_DEFINED
+#  endif
+# else
+#  include <stdarg.h>
+# endif
+#endif
+
 #include <bits/wchar.h>
 #include <bits/types/wint_t.h>
 #include <bits/types/mbstate_t.h>

In any case, I will open a bug report on glibc fix on our side.

enh added a comment.Jan 27 2023, 7:39 AM

Could you check if this fixes your issue?

yes, thanks... the person doing the llvm update tried it and reports that it works.

here's the patch against our old copy of glibc: https://android-review.googlesource.com/c/platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/+/2403274