aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Martin <simon@nasilyan.com>2025-01-22 10:44:32 +0100
committerSimon Martin <simon@nasilyan.com>2025-01-22 10:47:30 +0100
commite13e751d8144c9cfb7a9f1cd38119d1fa4ab38cf (patch)
treeb3b738d71c578e9282d4c3353acf6d1b007fb0cf
parent8c93a8aa67f12c8e03eb7fd90f671a03ae46935b (diff)
downloadgcc-e13e751d8144c9cfb7a9f1cd38119d1fa4ab38cf.zip
gcc-e13e751d8144c9cfb7a9f1cd38119d1fa4ab38cf.tar.gz
gcc-e13e751d8144c9cfb7a9f1cd38119d1fa4ab38cf.tar.bz2
c++: Clear TARGET_EXPR_ELIDING_P when forced to use a copy constructor due to __no_unique_address__ [PR118199]
We currently fail with a checking assert upon the following valid code when using -fno-elide-constructors === cut here === struct d { ~d(); }; d &b(); struct f { [[__no_unique_address__]] d e; }; struct h : f { h() : f{b()} {} } i; === cut here === The problem is that split_nonconstant_init_1 detects that it cannot elide the copy constructor due to __no_unique_address__ but does not clear TARGET_EXPR_ELIDING_P, and due to -fno-elide-constructors, we trip on a checking assert in cp_gimplify_expr. This patch fixes this by making sure that we clear TARGET_EXPR_ELIDING_P if we determine that we have to keep the copy constructor due to __no_unique_address__. An alternative would be to just check for elide_constructors in that assert, but I think it'd lose most of its value if we did so. PR c++/118199 gcc/cp/ChangeLog: * typeck2.cc (split_nonconstant_init_1): Clear TARGET_EXPR_ELIDING_P if we need to use a copy constructor because of __no_unique_address__. gcc/testsuite/ChangeLog: * g++.dg/init/no-elide3.C: New test.
-rw-r--r--gcc/cp/typeck2.cc5
-rw-r--r--gcc/testsuite/g++.dg/init/no-elide3.C12
2 files changed, 17 insertions, 0 deletions
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index 15528ba..e88f6f0 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -655,6 +655,11 @@ split_nonconstant_init_1 (tree dest, tree init, bool last,
&& make_safe_copy_elision (sub, value))
goto build_init;
+ if (TREE_CODE (value) == TARGET_EXPR)
+ /* We have to add this constructor, so we will not
+ elide. */
+ TARGET_EXPR_ELIDING_P (value) = false;
+
tree name = (DECL_FIELD_IS_BASE (field_index)
? base_ctor_identifier
: complete_ctor_identifier);
diff --git a/gcc/testsuite/g++.dg/init/no-elide3.C b/gcc/testsuite/g++.dg/init/no-elide3.C
new file mode 100644
index 0000000..659eb19
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/no-elide3.C
@@ -0,0 +1,12 @@
+// PR c++/118199
+// { dg-do "compile" { target c++11 } }
+// { dg-options "-fno-elide-constructors" }
+
+struct d { ~d(); };
+d &b();
+struct f {
+ [[__no_unique_address__]] d e;
+};
+struct h : f {
+ h() : f{b()} {}
+} i;