Skip to content

Commit 251478a

Browse files
pks-tdscho
authored andcommitted
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`. 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> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 9667258 commit 251478a

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

config.mak.dev

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@ endif
2121
endif
2222

2323
ifneq ($(uname_S),FreeBSD)
24-
ifneq ($(or $(filter gcc6,$(COMPILER_FEATURES)),$(filter clang7,$(COMPILER_FEATURES))),)
24+
ifneq ($(filter gcc6,$(COMPILER_FEATURES)),)
2525
ifndef USE_MIMALLOC
2626
DEVELOPER_CFLAGS += -std=gnu99
2727
endif
2828
endif
2929
else
3030
# FreeBSD cannot limit to C99 because its system headers unconditionally
3131
# rely on C11 features.
32+
#
33+
# Clang cannot limit to C99 when using glibc 2.43 because its system headers
34+
# depend on the _Generic C11 feature. This works with GCC though.
3235
endif
3336

3437
DEVELOPER_CFLAGS += -Wdeclaration-after-statement

meson.build

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,12 @@ if get_option('warning_level') in ['2','3', 'everything'] and compiler.get_argum
873873
libgit_c_args += cflag
874874
endif
875875
endforeach
876+
877+
# Clang generates warnings when compiling glibc 2.43 because of the use of
878+
# _Generic.
879+
if compiler.get_id() == 'clang'
880+
libgit_c_args += '-Wno-c11-extensions'
881+
endif
876882
endif
877883

878884
if get_option('breaking_changes')

0 commit comments

Comments
 (0)