[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #22 from CVS Commits --- The releases/gcc-12 branch has been updated by Jonathan Wakely : https://gcc.gnu.org/g:a088d93c210f9b662d706e2fcf63a59d05fe27c1 commit r12-8908-ga088d93c210f9b662d706e2fcf63a59d05fe27c1 Author: Nathaniel Shead Date: Fri Nov 11 22:23:31 2022 +1100 libstdc++: Set active union member in constexpr std::string [PR103295] Clang still complains about using std::string in constexpr contexts due to the changes made in commit 98a0d72a. This patch ensures that we set the active member of the union as according to [class.union.general] p6. libstdc++-v3/ChangeLog: PR libstdc++/103295 * include/bits/basic_string.h (_M_use_local_data): Set active member to _M_local_buf. Signed-off-by: Nathaniel Shead (cherry picked from commit 52672be7d328df50f9a05ce3ab44ebcae50fee1b)
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #21 from CVS Commits --- The master branch has been updated by Jonathan Wakely : https://gcc.gnu.org/g:52672be7d328df50f9a05ce3ab44ebcae50fee1b commit r13-3910-g52672be7d328df50f9a05ce3ab44ebcae50fee1b Author: Nathaniel Shead Date: Fri Nov 11 22:23:31 2022 +1100 libstdc++: Set active union member in constexpr std::string [PR103295] Clang still complains about using std::string in constexpr contexts due to the changes made in commit 98a0d72a. This patch ensures that we set the active member of the union as according to [class.union.general] p6. libstdc++-v3/ChangeLog: PR libstdc++/103295 * include/bits/basic_string.h (_M_use_local_data): Set active member to _M_local_buf. Signed-off-by: Nathaniel Shead
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 Jonathan Wakely changed: What|Removed |Added Resolution|--- |FIXED Target Milestone|--- |12.0 Status|ASSIGNED|RESOLVED --- Comment #20 from Jonathan Wakely --- It should be fixed now.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #19 from CVS Commits --- The master branch has been updated by Jonathan Wakely : https://gcc.gnu.org/g:1f8d01eb1476a997eb1fc686b60fccdf97747faa commit r12-5421-g1f8d01eb1476a997eb1fc686b60fccdf97747faa Author: Jonathan Wakely Date: Fri Nov 19 18:27:59 2021 + libstdc++: One more change for Clang to support constexpr std::string [PR103295] All writes into the allocated buffer need to be via traits_type::assign to begin lifetimes. libstdc++-v3/ChangeLog: PR libstdc++/103295 * include/bits/basic_string.tcc (_M_construct): Use the traits assign member to write into allcoated memory.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #18 from Jonathan Wakely --- There's still one more fix needed for _M_construct
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #17 from CVS Commits --- The master branch has been updated by Jonathan Wakely : https://gcc.gnu.org/g:2d76292bd6719d687bc77051da265df8ed7f5a61 commit r12-5413-g2d76292bd6719d687bc77051da265df8ed7f5a61 Author: Jonathan Wakely Date: Thu Nov 18 10:33:14 2021 + libstdc++: Begin lifetime of chars in constexpr std::string [PR103295] Clang gives errors for constexpr std::string because the memory returned by std::allocator::allocate does not contain any objects yet, and attempting to set them using char_traits::assign or char_traits::copy fails with: assignment to object outside its lifetime is not allowed in a constant expression *__result = *__first; ^ This adds code to std::char_traits to use std::construct_at to begin lifetimes when called during constant evaluation. To support specializations of std::basic_string that don't use std::char_traits there is now another layer of wrapper around the allocator_traits, so that the lifetime of characters is begun as soon as the memory is allocated. By doing it in the char traits and allocator traits, the rest of basic_string can ignore the problem. While modifying char_traits::copy and char_traits::assign to begin lifetimes for the constexpr cases, I also replaced their uses of std::copy and std::fill_n respectively. That means we don't need for char_traits. libstdc++-v3/ChangeLog: PR libstdc++/103295 * include/bits/basic_string.h (_Alloc_traits): Replace typedef with struct for C++20 mode. * include/bits/basic_string.tcc (_M_replace): Use _Alloc_traits for allocation. * include/bits/char_traits.h (__gnu_cxx::char_traits::assign): Use std::_Construct during constant evaluation. (__gnu_cxx::char_traits::assign(CharT*, const CharT*, size_t)): Likewise. Replace std::fill_n with memset or manual loop. (__gnu_cxx::char_traits::copy): Likewise, replacing std::copy with memcpy. * include/ext/vstring.h: Include for std::min. * include/std/string_view: Likewise. * testsuite/21_strings/basic_string/capacity/char/resize_and_overwrite.cc: Add constexpr test.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 Richard Biener changed: What|Removed |Added Target Milestone|12.0|---
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #16 from cqwrteur --- (In reply to Jonathan Wakely from comment #15) > Reopened :-( > > I have a patch to make clang happy, but I think what we really want is a > language change. hi jwakely. i am trying to add a new patch to ignore copying DLLs to ../$(libdir)/bin if we are build gcc with multilibs (since 32 bits dlls overrides 64 bits dlls). libgcc does not copy dlls either. do you think that is appropriate?
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 Jonathan Wakely changed: What|Removed |Added Resolution|FIXED |--- Status|RESOLVED|ASSIGNED --- Comment #15 from Jonathan Wakely --- Reopened :-( I have a patch to make clang happy, but I think what we really want is a language change.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 Jonathan Wakely changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #14 from Jonathan Wakely --- I'm going to mark this as fixed, I think the remaining problem is a clang bug. I'll reopen if Richard Smith convinces me otherwise.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #13 from CVS Commits --- The master branch has been updated by Jonathan Wakely : https://gcc.gnu.org/g:6afa1083c6ee7b31629fb0c16299b952cb17868c commit r12-5343-g6afa1083c6ee7b31629fb0c16299b952cb17868c Author: Jonathan Wakely Date: Wed Nov 17 10:23:14 2021 + libstdc++: Set active member of union in std::string [PR103295] Clang diagnoses that the new constexpr std::string constructors are not usable in constant expressions, because they start to write to members of the union without setting an active member. This adds a new helper function which returns the address of the local buffer after making it the active member. This doesn't fix all problems with Clang, because it still refuses to write to memory returned by the allocator. libstdc++-v3/ChangeLog: PR libstdc++/103295 * include/bits/basic_string.h (_M_use_local_data()): New member function to make local buffer the active member. (assign(const basic_string&)): Use it. * include/bits/basic_string.tcc (_M_construct, reserve()): Likewise.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #12 from Jonathan Wakely --- But even with those problems fixed, Clang fails for anything that doesn't fit in the SSO buffer, as shown by this: #include constexpr char test() { char* p = std::allocator().allocate(2); p[0] = 'a'; char c = *p; std::allocator().deallocate(p, 2); return c; } static_assert( test() == 'a' );
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #11 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #7) > It just doesn't allow assignment through the pointer. I think that's correct according to [class.union.general] p6: "When the left operand of an assignment operator involves a member access expression ([expr.ref]) that nominates a union member, it may begin the lifetime of that union member, as described below." `_M_local_buf[0] = 0;` is OK, but `auto p = _M_local_buf; p[0] = 0;` is not.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #10 from Jonathan Wakely --- (Do you really need to quote the whole of comment 9 to reply to comment 8?) You can't, it's not freely available.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #9 from cqwrteur --- (In reply to Jonathan Wakely from comment #8) > Which means this is enough to make Clang happy for the comment 0 example: > > --- a/libstdc++-v3/include/bits/basic_string.tcc > +++ b/libstdc++-v3/include/bits/basic_string.tcc > @@ -167,6 +167,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >_M_construct(_InIterator __beg, _InIterator __end, >std::input_iterator_tag) >{ > +#if __cpp_lib_is_constant_evaluated > + if (__builtin_is_constant_evaluated()) > + _M_local_buf[0] = _CharT(); > +#endif > + > size_type __len = 0; > size_type __capacity = size_type(_S_local_capacity); > > @@ -223,6 +228,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > _M_data(_M_create(__dnew, size_type(0))); > _M_capacity(__dnew); > } > +#if __cpp_lib_is_constant_evaluated > + else if (__builtin_is_constant_evaluated()) > + _M_local_buf[0] = _CharT(); > +#endif > > // Check for out_of_range and length_error exceptions. > __try > @@ -247,6 +256,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > _M_data(_M_create(__n, size_type(0))); > _M_capacity(__n); > } > +#if __cpp_lib_is_constant_evaluated > + else if (__builtin_is_constant_evaluated()) > + _M_local_buf[0] = _CharT(); > +#endif > >if (__n) > this->_S_assign(_M_data(), __n, __c); where can i download EDG??
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #8 from Jonathan Wakely --- Which means this is enough to make Clang happy for the comment 0 example: --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -167,6 +167,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_construct(_InIterator __beg, _InIterator __end, std::input_iterator_tag) { +#if __cpp_lib_is_constant_evaluated + if (__builtin_is_constant_evaluated()) + _M_local_buf[0] = _CharT(); +#endif + size_type __len = 0; size_type __capacity = size_type(_S_local_capacity); @@ -223,6 +228,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_data(_M_create(__dnew, size_type(0))); _M_capacity(__dnew); } +#if __cpp_lib_is_constant_evaluated + else if (__builtin_is_constant_evaluated()) + _M_local_buf[0] = _CharT(); +#endif // Check for out_of_range and length_error exceptions. __try @@ -247,6 +256,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_data(_M_create(__n, size_type(0))); _M_capacity(__n); } +#if __cpp_lib_is_constant_evaluated + else if (__builtin_is_constant_evaluated()) + _M_local_buf[0] = _CharT(); +#endif if (__n) this->_S_assign(_M_data(), __n, __c);
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #7 from Jonathan Wakely --- The code can be reduced to this, which GCC, EDG and MSVC all accept, but Clang doesn't: struct S { union { char buf[8]; char* ptr; }; unsigned len; constexpr S(const char* s, unsigned n) { char* p; if (n > 7) p = ptr = new char[n]; else p = buf; for (len = 0; len < n; ++len) p[len] = s[len]; p[len] = '\0'; } constexpr ~S() { if (len > 7) delete[] ptr; } }; constexpr bool test() { S s("test", 4); return true; } static_assert( test() ); Clang accepts it if written like this: constexpr S(const char* s, unsigned n) { if (n > max_size()) { ptr = new char[n]; for (len = 0; len < n; ++len) ptr[len] = s[len]; ptr[len] = '\0'; } else { for (len = 0; len < n; ++len) buf[len] = s[len]; buf[len] = '\0'; } } It just doesn't allow assignment through the pointer.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 Jonathan Wakely changed: What|Removed |Added Target Milestone|--- |12.0
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |ASSIGNED Last reconfirmed||2021-11-17 Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #6 from Jonathan Wakely --- (In reply to Andrew Pinski from comment #3) > This could be an unimplemented feature in clang with respect to C++23 by the > way. It's supposed to work in C++20, nothing from 23 should be needed.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #5 from cqwrteur --- (In reply to Andrew Pinski from comment #3) > This could be an unimplemented feature in clang with respect to C++23 by the > way. The problem is that it has a silent undefined behavior in the code, the string does not give the union a storage, the lifetime of the sso buffer is not activated under constexpr context. (although a proposal is trying to fix that.)
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #4 from cqwrteur --- (In reply to Andrew Pinski from comment #3) > This could be an unimplemented feature in clang with respect to C++23 by the > way. Same code works with clang --target=x86_64-windows-msvc. D:\hg\fast_io\tests\0003.concat>clang++ -o constexpr_clang_msvcstl.exe constexpr.cc -Ofast -std=c++20 -s -flto -march=native -I../../include --target=x86_64-windows-msvc -fuse-ld=lld -D_DLL=1 -lmsvcrt
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #3 from Andrew Pinski --- This could be an unimplemented feature in clang with respect to C++23 by the way.
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 --- Comment #2 from cqwrteur --- *** Bug 103294 has been marked as a duplicate of this bug. ***
[Bug libstdc++/103295] constexpr std::string does not work for clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103295 cqwrteur changed: What|Removed |Added CC||unlvsur at live dot com --- Comment #1 from cqwrteur --- Created attachment 51821 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51821&action=edit clang error message