[cfe-dev] libc++: Unexpected pointer-to-member-function behavior

David Blaikie via cfe-dev cfe-dev at lists.llvm.org
Wed May 3 16:13:57 PDT 2017


On Wed, May 3, 2017 at 4:09 PM Eric Fiselier <eric at efcs.ca> wrote:

> This is a by-product of libc++'s use of __attribute__((always_inline,
> visibility("hidden"))) on string::size (and many other functions).
>
> std::string is externally instantiated in the dylib, this causes functions
> like `string::size` to have a dylib definition.
> Unfortunately this definition has hidden visibility which causes linker
> failures when an out-of-line reference to `string::size` is generated.
>

Ah, I was wondering how this actually lead to breakage - thanks for
covering it!


> This behavior should eventually be fixed for QoI reasons, even though the
> standard forbids taking the address of a member function.
>

+1. Richard Smith & I were talking about ways this might look at lunch the
other day due to some other issue we were discussing..

- Dave


>
> /Eric
>
>
>
> On Fri, Apr 21, 2017 at 9:54 AM, David Blaikie via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
>> FWIW the C++ standard doesn't allow taking the address of standard
>> library member functions (I don't know the wording - but I can go hunt for
>> it), so far as I understand.
>>
>> That said, interesting failure - not what I'd have expected.
>>
>> On Thu, Apr 20, 2017 at 10:45 PM Adam C. Emerson via cfe-dev <
>> cfe-dev at lists.llvm.org> wrote:
>>
>>> Hello. I'm not sure if this is a bug or if I'm using undefined
>>> behavior or otherwise doing something screwy.
>>>
>>> My Minimal Working Reproducer is:
>>>
>>> ---------->8-----------
>>>
>>> #include <functional>
>>> #include <iostream>
>>> #include <string>
>>>
>>> int main(void) {
>>>     auto s = ::std::string("Meow.");
>>>     auto l = ::std::mem_fn(&::std::string::size);
>>>
>>>     ::std::cout << l(s) << ::std::endl;
>>>
>>>     return 0;
>>> }
>>>
>>> ---------->8-----------
>>>
>>> If I compile this under g++ or with clang++ using libstdc++, this
>>> compiles and works as expected. However, if I use clang++ (v4.0.0 on
>>> Arch Linux x86_64) with libc++ (4.0.0), I get a link error:
>>>
>>> ---------->8-----------
>>>
>>> % clang++ -v -std=c++14 -stdlib=libc++ foo.cc
>>> clang version 4.0.0 (tags/RELEASE_400/final)
>>> Target: x86_64-unknown-linux-gnu
>>> Thread model: posix
>>> InstalledDir: /usr/bin
>>> Found candidate GCC installation:
>>> /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/6.3.1
>>> Found candidate GCC installation:
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1
>>> Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1
>>> Found candidate GCC installation:
>>> /usr/lib64/gcc/x86_64-pc-linux-gnu/6.3.1
>>> Selected GCC installation:
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1
>>> Candidate multilib: .;@m64
>>> Candidate multilib: 32;@m32
>>> Selected multilib: .;@m64
>>>  "/usr/bin/clang-4.0" -cc1 -triple x86_64-unknown-linux-gnu -emit-obj
>>> -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names
>>> -main-file-name foo.cc -mrelocation-model static -mthread-model posix
>>> -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases
>>> -munwind-tables -fuse-init-array -target-cpu x86-64 -v -dwarf-column-info
>>> -debugger-tuning=gdb -resource-dir /usr/bin/../lib/clang/4.0.0
>>> -internal-isystem /usr/bin/../include/c++/v1 -internal-isystem
>>> /usr/local/include -internal-isystem /usr/bin/../lib/clang/4.0.0/include
>>> -internal-externc-isystem /include -internal-externc-isystem /usr/include
>>> -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/azure
>>> -ferror-limit 19 -fmessage-length 119 -fobjc-runtime=gcc -fcxx-exceptions
>>> -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o
>>> /tmp/foo-1fe78b.o -x c++ foo.cc
>>> clang -cc1 version 4.0.0 based upon LLVM 4.0.0 default target
>>> x86_64-unknown-linux-gnu
>>> ignoring nonexistent directory "/include"
>>> #include "..." search starts here:
>>> #include <...> search starts here:
>>>  /usr/bin/../include/c++/v1
>>>  /usr/local/include
>>>  /usr/bin/../lib/clang/4.0.0/include
>>>  /usr/include
>>> End of search list.
>>>  "/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker
>>> /lib64/ld-linux-x86-64.so.2 -o a.out
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64/crt1.o
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64/crti.o
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/crtbegin.o
>>> -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1
>>> -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64
>>> -L/usr/bin/../lib64 -L/lib/../lib64 -L/usr/lib/../lib64
>>> -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../..
>>> -L/usr/bin/../lib -L/lib -L/usr/lib /tmp/foo-1fe78b.o -lc++ -lm -lgcc_s
>>> -lgcc -lc -lgcc_s -lgcc
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/crtend.o
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../lib64/crtn.o
>>> /tmp/foo-1fe78b.o: In function `main':
>>> foo.cc:(.text+0x44d): undefined reference to
>>> `std::__1::basic_string<char, std::__1::char_traits<char>,
>>> std::__1::allocator<char> >::size() const'
>>> /usr/bin/ld: a.out: hidden symbol
>>> `_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4sizeEv'
>>> isn't defined
>>> /usr/bin/ld: final link failed: Bad value
>>> clang-4.0: error: linker command failed with exit code 1 (use -v to see
>>> invocation)
>>>
>>> ---------->8-----------
>>>
>>> Thank you very much.
>>> _______________________________________________
>>> cfe-dev mailing list
>>> cfe-dev at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170503/01e204ae/attachment.html>


More information about the cfe-dev mailing list