[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 --- Comment #9 from Jonathan Wakely --- Odd, I thought I'd checked it when testing r14-4334-g28adad7a32ed92. Seems like the same issue as PR 112642 though (which has a minimized version without std::string).
[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 --- Comment #8 from Patrick Palka --- It seems the comment #4 testcase is still rejected on trunk after/despite r14-4334-g28adad7a32ed92?
[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 --- Comment #7 from Jonathan Wakely --- That bug in comment 6 has already been fixed in gcc-12.3, by the last patch for PR 103295. The one in comment 4 is different, and will be fixed by Nathaniel's latest patch: https://gcc.gnu.org/pipermail/gcc-patches/2023-September/631642.html
[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 --- Comment #6 from danakj at orodu dot net --- In case it is of help, here's an even smaller repro that clang reports the error in libstdc++. For whatever reason gcc does not notice the libstdc++ bug here. https://gcc.godbolt.org/z/Phndafeoe ``` #include struct S { constexpr ~S() {} std::string s; }; constexpr std::string foo(const S& s) { return s.s; } static_assert(foo(S("hi")) == "hi"); // Fails. static_assert(foo(S("a longer string works")) == "a longer string works"); int main() {} ``` The error: ``` :11:15: error: static assertion expression is not an integral constant expression static_assert(foo(S("hi")) == "hi"); ^~~~ /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/basic_string.h:356:10: note: assignment to member '_M_local_buf' of union with no active member is not allowed in a constant expression __c = _CharT(); ^ /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/basic_string.tcc:229:4: note: in call to '(("hi")).s->_M_use_local_data()' _M_use_local_data(); ^ /opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/basic_string.h:642:2: note: in call to '(("hi")).s->_M_construct(&"hi"[0], &"hi"[2], {{}})' _M_construct(__s, __end, forward_iterator_tag()); ^ :11:21: note: in call to 'basic_string(&"hi"[0], std::allocator())' static_assert(foo(S("hi")) == "hi"); ^ 1 error generated. ```
[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 --- Comment #5 from danakj at orodu dot net --- As a means to work around #4 in static asserts, making your string long enough that it avoids the SSO will allow the compiler to accept it.
[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 --- Comment #4 from danakj at orodu dot net --- Here's a repro without the std::string inside a union. It is the SSO union inside the string that causes the error. https://gcc.godbolt.org/z/T8oM8vYnq ``` #include template constexpr T fold(T init, I i, S s, F f) { while (true) { if (i == s) return init; else init = f(std::move(init), *i++); } } constexpr char v[] = {'a', 'b', 'c'}; static_assert(fold(std::string(), std::begin(v), std::end(v), [](std::string acc, char v) { acc.push_back(v); return acc; }) == "abc"); int main() {} ``` :18:23: error: non-constant condition for static assertion 14 | static_assert(fold(std::string(), std::begin(v), std::end(v), | ~~~ 15 |[](std::string acc, char v) { |~ 16 |acc.push_back(v); |~ 17 |return acc; |~~~ 18 |}) == "abc"); |~~~^~~~ :18:32: in 'constexpr' expansion of 'fold(T, I, S, F) [with T = std::__cxx11::basic_string; I = const char*; S = const char*; F = ](std::begin(v), std::end(v), ((), ()))' :18:32: in 'constexpr' expansion of 'std::__cxx11::basic_string((* & std::move<__cxx11::basic_string&>(init)))' :18:23: error: accessing 'std::__cxx11::basic_string_M_allocated_capacity' member instead of initialized 'std::__cxx11::basic_string_M_local_buf' member in constant expression ASM generation compiler returned: 1
[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 Andrew Pinski changed: What|Removed |Added CC||danakj at orodu dot net --- Comment #3 from Andrew Pinski --- *** Bug 110900 has been marked as a duplicate of this bug. ***
[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 Patrick Palka changed: What|Removed |Added CC||ppalka at gcc dot gnu.org See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=110245 --- Comment #2 from Patrick Palka --- It works if we activate the union's member: constexpr bool f() { union U{ std::string s = {}; constexpr ~U(){ s.~basic_string(); } } u{}; return true; } static_assert( f() ); So perhaps this is a dup of PR110245?
[Bug c++/110158] Cannot use union with std::string inside in constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110158 --- Comment #1 from Andrew Pinski --- Here is a slightly reduced testcase (for a slightly different issue still dealing with unions): ``` struct str1 { // bool a; char *var; union { char t[15]; int allocated; }; constexpr str1() : var(new char[2]) { t[0] = 0; } constexpr ~str1() {if (var != t) delete[] var; } }; typedef str1 str; constexpr bool f1() { str t{}; return true; } static_assert( f1() ); constexpr bool f() { union U{ str s; constexpr ~U(){ s.~str(); } } u{}; return true; } static_assert( f() ); ```