[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: clang++ hard failure with GNULIB_NAMESPACE
From: |
Alexandre Duret-Lutz |
Subject: |
Re: clang++ hard failure with GNULIB_NAMESPACE |
Date: |
Fri, 15 Jan 2021 13:19:21 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
Hi Bruno
Bruno Haible <bruno@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