This is causing ODR violations in Chrome that is preventing it from
being built with libc++ debug symbols and ThinLTO[0].
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
libcxx/include/ios | ||
---|---|---|
696–697 | I'm not sure if I should specify _LIBCPP_INLINE_VISIBILITY here - does anyone have any ideas? |
libcxx/include/ios | ||
---|---|---|
696–697 | Should we use inline _LIBCPP_INLINE_VISIBILITY instead like the neighboring code currently does? |
libcxx/include/ios | ||
---|---|---|
696–697 | So, _LIBCPP_INLINE_VISIBILITY is a historical predecessor to _LIBCPP_HIDE_FROM_ABI. In newer code, we've been updating to _LIBCPP_HIDE_FROM_ABI. With that being said, we definitely want inline there and also either _LIBCPP_HIDE_FROM_ABI or _LIBCPP_INLINE_VISIBILITY. There's an argument to be made for both. Using _LIBCPP_HIDE_FROM_ABI is the "new de-facto standard", whereas the latter is locally consistent in this neighborhood of code. I don't feel strongly. It's a bit surprising this destructor wasn't hidden from being an exported symbol in the ABI! |
libcxx/include/ios | ||
---|---|---|
696–697 | I think nobody would have a problem if we just remove the out-of-line definition and change line 642 to _LIBCPP_HIDE_FROM_ABI virtual ~basic_ios() = default;. I think it should be fine to make it = default, because all copy- and move constructors are deleted. |
LGTM assuming CI passes, but please wait for a second #libc reviewer before landing the patch.
I'm pretty sure CI is going to fail during check-cxx-abilist.
As-is, this patch is an ABI break for any user of iostream because it removes std::__1::basic_ios<wchar_t, std::__1::char_traits<wchar_t> >::~basic_ios() and std::__1::basic_ios<char, std::__1::char_traits<char> >::~basic_ios() from the dylib. Furthermore, I believe there was probably an intent of this destructor acting as a key function so that the vtable and RTTI of basic_ios<char|wchar_t> ends up in the dylib, and in the dylib only. I'm not 100% sure about that, but that's the most likely explanation for this strange definition in the first place.
After reading https://crbug.com/1327706#c13, it seems like the issue comes up when enabling libc++'s debug mode, right? If so, then I think this must be tackled via D122941 or something like it, instead.
I spoke with cjdb@ offline and it seems that we can maintain ABI compatibility by defining an empty destructor (i.e. ~basic_ios() {}) instead of using = default: https://godbolt.org/z/r73v1oE6n. WDYT?
I spoke with cjdb@ offline and it seems that we can maintain ABI compatibility by defining an empty destructor (i.e. ~basic_ios() {}) instead of using = default: https://godbolt.org/z/r73v1oE6n. WDYT?
The problem isn't the triviality of basic_ios. The problem is that there isn't a key function anymore, so the vtable and destructor aren't emitted in the dylib anymore.
Apologies for the dumb question, but could we resolve the issue by moving the definition of the destructor to ios.cpp? The destructor would still be a key function, and this should resolve the ODR issue.
@ayzhao I think using virtual ~basic_ios() {} should work. I think I'm missing something in how [[gnu::visibility("hidden")]], [[clang::exclude_from_explicit_instantiation]] and = default interact. Sorry for the confusion.
I just landed D122941 -- I think you should check whether this is still an issue for you.
So far, your patch does seem to work, but I'll need to wait to see if our bots are green when we roll libc++. Thanks!
I'm not sure if I should specify _LIBCPP_INLINE_VISIBILITY here - does anyone have any ideas?