Hi Bruno Bruno Haible <br...@clisp.org> writes:
>> Using clang++ 11, compilation fails because of the overloads of memchr >> and friends. >> >> In file included from bitvect.cc:28: >> In file included from >> /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cstring:42: >> ../../lib/string.h:693:1: error: reference to overloaded function >> could not be resolved; did you mean to call it? >> _GL_CXXALIASWARN (memchr); >> ^~~~~~~~~~~~~~~~~~~~~~~~~ > > On which version of glibc do you see this? This is the glibc packaged as "libc6 2.31-9" in Debian unstable. > On my machine, the testdir created through > $ ./gnulib-tool --create-testdir --dir=../testdir4 > --single-configure --with-c++-tests memchr rawmemchr strchrnul > > compiles fine with clang 11 and these environment variable settings: > > CC=$HOME/inst-clang/11.0.0/bin/clang > CXX="$HOME/inst-clang/11.0.0/bin/clang++ > -L/usr/lib/gcc/x86_64-linux-gnu/5 -I/usr/include/c++/5 > -I/usr/include/x86_64-linux-gnu/c++/5" > export CC CXX > > Does this same testdir work for you? No, the command ./configure CXX=clang++ && make fails as follows: clang++ -DHAVE_CONFIG_H -I. -I.. -DGNULIB_STRICT_CHECKING=1 -DIN_GNULIB_TESTS=1 -I. -I. -I.. -I./.. -I../gllib -I./../gllib -g -O2 -MT test-string-c++.o -MD -MP -MF .deps/test-string-c++.Tpo -c -o test-string-c++.o test-string-c++.cc In file included from test-string-c++.cc:22: ../gllib/string.h:693:1: error: reference to overloaded function could not be resolved; did you mean to call it? _GL_CXXALIASWARN (memchr); ^~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:365:4: note: expanded from macro '_GL_CXXALIASWARN' _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:367:4: note: expanded from macro '_GL_CXXALIASWARN_1' _GL_CXXALIASWARN_2 (func, namespace) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:372:5: note: expanded from macro '_GL_CXXALIASWARN_2' _GL_WARN_ON_USE (func, \ ^~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:535:19: note: expanded from macro '_GL_WARN_ON_USE' extern __typeof__ (function) function \ ^~~~~~~~~~ /usr/include/string.h:84:1: note: possible target for call memchr (const void *__s, int __c, size_t __n) __THROW ^ /usr/include/string.h:78:1: note: possible target for call memchr (void *__s, int __c, size_t __n) __THROW ^ In file included from test-string-c++.cc:22: ../gllib/string.h:807:1: error: reference to overloaded function could not be resolved; did you mean to call it? _GL_CXXALIASWARN (rawmemchr); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:365:4: note: expanded from macro '_GL_CXXALIASWARN' _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:367:4: note: expanded from macro '_GL_CXXALIASWARN_1' _GL_CXXALIASWARN_2 (func, namespace) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:372:5: note: expanded from macro '_GL_CXXALIASWARN_2' _GL_WARN_ON_USE (func, \ ^~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:535:19: note: expanded from macro '_GL_WARN_ON_USE' extern __typeof__ (function) function \ ^~~~~~~~~~ /usr/include/string.h:101:26: note: possible target for call extern "C++" const void *rawmemchr (const void *__s, int __c) ^ /usr/include/string.h:99:20: note: possible target for call extern "C++" void *rawmemchr (void *__s, int __c) ^ In file included from test-string-c++.cc:22: ../gllib/string.h:911:1: error: reference to overloaded function could not be resolved; did you mean to call it? _GL_CXXALIASWARN (strchrnul); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:365:4: note: expanded from macro '_GL_CXXALIASWARN' _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:367:4: note: expanded from macro '_GL_CXXALIASWARN_1' _GL_CXXALIASWARN_2 (func, namespace) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:372:5: note: expanded from macro '_GL_CXXALIASWARN_2' _GL_WARN_ON_USE (func, \ ^~~~~~~~~~~~~~~~~~~~~~~~ ../gllib/string.h:535:19: note: expanded from macro '_GL_WARN_ON_USE' extern __typeof__ (function) function \ ^~~~~~~~~~ /usr/include/string.h:263:26: note: possible target for call extern "C++" const char *strchrnul (const char *__s, int __c) ^ /usr/include/string.h:261:20: note: possible target for call extern "C++" char *strchrnul (char *__s, int __c) ^ 3 errors generated. make[4]: *** [Makefile:1542: test-string-c++.o] Error 1 > If I can't reproduce it, I'll have to ask you for appropriate modifications > of gnulib/lib/string.in.h that make things for work you. >From what I understand, the problem is that: 1) my version of string.h has two definitions of memchr for clang, 2) the following snippet assumes that g++ < 4.4 should only see one, regardless of the glibc version 3) clang++ masquerade as g++ 4.2.1 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) _GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n)); _GL_CXXALIASWARN1 (memchr, void const *, (void const *__s, int __c, size_t __n)); # elif __GLIBC__ >= 2 _GL_CXXALIASWARN (memchr); # endif As a first approximation, I tried to simply change the condition to # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __clang__) but doing so still fail with In file included from test-string-c++.cc:22: ../gllib/string.h:689:20: error: 'memchr' is missing exception specification 'throw()' _GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n)); ^ /usr/include/string.h:78:1: note: previous declaration is here memchr (void *__s, int __c, size_t __n) __THROW ^ In file included from test-string-c++.cc:22: ../gllib/string.h:690:20: error: 'memchr' is missing exception specification 'throw()' _GL_CXXALIASWARN1 (memchr, void const *, ^ /usr/include/string.h:84:1: note: previous declaration is here memchr (const void *__s, int __c, size_t __n) __THROW ^ The relevant definitions of memchr in my copy of /usr/include/string.h 35 /* Tell the caller that we provide correct C++ prototypes. */ 36 #if defined __cplusplus && (__GNUC_PREREQ (4, 4) \ 37 || __glibc_clang_prereq (3, 5)) 38 # define __CORRECT_ISO_CPP_STRING_H_PROTO 39 #endif .. 67 /* Search N bytes of S for C. */ 68 #ifdef __CORRECT_ISO_CPP_STRING_H_PROTO 69 extern "C++" 70 { 71 extern void *memchr (void *__s, int __c, size_t __n) 72 __THROW __asm ("memchr") __attribute_pure__ __nonnull ((1)); 73 extern const void *memchr (const void *__s, int __c, size_t __n) 74 __THROW __asm ("memchr") __attribute_pure__ __nonnull ((1)); 75 76 # ifdef __OPTIMIZE__ 77 __extern_always_inline void * 78 memchr (void *__s, int __c, size_t __n) __THROW 79 { 80 return __builtin_memchr (__s, __c, __n); 81 } 82 83 __extern_always_inline const void * 84 memchr (const void *__s, int __c, size_t __n) __THROW 85 { 86 return __builtin_memchr (__s, __c, __n); 87 } 88 # endif 89 } 90 #else 91 extern void *memchr (const void *__s, int __c, size_t __n) 92 __THROW __attribute_pure__ __nonnull ((1)); 93 #endif If I preprocess the file, I can see the __THROW expands to "throw ()", but that's the case for g++ as well. The reason for the "g++ 4.4" threshold was that initially the definition of __CORRECT_ISO_CPP_STRING_H_PROTO used only that: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d8387c7b7b1c9ae92f924c33ba05790c98464d19 The change to the current definition is one year old: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=953ceff17a4a15b10cfdd5edc3c8cae4884c8ec3 I have reproduced these errors with clang++ 9, 10, and 11, but that should not be surprising if __CORRECT_ISO_CPP_STRING_H_PROTO is enabled for clang++ >= 3.5. -- Alexandre Duret-Lutz