Details
- Reviewers
Mordante - Group Reviewers
Restricted Project - Commits
- rG81ad5a5cb877: [libc++] Implement stringbuf members of P0408R7 (Efficient Access to…
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Thanks a lot for splitting, that really helped me to finally do a full review of this patch.
It looks mostely good, some minor things.
libcxx/include/sstream | ||
---|---|---|
364 | http://eel.is/c++draft/stringbuf#members-15 Constraints: is_same_v<SAlloc,Allocator> is false. | |
423 | We still need to look at this issue. | |
470 | Same here. | |
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/alloc.pass.cpp | ||
14 | Here and in the other tests. | |
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string-alloc.mode.pass.cpp | ||
35 | How about testing the allocator of buf.str()? | |
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.alloc.pass.cpp | ||
32 | This nesting is not needed. |
libcxx/include/sstream | ||
---|---|---|
423 | I think it is okay to use nullptr instead of __p obtained from the moved string. | |
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string-alloc.mode.pass.cpp | ||
35 | How? |
Thanks LGTM! I'll land the patch on your behalf.
libcxx/include/sstream | ||
---|---|---|
365 | Nit: we only use std:: for function calls to avoid ADL. Note since the rest of the patch is fine, I'll fix this before landing. | |
423 | +1 for doing it in a separate patch. | |
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/string-alloc.mode.pass.cpp | ||
35 | Good point. |
libcxx/include/sstream | ||
---|---|---|
337 | This is causing link errors for us on Windows. (https://crbug.com/1463881) The problem is that sstream has an explicit instantiation declaration of basic_stringbuf<char> in the sstream header, but when compiling the instantiation in ios.instantiations.cpp, _LIBCPP_BUILDING_LIBRARY is defined and so this string_type str() const & member function doesn't get defined. (Apologies for the late report; we were blocked on https://reviews.llvm.org/D151953#4472195 until yesterday.) |
libcxx/include/sstream | ||
---|---|---|
337 | str() const & is _LIBCPP_HIDE_FROM_ABI so I think it should NOT be linked. |
libcxx/include/sstream | ||
---|---|---|
337 | The explicit instantiation decl uses _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS which is dllimport: https://github.com/llvm/llvm-project/blob/main/libcxx/include/__config#L564 I think the idea is that _LIBCPP_HIDE_FROM_ABI should exclude the method from the explicit instantiation but that attribute doesn't seem to be really working with dllimport: https://godbolt.org/z/qc3zfvdaa |
libcxx/include/sstream | ||
---|---|---|
337 | Is this issue specific to the str() const & overload? |
libcxx/include/sstream | ||
---|---|---|
337 | Yes, we're only seeing this issue for str() const & (I suppose the const && overload has the same problem, but we're not calling it.) I believe the other members are also dllimport, so in effect the _LIBCPP_HIDE_FROM_ABI isn't working, but it still builds because the members (at least the ones that get called in our builds) do get defined in the dll. What makes these specific methods problematic is that they're excluded when _LIBCPP_BUILDING_LIBRARY is set. I suppose that's technically an ODR violation, but I can see why it's needed for compatibility. I suppose we can try to make exclude_from_explicit_instantiation work better with dllimport explicit instantiations, but that means the code would only work with versions of Clang which has that fix. We could also stop using exclude_from_explicit_instantiation on Windows and go back to _LIBCPP_ALWAYS_INLINE. I guess that was more brittle which is why the attribute was added in the first place though. Maybe @ldionne has ideas here? |
libcxx/include/sstream | ||
---|---|---|
337 | This seems like https://github.com/llvm/llvm-project/issues/40363. I never had time to look into it, and until now it seemed like it wasn't hard-blocking anyone. The medium term fix is to fix https://github.com/llvm/llvm-project/issues/40363 and be done with it. // TODO(LLVM 19): Remove this once we drop support for Clang 16, which had this bug: https://github.com/llvm/llvm-project/issues/40363 #ifdef _WIN32 _LIBCPP_ALWAYS_INLINE string_type str() const & { return str(__str_.get_allocator()); } #else _LIBCPP_HIDE_FROM_ABI string_type str() const & { return str(__str_.get_allocator()); } #endif WDYT? Would someone with Windows access be willing to take on the fix for Clang? I can review it, I'm just really under water until the release. I don't think it's too hard to fix, the attribute was really simple to implement. It would be nice to fix this for LLVM 17, then we can remove the workaround fairly soon. |
libcxx/include/sstream | ||
---|---|---|
337 | I'm fine with both the short and medium term fixes and can do both. |
libcxx/include/sstream | ||
---|---|---|
337 | Both of these sound good to me too. I just confirmed the short-term one fixes our build, and I'm happy to help with the medium-term one too. (Thanks for finding the bug Louis, I had completely forgotten that we already had it on file.) |
libcxx/include/sstream | ||
---|---|---|
337 | Mentioning this here since this is where the discussion is: We're also seeing "missing symbol" errors for basic_ostringstream::str() (D155276) and basic_stringstream::str() (D155359) when building libc++ as a dll, and using it from client code built as c++17. (_Not_ for the const & overload as above, just for str(void) const.) (basic_istringstream was D154454 and it probably has similar issues, but we apparently don't have callers to it.) We only see this for the str() method, but we probably just don't call the str(string) method. I'm guessing this has a similar cause to what's discussed above. Using the ALWAYS_INLINE hack that was added in D155185 here as well, they go away: https://bugs.chromium.org/p/chromium/issues/detail?id=1463881#c11 For a more complete workaround, I'm guessing we'd have to slap on that attribute to the other functions touched in the revisions linked to above.) @pfusik Could you extend the workaround to cover those three classes too? |
libcxx/include/sstream | ||
---|---|---|
337 | https://reviews.llvm.org/D157602 My solution retains str() const in the DLL for compatibility with libc++ 16. Could you please verify if that works for you? |
libcxx/include/sstream | ||
---|---|---|
337 | Yes, it helps. Thanks! |
This is causing link errors for us on Windows. (https://crbug.com/1463881)
The problem is that sstream has an explicit instantiation declaration of basic_stringbuf<char> in the sstream header, but when compiling the instantiation in ios.instantiations.cpp, _LIBCPP_BUILDING_LIBRARY is defined and so this string_type str() const & member function doesn't get defined.
(Apologies for the late report; we were blocked on https://reviews.llvm.org/D151953#4472195 until yesterday.)