When building a testdir of all of gnulib with clang 9 on a glibc system, I see these compilation errors:
In file included from ../../gltests/test-list-c++.cc:23: ../gllib/string.h:821:22: error: functions that differ only in their return type cannot be overloaded _GL_WARN_ON_USE_CXX (strchr, const char *, (const char *, int), ^ ~~~~~~ ../gllib/string.h:544:16: note: expanded from macro '_GL_WARN_ON_USE_CXX' extern rettype function parameters_and_attributes \ ~~~~~~~ ^ /usr/include/string.h:231:14: note: previous declaration is here extern char *strchr (const char *__s, int __c) ~~~~~~^ In file included from ../../gltests/test-list-c++.cc:23: ../gllib/string.h:1016:22: error: functions that differ only in their return type cannot be overloaded _GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *), ^ ~~~~~~ ../gllib/string.h:544:16: note: expanded from macro '_GL_WARN_ON_USE_CXX' extern rettype function parameters_and_attributes \ ~~~~~~~ ^ /usr/include/string.h:310:14: note: previous declaration is here extern char *strpbrk (const char *__s, const char *__accept) ~~~~~~^ In file included from ../../gltests/test-list-c++.cc:23: ../gllib/string.h:1045:22: error: functions that differ only in their return type cannot be overloaded _GL_WARN_ON_USE_CXX (strrchr, const char *, (const char *, int), ^ ~~~~~~ ../gllib/string.h:544:16: note: expanded from macro '_GL_WARN_ON_USE_CXX' extern rettype function parameters_and_attributes \ ~~~~~~~ ^ /usr/include/string.h:258:14: note: previous declaration is here extern char *strrchr (const char *__s, int __c) ~~~~~~^ 3 errors generated. So, where gcc wants a declaration of 'strchr', 'strpbrk', 'strrchr' with return type 'const char *' (see [1]), clang wants to see a return type 'char *'. [1] https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00099.html 2020-08-09 Bruno Haible <br...@clisp.org> string: Fix build error in C++ mode with clang (regression from today). * lib/warn-on-use.h (_GL_WARN_ON_USE_CXX): Expect two rettype parameters, one for GCC, one for clang. * lib/c++defs.h (_GL_CXXALIASWARN1_2): Update. * lib/string.in.h (strchr, strpbrk, strrchr): For clang, pass 'char *' as return type. diff --git a/lib/c++defs.h b/lib/c++defs.h index 75d6250..cd56ea2 100644 --- a/lib/c++defs.h +++ b/lib/c++defs.h @@ -298,7 +298,7 @@ we enable the warning only when not optimizing. */ # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ - _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ + _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \ "The symbol ::" #func " refers to the system function. " \ "Use " #namespace "::" #func " instead.") # else diff --git a/lib/string.in.h b/lib/string.in.h index c18efa7..ef702e3 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -329,7 +329,8 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " GB18030 and the character to be searched is a digit. */ # undef strchr /* Assume strchr is always declared. */ -_GL_WARN_ON_USE_CXX (strchr, const char *, (const char *, int), +_GL_WARN_ON_USE_CXX (strchr, + const char *, char *, (const char *, int), "strchr cannot work correctly on character strings " "in some multibyte locales - " "use mbschr if you care about internationalization"); @@ -524,7 +525,8 @@ _GL_CXXALIASWARN (strpbrk); locale encoding is GB18030 and one of the characters to be searched is a digit. */ # undef strpbrk -_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *), +_GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), "strpbrk cannot work correctly on character strings " "in multibyte locales - " "use mbspbrk if you care about internationalization"); @@ -532,7 +534,8 @@ _GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *), #elif defined GNULIB_POSIXCHECK # undef strpbrk # if HAVE_RAW_DECL_STRPBRK -_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *), +_GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), "strpbrk is unportable - " "use gnulib module strpbrk for portability"); # endif @@ -553,7 +556,8 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " GB18030 and the character to be searched is a digit. */ # undef strrchr /* Assume strrchr is always declared. */ -_GL_WARN_ON_USE_CXX (strrchr, const char *, (const char *, int), +_GL_WARN_ON_USE_CXX (strrchr, + const char *, char *, (const char *, int), "strrchr cannot work correctly on character strings " "in some multibyte locales - " "use mbsrchr if you care about internationalization"); diff --git a/lib/warn-on-use.h b/lib/warn-on-use.h index a39e3a3..5ff2163 100644 --- a/lib/warn-on-use.h +++ b/lib/warn-on-use.h @@ -106,33 +106,33 @@ _GL_WARN_EXTERN_C int _gl_warn_on_use # endif #endif -/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string") - is like _GL_WARN_ON_USE (function, "string"), except that in C++ mode the +/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message") + is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the function is declared with the given prototype, consisting of return type, parameters, and attributes. This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does not work in this case. */ #ifndef _GL_WARN_ON_USE_CXX # if !defined __cplusplus -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +# 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__) /* A compiler attribute is available in gcc versions 4.3.0 and later. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes \ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_gcc function parameters_and_attributes \ __attribute__ ((__warning__ (msg))) # elif __clang_major__ >= 4 /* Another compiler attribute is available in clang. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes \ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_clang function parameters_and_attributes \ __attribute__ ((__diagnose_if__ (1, msg, "warning"))) # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING /* Verify the existence of the function. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_gcc function parameters_and_attributes # else /* Unsupported. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ _GL_WARN_EXTERN_C int _gl_warn_on_use # endif # endif