aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-03-04 12:08:42 -0500
committerJason Merrill <jason@redhat.com>2020-03-04 17:32:10 -0500
commit6876b269bc7fe6465fedfed87c31e6175992129f (patch)
tree932e196928b06bdf75240404f18593556310a575
parent10bbbb591cfe6cac200e926a73f3b8065147ce84 (diff)
c++: Fix [[no_unique_address]] and default mem-init [PR90432]
output_constructor doesn't like two consecutive entries with fields at the same position; let's avoid adding the one for the empty field. gcc/cp/ChangeLog 2020-03-04 Jason Merrill <jason@redhat.com> PR c++/90432 * init.c (perform_member_init): Don't do aggregate initialization of empty field. * constexpr.c (cx_check_missing_mem_inits): Don't enforce initialization of empty field.
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/constexpr.c3
-rw-r--r--gcc/cp/init.c5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/no_unique_address3.C16
4 files changed, 32 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 34ff88ee033..254e5a31096 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2020-03-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/90432
+ * init.c (perform_member_init): Don't do aggregate initialization of
+ empty field.
+ * constexpr.c (cx_check_missing_mem_inits): Don't enforce
+ initialization of empty field.
+
2020-03-04 Martin Liska <mliska@suse.cz>
* method.c: Wrap array in ctor with braces in order
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index c2d44605764..521c87f6210 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -831,6 +831,9 @@ cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
/* A flexible array can't be intialized here, so don't complain
that it isn't. */
continue;
+ if (DECL_SIZE (field) && integer_zerop (DECL_SIZE (field)))
+ /* An empty field doesn't need an initializer. */
+ continue;
ftype = strip_array_types (ftype);
if (type_has_constexpr_default_constructor (ftype))
{
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 61ed3aa7e93..27623cf4db1 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -865,6 +865,11 @@ perform_member_init (tree member, tree init)
}
if (init == error_mark_node)
return;
+ if (DECL_SIZE (member) && integer_zerop (DECL_SIZE (member))
+ && !TREE_SIDE_EFFECTS (init))
+ /* Don't add trivial initialization of an empty base/field, as they
+ might not be ordered the way the back-end expects. */
+ return;
/* A FIELD_DECL doesn't really have a suitable lifetime, but
make_temporary_var_for_ref_to_temp will treat it as automatic and
set_up_extended_ref_temp wants to use the decl in a warning. */
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address3.C b/gcc/testsuite/g++.dg/cpp2a/no_unique_address3.C
new file mode 100644
index 00000000000..07108b8b715
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address3.C
@@ -0,0 +1,16 @@
+// PR c++/90432
+// { dg-do compile { target c++11 } }
+
+struct empty {};
+
+struct has_empty {
+ [[no_unique_address]] empty brace_or_equal_initialized{};
+};
+
+struct has_value {
+ int non_zero = 1;
+};
+
+struct pair : has_empty, has_value {};
+
+pair a;