aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp0x
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-12-10 18:43:56 -0500
committerMarek Polacek <polacek@redhat.com>2024-12-19 11:07:18 -0500
commitfa99002538bc91c869f3b1fd9af7f14e410e1e1a (patch)
tree2e5eb34b71657d9c1c517c3da2a39be90bd8e5f8 /gcc/testsuite/g++.dg/cpp0x
parentfc95e8776cf4b11bbffc593167105883165b9e4c (diff)
downloadgcc-fa99002538bc91c869f3b1fd9af7f14e410e1e1a.zip
gcc-fa99002538bc91c869f3b1fd9af7f14e410e1e1a.tar.gz
gcc-fa99002538bc91c869f3b1fd9af7f14e410e1e1a.tar.bz2
c++: ICE in TARGET_EXPR evaluation in cp_fold_r [PR117980]
This ICE started with the recent prvalue optimization (r15-6052). In cp_fold_r we have: if (tree &init = TARGET_EXPR_INITIAL (stmt)) { cp_walk_tree (&init, cp_fold_r, data, NULL); // ... tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt)); What can happen here is that originally the TARGET_EXPR is: TARGET_EXPR <D.2747, <<< Unknown tree: aggr_init_expr 5 __ct_comp D.2747 (struct subrange *) <<< Unknown tree: void_cst >>> &TARGET_EXPR <D.2707, {.it=TARGET_EXPR <D.2695, ...>}> >>>> but after the first cp_walk_tree we fold the D.2707 TARGET_EXPR into: TARGET_EXPR <D.2707, <<< Unknown tree: expr_stmt D.2707.it = TARGET_EXPR <D.2695, ...> >>>> and then we pass the EXPR_STMT to maybe_constant_init, with D.2707 as the object. But their types don't match anymore, so we crash. We'd have to pass D.2707.it as the object for it to work. This patch adjusts cxx_eval_outermost_constant_expr to take the object's type if available. constexpr-prvalue3.C is reduced from a large std::ranges libstdc++ test. PR c++/117980 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): If there's an object to initialize, take its type. Don't set the type in the constexpr dtor case. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-prvalue2.C: New test. * g++.dg/cpp0x/constexpr-prvalue3.C: New test. Co-authored-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp0x')
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue2.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue3.C26
2 files changed, 41 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue2.C
new file mode 100644
index 0000000..4605323
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue2.C
@@ -0,0 +1,15 @@
+// PR c++/117980
+// { dg-do compile { target c++11 } }
+// { dg-options "-O" }
+
+struct S {
+ constexpr S(S &); // { dg-warning "used but never defined" }
+ ~S();
+};
+struct B {
+ S s;
+};
+struct A {
+ B b;
+};
+void fn(B b) { A{b}; }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue3.C
new file mode 100644
index 0000000..a2eb12c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue3.C
@@ -0,0 +1,26 @@
+// PR c++/117980
+// { dg-do compile { target c++11 } }
+// { dg-options "-O" }
+
+struct _Safe_iterator {
+ _Safe_iterator();
+ ~_Safe_iterator();
+};
+template <typename _Tp>
+struct vector {
+ vector(int) {}
+ constexpr _Safe_iterator end() {
+ return _Safe_iterator();
+ }
+};
+template <typename It> struct sentinel {
+ It it;
+};
+template <typename _Sent>
+struct subrange {
+ subrange(sentinel<_Safe_iterator>) {}
+};
+void test01() {
+ vector<int> v{0};
+ subrange<sentinel<_Safe_iterator>>{sentinel<_Safe_iterator>{v.end()}};
+}