diff options
author | Jason Merrill <jason@redhat.com> | 2025-01-27 18:30:18 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2025-01-28 12:31:00 -0500 |
commit | d0f230adf0e888d9218a123ac620c9a5b3020c2d (patch) | |
tree | c657de3ee932d57a8fa58104c29ede7305be9674 /gcc/testsuite/g++.dg/cpp0x | |
parent | 0204dcf930b5093d0811a007b7f47aa42e55e787 (diff) | |
download | gcc-d0f230adf0e888d9218a123ac620c9a5b3020c2d.zip gcc-d0f230adf0e888d9218a123ac620c9a5b3020c2d.tar.gz gcc-d0f230adf0e888d9218a123ac620c9a5b3020c2d.tar.bz2 |
c++: init-list opt and lvalue initializers [PR118673]
When fn returns {extension}, the ArrayRef in the initializer_list is
constructed to point to 'extension', the variable with static storage
duration. The optimization was copying extension's value into a temporary
array and constructing the ArrayRef to point to that temporary copy instead,
resulting in a dangling pointer. So suppress this optimization if the
element constructor takes a reference and the initializer is a non-mergeable
lvalue.
PR c++/118673
gcc/cp/ChangeLog:
* call.cc (maybe_init_list_as_array): Check for lvalue
initializers.
* cp-tree.h (enum cp_lvalue_kind_flags): Add clk_mergeable.
* tree.cc (lvalue_kind): Return it.
(non_mergeable_glvalue_p): New.
(test_lvalue_kind): Adjust.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/initlist-opt6.C: New test.
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp0x')
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-opt6.C | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-opt6.C b/gcc/testsuite/g++.dg/cpp0x/initlist-opt6.C new file mode 100644 index 0000000..8019289 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-opt6.C @@ -0,0 +1,26 @@ +// PR c++/118673 +// { dg-do run { target c++11 } } + +#include <initializer_list> + +struct ArrayRef { + const int *Data = nullptr; + ArrayRef(const int &OneElt) : Data(&OneElt) {} +}; + +struct Vec +{ + ArrayRef Elts[1]; + Vec(std::initializer_list<ArrayRef> IL) + : Elts{*IL.begin()} + { } +}; + +[[gnu::noinline]] Vec fn() { + static const auto extension = 42; + return {extension}; +} +int main() { + auto t = fn(); + if (t.Elts[0].Data[0] != 42) __builtin_abort(); +} |