* [Bug libstdc++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
@ 2023-11-20 15:35 ` redi at gcc dot gnu.org
2023-11-20 16:02 ` redi at gcc dot gnu.org
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-20 15:35 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |rejects-valid
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
Last reconfirmed| |2023-11-20
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I think the libstdc++ code is fine here, suggesting a compiler bug.
Slightly reduced:
#include <string>
#include <vector>
using namespace std;
using namespace std::literals;
struct Fold
{
template<typename _Iter, typename _Sent, typename _Tp, typename _Fp>
constexpr auto
operator()(_Iter, _Sent, _Tp __init, _Fp) const
{
return std::move(__init);
}
template<typename _Range, typename _Tp, typename _Fp>
constexpr auto
operator()(_Range&& __r, _Tp __init, _Fp __f) const
{ return (*this)(__r.begin(), __r.end(), std::move(__init),
std::move(__f)); }
} fold;
constexpr auto foo() {
const auto vec = vector{ "a"s, "b"s, "c"s };
return fold(vec, ""s, plus{});
}
constexpr auto bar() {
return foo().size();
}
int main() {
constexpr auto _ = bar();
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug libstdc++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
2023-11-20 15:35 ` [Bug libstdc++/112642] " redi at gcc dot gnu.org
@ 2023-11-20 16:02 ` redi at gcc dot gnu.org
2023-11-20 16:50 ` miro.palmu at helsinki dot fi
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-20 16:02 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Further reduced:
#include <string>
using namespace std::literals;
template<typename T>
constexpr auto
fold2(T init)
{ return std::move(init); }
template<typename T>
constexpr auto
fold(T init)
{ return fold2(std::move(init)); }
constexpr auto foo() {
return fold(""s);
}
constexpr auto bar() {
return foo().size();
}
int main() {
constexpr auto i = bar();
return i;
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug libstdc++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
2023-11-20 15:35 ` [Bug libstdc++/112642] " redi at gcc dot gnu.org
2023-11-20 16:02 ` redi at gcc dot gnu.org
@ 2023-11-20 16:50 ` miro.palmu at helsinki dot fi
2023-11-20 17:10 ` [Bug c++/112642] " redi at gcc dot gnu.org
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: miro.palmu at helsinki dot fi @ 2023-11-20 16:50 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
--- Comment #3 from Miro Palmu <miro.palmu at helsinki dot fi> ---
Further reduced:
#include <string>
using namespace std::literals;
consteval void bar() {
auto _ = [](auto s) { return s; }(""s);
}
int main() {
bar();
return 0;
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug c++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
` (2 preceding siblings ...)
2023-11-20 16:50 ` miro.palmu at helsinki dot fi
@ 2023-11-20 17:10 ` redi at gcc dot gnu.org
2023-11-21 17:48 ` miro.palmu at helsinki dot fi
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-20 17:10 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|libstdc++ |c++
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Or:
#include <string>
consteval void bar() {
auto _ = [](std::string s) { return s; }({});
}
int main() {
bar();
}
Or:
#include <string>
constexpr auto foo(std::string init) { return init; }
constexpr auto bar() { return foo("").size(); }
constexpr auto i = bar();
Clang compiles both of these without problems (it can't compile anything using
""s in a constant expression, maybe due to
https://github.com/llvm/llvm-project/issues/68527)
So I am pretty sure this is a g++ front end bug.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug c++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
` (3 preceding siblings ...)
2023-11-20 17:10 ` [Bug c++/112642] " redi at gcc dot gnu.org
@ 2023-11-21 17:48 ` miro.palmu at helsinki dot fi
2023-11-21 20:14 ` redi at gcc dot gnu.org
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: miro.palmu at helsinki dot fi @ 2023-11-21 17:48 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
--- Comment #5 from Miro Palmu <miro.palmu at helsinki dot fi> ---
I have been trying to figure out where exactly the bug is and these are my
findings.
> Or:
>
> #include <string>
>
> consteval void bar() {
> auto _ = [](std::string s) { return s; }({});
> }
>
> int main() {
> bar();
> }
>
> Or:
>
> #include <string>
> constexpr auto foo(std::string init) { return init; }
> constexpr auto bar() { return foo("").size(); }
> constexpr auto i = bar();
>
>Clang compiles both of these without problems (it can't compile anything using ""s in a constant expression, maybe due to https://github.com/llvm/llvm-project/issues/68527)
>
> So I am pretty sure this is a g++ front end bug.
If you use libstdc++ on clang these will not compile but with different errors.
Then with following example I try to showcase the bug without std::string.
Try it out: https://godbolt.org/z/rvoeMEaxc
This is bare minimum of libstdc++ basic_string to reproduce this bug:
---
struct S {
union {
char a[1];
};
char* ptr;
constexpr S() : ptr{a} {
a[0] = {};
}
constexpr S(S&&) = delete;
constexpr S(const S&) = delete;
constexpr S operator=(S&&) = delete;
constexpr S operator=(const S&) = delete;
constexpr ~S() = default;
}
---
Then to reproduce the bug instance of this class has to be function parameter
and the function has to be constant evaluated.
This can happens in std::basic_string move constructor bits/basic_string.h:682
and following tester functions tries to emulate what happens in it.
---
// Should always be false
constexpr bool test(const S& s){
return s.ptr != s.a;
}
consteval void tester1(S param = {}) {
S notparam = {};
if (test(notparam)){
throw std::logic_error("compiletime notparam!");
}
if (test(param)) {
// gcc ends up here so fails to compile
// in std::basic_string move constructor
// compilation would fail due to accessing
// inactive union member
// clang and msvc never end up here
throw std::logic_error("compiletime param");
}
}
int main() { tester(); )
---
Notice that here only the parameter version fails.
In non-constant evaluated context (see godbolt link)
all of the test evaluate false as they should.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug c++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
` (4 preceding siblings ...)
2023-11-21 17:48 ` miro.palmu at helsinki dot fi
@ 2023-11-21 20:14 ` redi at gcc dot gnu.org
2023-11-22 11:22 ` miro.palmu at helsinki dot fi
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-21 20:14 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Miro Palmu from comment #5)
> If you use libstdc++ on clang these will not compile but with different
> errors.
The examples in comment 4 do compile using libstdc++ on clang, if you use
libstdc++ headers from after sept 29 (for trunk) or oct 21 (for gcc-13).
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug c++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
` (5 preceding siblings ...)
2023-11-21 20:14 ` redi at gcc dot gnu.org
@ 2023-11-22 11:22 ` miro.palmu at helsinki dot fi
2023-11-22 12:04 ` redi at gcc dot gnu.org
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: miro.palmu at helsinki dot fi @ 2023-11-22 11:22 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
--- Comment #7 from Miro Palmu <miro.palmu at helsinki dot fi> ---
(In reply to Jonathan Wakely from comment #6)
> The examples in comment 4 do compile using libstdc++ on clang, if you use
> libstdc++ headers from after sept 29 (for trunk) or oct 21 (for gcc-13).
I was testing this on compiler explorer on clang 17.0.1 and it used gcc-13.2.0
libstdc++. Also tried it locally with clang 16.0.6 with gcc-13.2.1 libstdc++
Output:
$ cat prog.cpp
#include <string>
#include <utility>
int main() {
[](std::string s = {}) consteval {
std::string ss{ std::move(s) };
}();
}
$ clang prog.cpp -std=c++2b -stdlib=libstdc++
prog.cpp:4:5: error: call to consteval function 'main()::(anonymous
class)::operator()' is not a constant expression
[](std::string s = {}) consteval {
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/stl_construct.h:97:14:
note: construction of subobject of member '_M_local_buf' of union with no
active member is not allowed in a constant expression
{ return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); }
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/char_traits.h:272:6:
note: in call to 'construct_at(&ss.._M_local_buf[0], s.._M_local_buf[0])'
std::construct_at(__s1 + __i, __s2[__i]);
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/char_traits.h:443:11:
note: in call to 'copy(&ss.._M_local_buf[0], &s.._M_local_buf[0], 1)'
return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/basic_string.h:672:6:
note: in call to 'copy(&ss.._M_local_buf[0], &s.._M_local_buf[0], 1)'
traits_type::copy(_M_local_buf, __str._M_local_buf,
^
prog.cpp:5:21: note: in call to 'basic_string(s)'
std::string ss{ std::move(s) };
^
prog.cpp:4:5: note: in call to '&[](std::string s) {
std::string ss{std::move(s)};
}->operator()({{{{}}, &s.._M_local_buf[0]}, 0, {._M_local_buf = {0, 0, 0, 0, 0,
0, 0, 0, 0, 0, ...}}})'
[](std::string s = {}) consteval {
^
1 error generated.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug c++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
` (6 preceding siblings ...)
2023-11-22 11:22 ` miro.palmu at helsinki dot fi
@ 2023-11-22 12:04 ` redi at gcc dot gnu.org
2023-11-22 12:31 ` miro.palmu at helsinki dot fi
2023-11-22 17:19 ` redi at gcc dot gnu.org
9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-22 12:04 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Miro Palmu from comment #7)
> (In reply to Jonathan Wakely from comment #6)
> > The examples in comment 4 do compile using libstdc++ on clang, if you use
> > libstdc++ headers from after sept 29 (for trunk) or oct 21 (for gcc-13).
>
> I was testing this on compiler explorer on clang 17.0.1 and it used
> gcc-13.2.0 libstdc++.
Which is expected to fail, because 13.2.0 was released before Oct 21.
> Also tried it locally with clang 16.0.6 with
> gcc-13.2.1 libstdc++
Which gcc-13.2.1 though? That's a snapshot that could date from any time in the
past four months. If I use gcc version 13.2.1 20231025 then clang compiles it.
Anyway, the original GCC error is the same as PR 112642 which was apparently
reduced to PR 111284, which does seem relevant.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug c++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
` (7 preceding siblings ...)
2023-11-22 12:04 ` redi at gcc dot gnu.org
@ 2023-11-22 12:31 ` miro.palmu at helsinki dot fi
2023-11-22 17:19 ` redi at gcc dot gnu.org
9 siblings, 0 replies; 11+ messages in thread
From: miro.palmu at helsinki dot fi @ 2023-11-22 12:31 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
--- Comment #9 from Miro Palmu <miro.palmu at helsinki dot fi> ---
(In reply to Jonathan Wakely from comment #8)
> > Also tried it locally with clang 16.0.6 with
> > gcc-13.2.1 libstdc++
>
> Which gcc-13.2.1 though? That's a snapshot that could date from any time in
> the past four months. If I use gcc version 13.2.1 20231025 then clang
> compiles it.
Mine is 13.2.1 20230801 so way before Oct 21. (I did not know there were
different snapshots of the releases, I'm just a user trying to help :) )
> Anyway, the original GCC error is the same as PR 112642
You probably mean PR 110158
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug c++/112642] ranges::fold_left tries to access inactive union member of string in constant expression
2023-11-20 15:28 [Bug libstdc++/112642] New: ranges::fold_left tries to access inactive union member of string in constant expression miro.palmu at helsinki dot fi
` (8 preceding siblings ...)
2023-11-22 12:31 ` miro.palmu at helsinki dot fi
@ 2023-11-22 17:19 ` redi at gcc dot gnu.org
9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2023-11-22 17:19 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112642
--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Miro Palmu from comment #9)
> Mine is 13.2.1 20230801 so way before Oct 21. (I did not know there were
> different snapshots of the releases, I'm just a user trying to help :) )
13.2.1 (and any x.y.1 version) is not a release, it's a snapshot made from a
branch between releases. See https://gcc.gnu.org/develop.html#num_scheme or
more details.
Releases end with a .0 number.
> > Anyway, the original GCC error is the same as PR 112642
>
> You probably mean PR 110158
Oops! I meant PR 111258
^ permalink raw reply [flat|nested] 11+ messages in thread