Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

std::string + -finstrument-functions + -std=c++20 = template miscompilation #50367

Open Quuxplusone opened 3 years ago

Quuxplusone commented 3 years ago
Bugzilla Link PR51400
Status NEW
Importance P normal
Reported by Matt Fellenz (mattf53190@gmail.com)
Reported on 2021-08-07 07:16:17 -0700
Last modified on 2021-08-07 17:38:50 -0700
Version trunk
Hardware PC Linux
CC blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, mattf53190@gmail.com, richard-llvm@metafoo.co.uk
Fixed by commit(s)
Attachments cpptest.tar.gz (475 bytes, application/gzip)
Blocks
Blocked by
See also

Created attachment 25117 MRE and test script

When compiling with -finstrument-functions and any standard above C++17, that is C++2a aka 20 or 2b aka 23, when attempting to declare a string, the proper templates relating to standard library allocators are not included in the object files, leading to the following linker error:

/usr/bin/ld: /tmp/main-6f2635.o: in function `std::allocator_traits<std::allocator<char> >::deallocate(std::allocator<char>&, char*, unsigned long)':
main.cpp:(.text._ZNSt16allocator_traitsISaIcEE10deallocateERS0_Pcm[_ZNSt16allocator_traitsISaIcEE10deallocateERS0_Pcm]+0x5d): undefined reference to `std::allocator<char>::deallocate(char*, unsigned long)'
/usr/bin/ld: main.cpp:(.text._ZNSt16allocator_traitsISaIcEE10deallocateERS0_Pcm[_ZNSt16allocator_traitsISaIcEE10deallocateERS0_Pcm]+0x99): undefined reference to `std::allocator<char>::deallocate(char*, unsigned long)'
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)

Additionally, if the string has contents, the error will include the inability to find an allocate method:

/usr/bin/ld: /tmp/main-248bd2.o: in function `std::allocator_traits<std::allocator<char> >::deallocate(std::allocator<char>&, char*, unsigned long)':
main.cpp:(.text._ZNSt16allocator_traitsISaIcEE10deallocateERS0_Pcm[_ZNSt16allocator_traitsISaIcEE10deallocateERS0_Pcm]+0x5d): undefined reference to `std::allocator<char>::deallocate(char*, unsigned long)'
/usr/bin/ld: main.cpp:(.text._ZNSt16allocator_traitsISaIcEE10deallocateERS0_Pcm[_ZNSt16allocator_traitsISaIcEE10deallocateERS0_Pcm]+0x99): undefined reference to `std::allocator<char>::deallocate(char*, unsigned long)'
/usr/bin/ld: /tmp/main-248bd2.o: in function `std::allocator_traits<std::allocator<char> >::allocate(std::allocator<char>&, unsigned long)':
main.cpp:(.text._ZNSt16allocator_traitsISaIcEE8allocateERS0_m[_ZNSt16allocator_traitsISaIcEE8allocateERS0_m]+0x49): undefined reference to `std::allocator<char>::allocate(unsigned long)'
/usr/bin/ld: main.cpp:(.text._ZNSt16allocator_traitsISaIcEE8allocateERS0_m[_ZNSt16allocator_traitsISaIcEE8allocateERS0_m]+0x81): undefined reference to `std::allocator<char>::allocate(unsigned long)'
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)

This manifests for -std=c++20, -std=gnu++20, -std=c++2b, -std=gnu++2b, but not for std=c++17. Additionally, the g++ can compile the code with the same flags, for every C++ standard I tested, from c++17 to c++2b.

See attached tarball for a minimal reproducible example and a script to test whether clang++ and g++ can build it for each standard.

I wasn't sure if this qualifies as release blocker because theoretically you could remove -finstrument-functions, in which case it compiles just fine. However I like seeing all the function names in debugging tools like ASAN.

Quuxplusone commented 3 years ago

Attached cpptest.tar.gz (475 bytes, application/gzip): MRE and test script

Quuxplusone commented 3 years ago

Godbolt demo link in case you don't want to download the gzip: https://godbolt.org/z/19j1MTa9j