https://gcc.gnu.org/g:2a6816883107ee4a4aabb43763ce079512f3f0f8

commit r15-7088-g2a6816883107ee4a4aabb43763ce079512f3f0f8
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Jan 21 09:14:01 2025 +0100

    c, c++: Return 1 for __has_builtin(__builtin_va_arg) and 
__has_builtin(__builtin_c23_va_start)
    
    The Linux kernel uses its own copy of stdarg.h.
    Now, before GCC 15, our stdarg.h had
        #if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
        #define va_start(v, ...)        __builtin_va_start(v, 0)
        #else
        #define va_start(v,l)   __builtin_va_start(v,l)
        #endif
    va_start definition but GCC 15 has:
        #if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
        #define va_start(...) __builtin_c23_va_start(__VA_ARGS__)
        #else
        #define va_start(v,l)   __builtin_va_start(v,l)
        #endif
    
    I wanted to suggest to the kernel people during their porting to C23
    that they'd better use C23 compatible va_start macro definition,
    but to make it portable, I think they really want something like
        #if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
        #define va_start(v, ...)        __builtin_va_start(v, 0)
        #ifdef __has_builtin
        #if __has_builtin(__builtin_c23_va_start)
        #undef va_start
        #define va_start(...) __builtin_c23_va_start(__VA_ARGS__)
        #endif
        #else
        #define va_start(v,l)   __builtin_va_start(v,l)
        #endif
    or so (or with >= 202311L), as GCC 13-14 and clang don't support
    __builtin_c23_va_start (yet?) and one gets better user experience with
    that.
    
    Except it seems __has_builtin(__builtin_c23_va_start) doesn't actually work,
    it works for most of the stdarg.h __builtin_va_*, doesn't work for
    __builtin_va_arg (neither C nor C++) and didn't work for
    __builtin_c23_va_start if it was available.
    
    The following patch wires __has_builtin for those.
    
    2025-01-21  Jakub Jelinek  <ja...@redhat.com>
    
    gcc/c/
            * c-decl.cc (names_builtin_p): Return 1 for RID_C23_VA_START and
            RID_VA_ARG.
    gcc/cp/
            * cp-objcp-common.cc (names_builtin_p): Return 1 for RID_VA_ARG.
    gcc/testsuite/
            * c-c++-common/cpp/has-builtin-4.c: New test.

Diff:
---
 gcc/c/c-decl.cc                                |  2 ++
 gcc/cp/cp-objcp-common.cc                      |  1 +
 gcc/testsuite/c-c++-common/cpp/has-builtin-4.c | 16 ++++++++++++++++
 3 files changed, 19 insertions(+)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 314b118b7c8b..68d331b22503 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -11804,6 +11804,8 @@ names_builtin_p (const char *name)
     case RID_CHOOSE_EXPR:
     case RID_OFFSETOF:
     case RID_TYPES_COMPATIBLE_P:
+    case RID_C23_VA_START:
+    case RID_VA_ARG:
       return 1;
     default:
       break;
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index fc6c790ce113..8336d0bb8f7c 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -587,6 +587,7 @@ names_builtin_p (const char *name)
     case RID_BUILTIN_ASSOC_BARRIER:
     case RID_BUILTIN_BIT_CAST:
     case RID_OFFSETOF:
+    case RID_VA_ARG:
       return 1;
     case RID_BUILTIN_OPERATOR_NEW:
     case RID_BUILTIN_OPERATOR_DELETE:
diff --git a/gcc/testsuite/c-c++-common/cpp/has-builtin-4.c 
b/gcc/testsuite/c-c++-common/cpp/has-builtin-4.c
new file mode 100644
index 000000000000..65d2b188d9aa
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/has-builtin-4.c
@@ -0,0 +1,16 @@
+/* { dg-do preprocess } */
+
+#if __has_builtin (__builtin_va_start) != 1
+#error "No __builtin_va_start"
+#endif
+#if __has_builtin (__builtin_va_end) != 1
+#error "No __builtin_va_end"
+#endif
+#if __has_builtin (__builtin_va_arg) != 1
+#error "no __builtin_va_arg"
+#endif
+#if __STDC_VERSION__ >= 202311L
+#if __has_builtin (__builtin_c23_va_start) != 1
+#error "no __builtin_c23_va_start"
+#endif
+#endif

Reply via email to