public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-2014] c++: [[no_unique_address]] fixes. [PR96105]
@ 2020-07-10 12:36 Jason Merrill
0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2020-07-10 12:36 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:e47dfca5aa473e77fdff95d631dc39de87a41eec
commit r11-2014-ge47dfca5aa473e77fdff95d631dc39de87a41eec
Author: Jason Merrill <jason@redhat.com>
Date: Thu Jul 9 15:11:12 2020 -0400
c++: [[no_unique_address]] fixes. [PR96105]
We were wrongly checking is_empty_class on the result of strip_array_types
rather than the actual field type. We weren't considering the alignment of
the data member. We needed to handle unions the same way as
layout_nonempty_base_or_field.
gcc/cp/ChangeLog:
PR c++/96105
PR c++/96052
PR c++/95976
* class.c (check_field_decls): An array of empty classes is not an
empty data member.
(layout_empty_base_or_field): Handle explicit alignment.
Fix union handling.
gcc/testsuite/ChangeLog:
PR c++/96105
PR c++/96052
PR c++/95976
* g++.dg/cpp2a/no_unique_address4.C: New test.
* g++.dg/cpp2a/no_unique_address5.C: New test.
* g++.dg/cpp2a/no_unique_address6.C: New test.
Diff:
---
gcc/cp/class.c | 27 ++++++++++++++++++-------
gcc/testsuite/g++.dg/cpp2a/no_unique_address4.C | 22 ++++++++++++++++++++
gcc/testsuite/g++.dg/cpp2a/no_unique_address5.C | 25 +++++++++++++++++++++++
gcc/testsuite/g++.dg/cpp2a/no_unique_address6.C | 25 +++++++++++++++++++++++
4 files changed, 92 insertions(+), 7 deletions(-)
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 7b5f1669d04..14380c7a08c 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3718,7 +3718,8 @@ check_field_decls (tree t, tree *access_decls,
/* We don't treat zero-width bitfields as making a class
non-empty. */
;
- else if (field_poverlapping_p (field) && is_empty_class (type))
+ else if (field_poverlapping_p (field)
+ && is_empty_class (TREE_TYPE (field)))
/* Empty data members also don't make a class non-empty. */
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
else
@@ -4385,15 +4386,20 @@ layout_empty_base_or_field (record_layout_info rli, tree binfo_or_decl,
/* This routine should only be used for empty classes. */
gcc_assert (is_empty_class (type));
- alignment = size_int (CLASSTYPE_ALIGN_UNIT (type));
+
+ if (decl && DECL_USER_ALIGN (decl))
+ alignment = size_int (DECL_ALIGN_UNIT (decl));
+ else
+ alignment = size_int (CLASSTYPE_ALIGN_UNIT (type));
/* This is an empty base class. We first try to put it at offset
zero. */
tree offset = size_zero_node;
- if (layout_conflict_p (type,
- offset,
- offsets,
- /*vbases_p=*/0))
+ if (TREE_CODE (rli->t) != UNION_TYPE
+ && layout_conflict_p (type,
+ offset,
+ offsets,
+ /*vbases_p=*/0))
{
/* That didn't work. Now, we move forward from the next
available spot in the class. */
@@ -4413,7 +4419,14 @@ layout_empty_base_or_field (record_layout_info rli, tree binfo_or_decl,
}
}
- if (CLASSTYPE_USER_ALIGN (type))
+ if (decl && DECL_USER_ALIGN (decl))
+ {
+ rli->record_align = MAX (rli->record_align, DECL_ALIGN (decl));
+ if (warn_packed)
+ rli->unpacked_align = MAX (rli->unpacked_align, DECL_ALIGN (decl));
+ TYPE_USER_ALIGN (rli->t) = 1;
+ }
+ else if (CLASSTYPE_USER_ALIGN (type))
{
rli->record_align = MAX (rli->record_align, CLASSTYPE_ALIGN (type));
if (warn_packed)
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address4.C b/gcc/testsuite/g++.dg/cpp2a/no_unique_address4.C
new file mode 100644
index 00000000000..2fe44e37163
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address4.C
@@ -0,0 +1,22 @@
+// PR c++/96105
+// { dg-do compile { target c++20 } }
+
+struct Empty {};
+
+struct A {
+ Empty emp [[no_unique_address]][3];
+};
+
+struct B : A {
+ float f;
+};
+
+struct C {
+ Empty emp [[no_unique_address]][3];
+ float f;
+};
+
+extern char szc[sizeof(C)];
+extern char szc[sizeof(float) * 2]; // GCC likes this
+extern char szb[sizeof(B)];
+extern char szb[sizeof(float) * 2]; // GCC does not like this
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address5.C b/gcc/testsuite/g++.dg/cpp2a/no_unique_address5.C
new file mode 100644
index 00000000000..5fca35dbd81
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address5.C
@@ -0,0 +1,25 @@
+// PR c++/96052
+// { dg-do compile { target c++20 } }
+
+struct Q {
+ struct {
+ } emp alignas(8) [[no_unique_address]];
+ char x;
+};
+struct QQ {
+ char x;
+ Q q;
+};
+
+struct Z {
+ char x alignas(8) [[no_unique_address]];
+};
+struct ZZ {
+ char x;
+ Z z;
+};
+
+extern char qx[sizeof(QQ)];
+extern char qx[16];
+extern char qz[sizeof(ZZ)];
+extern char qz[16];
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address6.C b/gcc/testsuite/g++.dg/cpp2a/no_unique_address6.C
new file mode 100644
index 00000000000..427db4439dd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address6.C
@@ -0,0 +1,25 @@
+// PR c++/95976
+// { dg-do compile { target c++20 } }
+
+struct empty {};
+
+union no_attribute_t
+{
+ empty _0;
+ empty _1;
+};
+
+union with_attribute_t
+{
+ [[no_unique_address]] empty _0;
+ [[no_unique_address]] empty _1;
+};
+
+constexpr no_attribute_t no_attribute{};
+constexpr with_attribute_t with_attribute{};
+
+// This succeeds
+static_assert( &no_attribute._0 == &no_attribute._1 );
+
+// This fails
+static_assert( &with_attribute._0 == &with_attribute._1 );
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-07-10 12:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-10 12:36 [gcc r11-2014] c++: [[no_unique_address]] fixes. [PR96105] Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).