Re: [pushed] c++: [[no_unique_address]] and cv-qualified type

2023-09-17 Thread Jason Merrill via Gcc-patches

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.
From 3f65c1dc56f3a6dd4be85a064d0023b7be3fcd8a Mon Sep 17 00:00:00 2001
From: Jason Merrill 
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



[pushed] c++: [[no_unique_address]] and cv-qualified type

2023-09-05 Thread Jason Merrill via 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 000..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 
+
+#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 000..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 
+
+#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