From bf7e2ebda2928c610b0d674bbe31aaa2878061bd Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 26 Aug 2024 21:13:50 +0200 Subject: [PATCH] Fix compilation errors with clang that masquerades as gcc 13. Reported by Sam James and Paul Eggert. * m4/gnulib-common.m4 (gl_COMMON_BODY): For _GL_GNUC_PREREQ, ignore the values of __GNUC__ and __GNUC_MINOR__ defined by clang. * lib/warn-on-use.h (_GL_WARN_ON_USE, _GL_WARN_ON_USE_CXX): Don't treat clang like GCC. * lib/wchar.in.h (wmemchr, wcschr, wcsrchr, wcspbrk, wcsstr): Disable the _GL_CXXALIASWARN1 and _GL_CXXALIASWARN invocations for masquerading clang++. --- ChangeLog | 12 ++++++++++++ lib/warn-on-use.h | 4 ++-- lib/wchar.in.h | 25 +++++++++++++++---------- m4/gnulib-common.m4 | 18 +++++++++++++++--- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 118cfdac75..1b047696ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2024-08-26 Bruno Haible + + Fix compilation errors with clang that masquerades as gcc 13. + Reported by Sam James and Paul Eggert. + * m4/gnulib-common.m4 (gl_COMMON_BODY): For _GL_GNUC_PREREQ, ignore the + values of __GNUC__ and __GNUC_MINOR__ defined by clang. + * lib/warn-on-use.h (_GL_WARN_ON_USE, _GL_WARN_ON_USE_CXX): Don't treat + clang like GCC. + * lib/wchar.in.h (wmemchr, wcschr, wcsrchr, wcspbrk, wcsstr): Disable + the _GL_CXXALIASWARN1 and _GL_CXXALIASWARN invocations for masquerading + clang++. + 2024-08-25 Paul Eggert diffseq: don’t worry about clang diff --git a/lib/warn-on-use.h b/lib/warn-on-use.h index 701013a07f..e3b1fefe50 100644 --- a/lib/warn-on-use.h +++ b/lib/warn-on-use.h @@ -85,7 +85,7 @@ */ #ifndef _GL_WARN_ON_USE -# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) +# if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ /* A compiler attribute is available in gcc versions 4.3.0 and later. */ # define _GL_WARN_ON_USE(function, message) \ _GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message))) @@ -121,7 +121,7 @@ _GL_WARN_EXTERN_C int _gl_warn_on_use # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ _GL_WARN_ON_USE (function, msg) # else -# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) +# if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ /* A compiler attribute is available in gcc versions 4.3.0 and later. */ # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ extern rettype_gcc function parameters_and_attributes \ diff --git a/lib/wchar.in.h b/lib/wchar.in.h index c08cf7299e..785e74787e 100644 --- a/lib/wchar.in.h +++ b/lib/wchar.in.h @@ -855,11 +855,12 @@ _GL_CXXALIAS_SYS_CAST2 (wmemchr, wchar_t *, (const wchar_t *, wchar_t, size_t), const wchar_t *, (const wchar_t *, wchar_t, size_t)); # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ + && !defined __clang__ _GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); _GL_CXXALIASWARN1 (wmemchr, const wchar_t *, (const wchar_t *s, wchar_t c, size_t n)); -# elif __GLIBC__ >= 2 +# elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO _GL_CXXALIASWARN (wmemchr); # endif #elif defined GNULIB_POSIXCHECK @@ -1407,10 +1408,11 @@ _GL_CXXALIAS_SYS_CAST2 (wcschr, wchar_t *, (const wchar_t *, wchar_t), const wchar_t *, (const wchar_t *, wchar_t)); # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ + && !defined __clang__ _GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc)); _GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); -# elif __GLIBC__ >= 2 +# elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO _GL_CXXALIASWARN (wcschr); # endif #elif defined GNULIB_POSIXCHECK @@ -1437,10 +1439,11 @@ _GL_CXXALIAS_SYS_CAST2 (wcsrchr, wchar_t *, (const wchar_t *, wchar_t), const wchar_t *, (const wchar_t *, wchar_t)); # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ + && !defined __clang__ _GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc)); _GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); -# elif __GLIBC__ >= 2 +# elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO _GL_CXXALIASWARN (wcsrchr); # endif #elif defined GNULIB_POSIXCHECK @@ -1508,12 +1511,13 @@ _GL_CXXALIAS_SYS_CAST2 (wcspbrk, wchar_t *, (const wchar_t *, const wchar_t *), const wchar_t *, (const wchar_t *, const wchar_t *)); # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ + && !defined __clang__ _GL_CXXALIASWARN1 (wcspbrk, wchar_t *, (wchar_t *wcs, const wchar_t *accept)); _GL_CXXALIASWARN1 (wcspbrk, const wchar_t *, (const wchar_t *wcs, const wchar_t *accept)); -# elif __GLIBC__ >= 2 +# elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO _GL_CXXALIASWARN (wcspbrk); # endif #elif defined GNULIB_POSIXCHECK @@ -1558,14 +1562,15 @@ _GL_CXXALIAS_SYS_CAST2 (wcsstr, (const wchar_t *restrict, const wchar_t *restrict)); # endif # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ + && !defined __clang__ _GL_CXXALIASWARN1 (wcsstr, wchar_t *, (wchar_t *restrict haystack, const wchar_t *restrict needle)); _GL_CXXALIASWARN1 (wcsstr, const wchar_t *, (const wchar_t *restrict haystack, const wchar_t *restrict needle)); -# elif __GLIBC__ >= 2 +# elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO _GL_CXXALIASWARN (wcsstr); # endif #elif defined GNULIB_POSIXCHECK diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index b1b3758db8..0f0eb07c44 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -1,5 +1,5 @@ # gnulib-common.m4 -# serial 101 +# serial 102 dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -21,10 +21,22 @@ AC_DEFUN([gl_COMMON_BODY], [ #define _GL_CONFIG_H_INCLUDED 1 ]) AH_VERBATIM([_GL_GNUC_PREREQ], -[/* True if the compiler says it groks GNU C version MAJOR.MINOR. */ -#if defined __GNUC__ && defined __GNUC_MINOR__ +[/* True if the compiler says it groks GNU C version MAJOR.MINOR. + Except that + - clang groks GNU C 4.2, even on Windows, where it does not define + __GNUC__. + - The OpenMandriva-modified clang compiler pretends that it groks + GNU C version 13.1, but it doesn't: It does not support + __attribute__ ((__malloc__ (f, i))), nor does it support + __attribute__ ((__warning__ (message))) on a function redeclaration. + - Users can make clang lie as well, through the -fgnuc-version option. */ +#if defined __GNUC__ && defined __GNUC_MINOR__ && !defined __clang__ # define _GL_GNUC_PREREQ(major, minor) \ ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__)) +#elif defined __clang__ + /* clang really only groks GNU C 4.2. */ +# define _GL_GNUC_PREREQ(major, minor) \ + ((major) < 4 + ((minor) <= 2)) #else # define _GL_GNUC_PREREQ(major, minor) 0 #endif -- 2.39.5