This is an archive of the discontinued LLVM Phabricator instance.

[libcxx] Add missing __cxa_deleted_virtual
AbandonedPublic

Authored by eduardo-elizondo on Aug 18 2017, 4:33 AM.

Details

Summary

At least on macOS, libc++ fails to advertise __cxa_deleted_virtual from the underlying libc++abi:

~ cat test.cc
struct S { virtual void f() = delete; };
int main() { new S; }

~ clang++ -v -std=c++11 test.cc
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name test.cc -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -target-linker-version 278.4 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.1.0 -stdlib=libc++ -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /Users/stephan -ferror-limit 19 -fmessage-length 132 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/q3/7lltvjlj4_l44qtq0fjz_slh0000gn/T/test-f1e908.o -x c++ test.cc
clang -cc1 version 8.1.0 (clang-802.0.42) default target x86_64-apple-darwin16.7.0
ignoring nonexistent directory "/usr/include/c++/v1"
ignoring nonexistent directory "/usr/local/include"
#include "..." search starts here:
#include <...> search starts here:
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.1.0/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -macosx_version_min 10.12.0 -o a.out /var/folders/q3/7lltvjlj4_l44qtq0fjz_slh0000gn/T/test-f1e908.o -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.1.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
  "___cxa_deleted_virtual", referenced from:
      vtable for S in test-f1e908.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I have no real idea what all these various files are used for, and which changes exactly are required and correct. Just adding cxa_deleted_virtual to all files in libcxx that already mentioned cxa_pure_virtual and doing a fresh build fixed the issue for me on macOS (after fruitless attempts with changing only a subset of the files and/or doing an incremental rebuild).

Diff Detail

Event Timeline

sberg created this revision.Aug 18 2017, 4:33 AM
mclow.lists edited edge metadata.EditedAug 31 2017, 7:26 AM

In an ideal world, your example would fail to compile. However, we don't live in that world. (yet) :-(
This looks reasonable to me - but I didn't write these files - @EricWF - what do you think?

Also, from an organizational point of view, I would put these next to (and make them identical to) the entries for ___cxa_pure_virtual (which you have for some, but not all of the files)

EricWF requested changes to this revision.Sep 10 2017, 4:45 PM
EricWF added inline comments.
lib/abi/3.9/x86_64-apple-darwin16.abilist
2284 ↗(On Diff #111653)

Files under lib/abi/<version> should not be changed. They're for already released versions of libc++, and this change doesn't affect those.

lib/abi/x86_64-unknown-linux-gnu.abilist
1873

Why are we changing the Linux lists when this change only affects OS X?

This revision now requires changes to proceed.Sep 10 2017, 4:45 PM
sberg added inline comments.Sep 11 2017, 2:45 AM
lib/abi/x86_64-unknown-linux-gnu.abilist
1873

As I wrote, "I have no real idea what all these various files are used for, and which changes exactly are required and correct. Just adding cxa_deleted_virtual to all files in libcxx that already mentioned cxa_pure_virtual [...]" The way libc++.so on Linux consists of

INPUT(libc++.so.1 -lc++abi)

it does not need the fix that macOS needs to make cxa_deleted_virtual available through -lc++, but it still "re-exports" cxa_deleted_virtual the same way it does for __cxa_pure_virtual (which is also mentioned in this file), so I naively assumed it should be listed here, too.

Any updates on this? I'm also hitting this bug.

sberg updated this revision to Diff 115168.Sep 13 2017, 11:29 PM
sberg edited edge metadata.

Drop changes of files under lib/abi/<version>.

sberg marked an inline comment as done.Sep 13 2017, 11:30 PM
eduardo-elizondo commandeered this revision.Sep 14 2017, 7:28 PM
eduardo-elizondo abandoned this revision.
eduardo-elizondo added a reviewer: sberg.

D37830 supersedes this change.

sberg edited edge metadata.Sep 15 2017, 12:33 AM

...but I'm still curious as to why lib/abi/x86_64-unknown-linux-gnu.abilist should want to mention __cxa_pure_virtual but not __cxa_deleted_virtual

...but I'm still curious as to why lib/abi/x86_64-unknown-linux-gnu.abilist should want to mention __cxa_pure_virtual but not __cxa_deleted_virtual

Because libc++ doesn't actually have any instances of deleted virtual functions within the library __cxa_deleted_vilrtual is never used, and hence never exported on Linux.
We do, however, have pure virtual functions, so __cxa_pure_virtual is exported transitively. On Linux we don't use the explicit export lists, so this change didn't change the Linux ABI.

Do you need somebody to commit this for you?

Because libc++ doesn't actually have any instances of deleted virtual functions within the library __cxa_deleted_vilrtual is never used, and hence never exported on Linux.
We do, however, have pure virtual functions, so __cxa_pure_virtual is exported transitively. On Linux we don't use the explicit export lists, so this change didn't change the Linux ABI.

Ah, I see. Thanks.

Do you need somebody to commit this for you?

No, as this has been abandoned in favour of D37830 anyway.