Volume XXII, number 280Wednesday, October 7, 2026Latest message 58 minutes ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

patchbuild: tolerate use of _Generic from glibc 2.43 with Clang

5 messages between May 5, 2026 and May 11, 2026, from Patrick Steinhardt, Junio C Hamano.

Plain Markdown or JSON for tools and agents. Diffs are folded; open one to read it.

Patrick SteinhardtMay 5, 2026, 12:26 UTC on lore

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`.

Unfortunately, there is no easy way for us to work around the warning. We cannot define `__HAVE_GENERIC_SELECTION` ourselves as that would lead to a redefinition, and given that the conditions are or'd together we cannot disable any of those, either.

Instead, work around the issue by not using -std=gnu99 with Clang when using the Makefile and by disabling warnings about C11 extensions when using Meson. This isn't ideal, but we at least retain the ability to detect the (mis-)use of features from newer standards with GCC.

An alternative to this might be to simply bump the required C standard to C11, which is 15 years old by now and should have support on most platforms out there. But some more esoteric platforms may not have it.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
Hi,

this patch fixes CI failures that have started to occur due to the upgrade to Ubuntu 26.04. Thanks!

Patrick
---
 config.mak.dev | 5 ++++-
 meson.build    | 6 ++++++
 2 files changed, 10 insertions(+), 1 deletion(-)
Show changes to 2 files +10 −1

config.mak.dev, meson.build

diff --git a/config.mak.dev b/config.mak.dev
index c8dcf78779..8830b78c1b 100644
--- a/config.mak.dev
+++ b/config.mak.dev
@@ -21,12 +21,15 @@ endif
 endif
 
 ifneq ($(uname_S),FreeBSD)
-ifneq ($(or $(filter gcc6,$(COMPILER_FEATURES)),$(filter clang7,$(COMPILER_FEATURES))),)
+ifneq ($(filter gcc6,$(COMPILER_FEATURES)),)
 DEVELOPER_CFLAGS += -std=gnu99
 endif
 else
 # FreeBSD cannot limit to C99 because its system headers unconditionally
 # rely on C11 features.
+#
+# Clang cannot limit to C99 when using glibc 2.43 because its system headers
+# depend on the _Generic C11 feature. This works with GCC though.
 endif
 
 DEVELOPER_CFLAGS += -Wdeclaration-after-statement
diff --git a/meson.build b/meson.build
index 11488623bf..2997d4f90f 100644
--- a/meson.build
+++ b/meson.build
@@ -866,6 +866,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')

---
base-commit: 94f057755b7941b321fd11fec1b2e3ca5313a4e0
change-id: 20260505-b4-pks-ci-tolerate-glibc-generic-0815aff39ff7
Junio C HamanoMay 11, 2026, 03:23 UTC in reply to Patrick Steinhardt on lore

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

Patrick Steinhardt <ps@pks.im> writes:
Show 8 quoted lines
> Instead, work around the issue by not using -std=gnu99 with Clang when
> using the Makefile and by disabling warnings about C11 extensions when
> using Meson. This isn't ideal, but we at least retain the ability to
> detect the (mis-)use of features from newer standards with GCC.
>
> An alternative to this might be to simply bump the required C standard
> to C11, which is 15 years old by now and should have support on most
> platforms out there. But some more esoteric platforms may not have it.

Wouldn't the approach you took on the meson side to pass "-Wno-c11-extensions" be yet another alternative? I think that is what the other proposal (which was only for Makefile world and not for meson world) did, even though it may not have been a great implemenation to help only those who use config.mak.dev

   <pull.2291.git.git.1778120192298.gitgitgadget@gmail.com>

We would need a patch to apply at lesat on v2.54.0 but possibly older tracks if we plan to keep them also buildable.

Thanks.
Junio C HamanoMay 11, 2026, 05:20 UTC in reply to Junio C Hamano on lore

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

Junio C Hamano <gitster@pobox.com> 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 <ps@pks.im>
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 <ps@pks.im>
Helped-by: Shardul Natu <snatu@google.com>
[jc: replaced Makefile side with Shardul's approach]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 config.mak.dev | 7 +++++++
 meson.build    | 6 ++++++
 2 files changed, 13 insertions(+)
Show changes to 2 files +13 −0

config.mak.dev, meson.build

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
Patrick SteinhardtMay 11, 2026, 05:46 UTC in reply to Junio C Hamano on lore

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

On Mon, May 11, 2026 at 02:20:09PM +0900, Junio C Hamano wrote:
Show 7 quoted lines
> Junio C Hamano <gitster@pobox.com> 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.

I was going back and forth on this myself. I simply wasn't sure whether it even buys us anything anymore if we have both "-std=gnu99" _and_ "-Wno-c11-extensions". But maybe this combination at least also detects the use of newer (C23) extensions?

In any case, I'm also happy with the patch you posted. Thanks!
Patrick
Junio C HamanoMay 11, 2026, 06:10 UTC in reply to Patrick Steinhardt on lore

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

Patrick Steinhardt <ps@pks.im> writes:
Show 13 quoted lines
> On Mon, May 11, 2026 at 02:20:09PM +0900, Junio C Hamano wrote:
>> Junio C Hamano <gitster@pobox.com> 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.
>
> I was going back and forth on this myself. I simply wasn't sure whether
> it even buys us anything anymore if we have both "-std=gnu99" _and_
> "-Wno-c11-extensions". But maybe this combination at least also detects
> the use of newer (C23) extensions?

We shouldn't be the only project hit by the unconditional use of _Generic in glibc 2.43 headers, should we? I was hoping that this would be fixed upstream, and that anything we do locally is merely a workaround of a tentative nature.

> In any case, I'm also happy with the patch you posted. Thanks!
Thanks for a quick response.

You may have guessed correctly that I want to fast-track this topic down to 'next' and 'master' soonish to salvage CI jobs running for them.

Back to recent threads