aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp0x
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2025-01-27 18:30:18 -0500
committerJason Merrill <jason@redhat.com>2025-01-28 12:31:00 -0500
commitd0f230adf0e888d9218a123ac620c9a5b3020c2d (patch)
treec657de3ee932d57a8fa58104c29ede7305be9674 /gcc/testsuite/g++.dg/cpp0x
parent0204dcf930b5093d0811a007b7f47aa42e55e787 (diff)
downloadgcc-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.C26
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();
+}