public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [pushed] c++: [[no_unique_address]] and cv-qualified type
@ 2023-09-06  3:19 Jason Merrill
  2023-09-18  3:36 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Jason Merrill @ 2023-09-06  3:19 UTC (permalink / raw)
  To: gcc-patches

Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

We were checking for overlap using same_type_p and therefore allocating two
Empty subobjects at the same offset because one was cv-qualified.

This gives the warning at the location of the class name rather than the
member declaration, but this should be a rare enough issue that it doesn't
seem worth trying to be more precise.

gcc/ChangeLog:

	* common.opt: Update -fabi-version=19.

gcc/cp/ChangeLog:

	* class.cc (check_subobject_offset): Check
	same_type_ignoring_top_level_qualifiers_p.

gcc/testsuite/ChangeLog:

	* g++.dg/abi/no_unique_address8.C: New test.
	* g++.dg/abi/no_unique_address8a.C: New test.
---
 gcc/common.opt                                |  1 +
 gcc/cp/class.cc                               | 28 +++++++++++++++--
 gcc/testsuite/g++.dg/abi/no_unique_address8.C | 30 ++++++++++++++++++
 .../g++.dg/abi/no_unique_address8a.C          | 31 +++++++++++++++++++
 4 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/abi/no_unique_address8.C
 create mode 100644 gcc/testsuite/g++.dg/abi/no_unique_address8a.C

diff --git a/gcc/common.opt b/gcc/common.opt
index 3e1939293e8..f137a1f81ac 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1011,6 +1011,7 @@ Driver Undocumented
 ;     Default in G++ 13.
 ;
 ; 19: Emits ABI tags if needed in structured binding mangled names.
+;     Ignores cv-quals on [[no_unique_object]] members.
 ;     Default in G++ 14.
 ;
 ; Additional positive integers will be assigned as new versions of
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 778759237dc..9139a0075ab 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -4053,9 +4053,33 @@ check_subobject_offset (tree type, tree offset, splay_tree offsets)
   if (!n)
     return 0;
 
+  enum { ignore, fast, slow, warn }
+  cv_check = (abi_version_crosses (19) ? slow
+	      : abi_version_at_least (19) ? fast
+	      : ignore);
   for (t = (tree) n->value; t; t = TREE_CHAIN (t))
-    if (same_type_p (TREE_VALUE (t), type))
-      return 1;
+    {
+      tree elt = TREE_VALUE (t);
+
+      if (same_type_p (elt, type))
+	return 1;
+
+      if (cv_check != ignore
+	  && same_type_ignoring_top_level_qualifiers_p (elt, type))
+	{
+	  if (cv_check == fast)
+	    return 1;
+	  cv_check = warn;
+	}
+    }
+
+  if (cv_check == warn)
+    {
+      warning (OPT_Wabi, "layout of %qs member of type %qT changes in %qs",
+	       "[[no_unique_address]]", type, "-fabi-version=19");
+      if (abi_version_at_least (19))
+	return 1;
+    }
 
   return 0;
 }
diff --git a/gcc/testsuite/g++.dg/abi/no_unique_address8.C b/gcc/testsuite/g++.dg/abi/no_unique_address8.C
new file mode 100644
index 00000000000..6aa2bba7810
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/no_unique_address8.C
@@ -0,0 +1,30 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-fabi-version=19 -Wabi=18" }
+
+#include <cstddef>
+
+#define NOUNIQUE [[no_unique_address]]
+
+struct Empty { };
+#define CHECK_DISTINCT(type, field1, field2) static_assert(offsetof(type, field1) != offsetof(type, field2))
+
+struct A1 {
+    NOUNIQUE Empty a;
+    Empty b;
+};
+CHECK_DISTINCT(A1, a, b);
+struct A2 {
+    NOUNIQUE const Empty a;
+    const Empty b;
+};
+CHECK_DISTINCT(A2, a, b);
+struct A3 {			// { dg-warning "layout" }
+    NOUNIQUE const Empty a;
+    Empty b;
+};
+CHECK_DISTINCT(A3, a, b);
+struct A4 {			// { dg-warning "layout" }
+    NOUNIQUE Empty a;
+    const Empty b;
+};
+CHECK_DISTINCT(A4, a, b);
diff --git a/gcc/testsuite/g++.dg/abi/no_unique_address8a.C b/gcc/testsuite/g++.dg/abi/no_unique_address8a.C
new file mode 100644
index 00000000000..c5d48088529
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/no_unique_address8a.C
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-fabi-version=18 -Wabi=19" }
+
+#include <cstddef>
+
+#define NOUNIQUE [[no_unique_address]]
+
+struct Empty { };
+#define CHECK_DISTINCT(type, field1, field2) static_assert(offsetof(type, field1) != offsetof(type, field2))
+#define CHECK_SAME(type, field1, field2) static_assert(offsetof(type, field1) == offsetof(type, field2))
+
+struct A1 {
+    NOUNIQUE Empty a;
+    Empty b;
+};
+CHECK_DISTINCT(A1, a, b);
+struct A2 {
+    NOUNIQUE const Empty a;
+    const Empty b;
+};
+CHECK_DISTINCT(A2, a, b);
+struct A3 {			// { dg-warning "layout" }
+    NOUNIQUE const Empty a;
+    Empty b;
+};
+CHECK_SAME(A3, a, b);
+struct A4 {			// { dg-warning "layout" }
+    NOUNIQUE Empty a;
+    const Empty b;
+};
+CHECK_SAME(A4, a, b);

base-commit: 244d1321340116b7780e78096356f69662fd0e18
-- 
2.39.3


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [pushed] c++: [[no_unique_address]] and cv-qualified type
  2023-09-06  3:19 [pushed] c++: [[no_unique_address]] and cv-qualified type Jason Merrill
@ 2023-09-18  3:36 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2023-09-18  3:36 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 624 bytes --]

On 9/5/23 23:19, Jason Merrill wrote:
> Tested x86_64-pc-linux-gnu, applying to trunk.
> 
> -- 8< --
> 
> We were checking for overlap using same_type_p and therefore allocating two
> Empty subobjects at the same offset because one was cv-qualified.
> 
> This gives the warning at the location of the class name rather than the
> member declaration, but this should be a rare enough issue that it doesn't
> seem worth trying to be more precise.

The ABI and language seem to be settling on referring to "similar types" 
here rather than same ignoring top-level cv-qualifiers.

Tested x86_64-pc-linux-gnu, applying to trunk.

[-- Attachment #2: 0001-c-overlapping-subobjects-tweak.patch --]
[-- Type: text/x-patch, Size: 848 bytes --]

From 3f65c1dc56f3a6dd4be85a064d0023b7be3fcd8a Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Tue, 12 Sep 2023 12:15:13 -0400
Subject: [PATCH] c++: overlapping subobjects tweak
To: gcc-patches@gcc.gnu.org

The ABI is settling on "similar" for this rule.

gcc/cp/ChangeLog:

	* class.cc (check_subobject_offset): Use similar_type_p.
---
 gcc/cp/class.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 9139a0075ab..d270dcbb14c 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -4065,7 +4065,7 @@ check_subobject_offset (tree type, tree offset, splay_tree offsets)
 	return 1;
 
       if (cv_check != ignore
-	  && same_type_ignoring_top_level_qualifiers_p (elt, type))
+	  && similar_type_p (elt, type))
 	{
 	  if (cv_check == fast)
 	    return 1;
-- 
2.39.3


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-09-18  3:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-06  3:19 [pushed] c++: [[no_unique_address]] and cv-qualified type Jason Merrill
2023-09-18  3:36 ` 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).