Subject: Re: [PATCH] build: tolerate use of _Generic from glibc 2.43 with Clang

From: Junio C Hamano <[email-masked]>
Date: Mon, 11 May 2026 14:20:09 +0900

Junio C Hamano <[email-masked]> writes:

> Wouldn't the approach you took on the meson side to pass
> "-Wno-c11-extensions" be yet another alternative?

In other words, I would imagine something like this patch that uses
the same strategy on both sides may be easier to reason about.

----- >8 -----
From: Patrick Steinhardt <[email-masked]>
Subject: [PATCH] build: tolerate use of _Generic from glibc 2.43 with Clang

When building with `make DEVELOPER=1` we explicitly pass "-std=gnu99" to
the compiler so that we don't start leaning on features exposed by more
recent versions of the C standard. Unfortunately though, glibc 2.43
started to use type-generic expressions. This works alright with GCC,
but when compiling with Clang this leads to errors:

  $ make DEVELOPER=1 CC=clang
  CC daemon.o
  In file included from daemon.c:3:
  ./git-compat-util.h:344:11: error: '_Generic' is a C11 extension [-Werror,-Wc11-extensions]
    344 |         return !!strchr(path, '/');
        |                  ^
  /usr/include/string.h:265:3: note: expanded from macro 'strchr'
    265 |   __glibc_const_generic (S, const char *, strchr (S, C))
        |   ^
  /usr/include/x86_64-linux-gnu/sys/cdefs.h:838:3: note: expanded from macro '__glibc_const_generic'
    838 |   _Generic (0 ? (PTR) : (void *) 1,                     \
        |   ^

In theory, the `__glibc_const_generic` macro does have feature gating:

  #if !defined __cplusplus \
      && (__GNUC_PREREQ (4, 9) \
          || __glibc_has_extension (c_generic_selections) \
          || (!defined __GNUC__ && defined __STDC_VERSION__ \
              && __STDC_VERSION__ >= 201112L))
  # define __HAVE_GENERIC_SELECTION 1
  #else
  # define __HAVE_GENERIC_SELECTION 0
  #endif

But this feature gating isn't effective because `_has_extension()` will
always evaluate to true as C generics _are_ available as a language
extension to GNU C99 when using Clang. This would have been different if
`_has_feature()` was used instead, in which case it would have properly
evaluated to `false`.

GCC has a workaround to squelch this warning from standard system
headers, but because clang fails due to [-Werror,-Wc11-extensions],
as it lacks the corresponding workaround.

For both meson and Makefile, pass -Wno-c11-extensions when we are
building with clang.

Signed-off-by: Patrick Steinhardt <[email-masked]>
Helped-by: Shardul Natu <[email-masked]>
[jc: replaced Makefile side with Shardul's approach]
Signed-off-by: Junio C Hamano <[email-masked]>
---
 config.mak.dev | 7 +++++++
 meson.build    | 6 ++++++
 2 files changed, 13 insertions(+)

diff --git a/config.mak.dev b/config.mak.dev
index e86b6e1b34..794b1c9627 100644
--- a/config.mak.dev
+++ b/config.mak.dev
@@ -98,6 +98,13 @@ endif
 endif
 endif
 
+# glibc 2.43 headers unconditionally use _Generic even when we ask the
+# compiler to stick to -std=gnu99 and unlike GCC, clang lacks a
+# workaround to squelch warnings from system headers.
+ifneq ($(filter clang1,$(COMPILER_FEATURES)),)     # if we are using clang
+DEVELOPER_CFLAGS += -Wno-c11-extensions
+endif
+
 # https://bugzilla.redhat.com/show_bug.cgi?id=2075786
 ifneq ($(filter gcc12,$(COMPILER_FEATURES)),)
 DEVELOPER_CFLAGS += -Wno-error=stringop-overread
diff --git a/meson.build b/meson.build
index dd52efd1c8..536bd2679c 100644
--- a/meson.build
+++ b/meson.build
@@ -854,6 +854,12 @@ if get_option('warning_level') in ['2','3', 'everything'] and compiler.get_argum
       libgit_c_args += cflag
     endif
   endforeach
+
+  # Clang generates warnings when compiling glibc 2.43 because of the use of
+  # _Generic.
+  if compiler.get_id() == 'clang'
+    libgit_c_args += '-Wno-c11-extensions'
+  endif
 endif
 
 if get_option('breaking_changes')
-- 
2.54.0-170-g88022b8681