Files
git/config.mak.dev
Patrick Steinhardt 0a6d29090c 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>
2026-05-11 14:57:07 +09:00

114 lines
3.7 KiB
Plaintext

ifndef COMPILER_FEATURES
COMPILER_FEATURES := $(shell ./detect-compiler $(CC))
endif
ifeq ($(filter no-error,$(DEVOPTS)),)
DEVELOPER_CFLAGS += -Werror
SPARSE_FLAGS += -Wsparse-error
endif
DEVELOPER_CFLAGS += -Wall
ifeq ($(filter no-pedantic,$(DEVOPTS)),)
DEVELOPER_CFLAGS += -pedantic
ifneq ($(or $(filter gcc5,$(COMPILER_FEATURES)),$(filter clang4,$(COMPILER_FEATURES))),)
DEVELOPER_CFLAGS += -Wpedantic
ifneq ($(filter gcc10,$(COMPILER_FEATURES)),)
ifeq ($(uname_S),MINGW)
DEVELOPER_CFLAGS += -Wno-pedantic-ms-format
endif
endif
endif
endif
ifneq ($(uname_S),FreeBSD)
ifneq ($(or $(filter gcc6,$(COMPILER_FEATURES)),$(filter clang7,$(COMPILER_FEATURES))),)
DEVELOPER_CFLAGS += -std=gnu99
endif
else
# FreeBSD cannot limit to C99 because its system headers unconditionally
# rely on C11 features.
endif
DEVELOPER_CFLAGS += -Wdeclaration-after-statement
DEVELOPER_CFLAGS += -Wformat-security
DEVELOPER_CFLAGS += -Wold-style-definition
DEVELOPER_CFLAGS += -Woverflow
DEVELOPER_CFLAGS += -Wpointer-arith
DEVELOPER_CFLAGS += -Wstrict-prototypes
DEVELOPER_CFLAGS += -Wunused
DEVELOPER_CFLAGS += -Wvla
DEVELOPER_CFLAGS += -Wwrite-strings
DEVELOPER_CFLAGS += -fno-common
DEVELOPER_CFLAGS += -Wunreachable-code
ifneq ($(filter clang9,$(COMPILER_FEATURES)),)
DEVELOPER_CFLAGS += -Wcomma
endif
ifneq ($(filter clang4,$(COMPILER_FEATURES)),)
DEVELOPER_CFLAGS += -Wtautological-constant-out-of-range-compare
endif
ifneq ($(or $(filter gcc6,$(COMPILER_FEATURES)),$(filter clang4,$(COMPILER_FEATURES))),)
DEVELOPER_CFLAGS += -Wextra
# if a function is public, there should be a prototype and the right
# header file should be included. If not, it should be static.
DEVELOPER_CFLAGS += -Wmissing-prototypes
ifeq ($(filter extra-all,$(DEVOPTS)),)
# These are disabled because we have these all over the place.
DEVELOPER_CFLAGS += -Wno-empty-body
DEVELOPER_CFLAGS += -Wno-missing-field-initializers
endif
endif
# uninitialized warnings on gcc 4.9.2 in xdiff/xdiffi.c and config.c
# not worth fixing since newer compilers correctly stop complaining
#
# Likewise, gcc older than 4.9 complains about initializing a
# struct-within-a-struct using just "{ 0 }"
ifneq ($(filter gcc4,$(COMPILER_FEATURES)),)
ifeq ($(filter gcc5,$(COMPILER_FEATURES)),)
DEVELOPER_CFLAGS += -Wno-uninitialized
DEVELOPER_CFLAGS += -Wno-missing-braces
endif
endif
# Old versions of clang complain about initializing a
# struct-within-a-struct using just "{0}" rather than "{{0}}". This
# error is considered a false-positive and not worth fixing, because
# new clang versions do not, so just disable it.
#
# The "bug" was fixed in upstream clang 9.
#
# Complicating this is that versions of clang released by Apple have
# their own version numbers (associated with the corresponding version
# of XCode) unrelated to the official clang version numbers.
#
# The bug was fixed in Apple clang 12.
#
ifneq ($(filter clang1,$(COMPILER_FEATURES)),) # if we are using clang
ifeq ($(uname_S),Darwin) # if we are on darwin
ifeq ($(filter clang12,$(COMPILER_FEATURES)),) # if version < 12
DEVELOPER_CFLAGS += -Wno-missing-braces
endif
else # not darwin
ifeq ($(filter clang9,$(COMPILER_FEATURES)),) # if version < 9
DEVELOPER_CFLAGS += -Wno-missing-braces
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
endif
GIT_TEST_PERL_FATAL_WARNINGS = YesPlease