[Bug c++/110158] Cannot use union with std::string inside in constant expression

2023-11-22 Thread redi at gcc dot gnu.org via Gcc-bugs
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

2023-11-21 Thread ppalka at gcc dot gnu.org via Gcc-bugs
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

2023-09-29 Thread redi at gcc dot gnu.org via Gcc-bugs
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

2023-09-06 Thread danakj at orodu dot net via Gcc-bugs
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

2023-09-06 Thread danakj at orodu dot net via Gcc-bugs
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

2023-08-04 Thread danakj at orodu dot net via Gcc-bugs
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

2023-08-04 Thread pinskia at gcc dot gnu.org via Gcc-bugs
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

2023-08-03 Thread ppalka at gcc dot gnu.org via Gcc-bugs
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

2023-06-07 Thread pinskia at gcc dot gnu.org via Gcc-bugs
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() );

```