[pushed] c++: using operator= [PR105223]

Message ID 20220412035728.2976497-1-jason@redhat.com
State Committed
Commit 4195fced8a13422db94e179404588d9d887a036a
Headers
Series [pushed] c++: using operator= [PR105223] |

Commit Message

Jason Merrill April 12, 2022, 3:57 a.m. UTC
  In a template class A we normally add an implicit using A::operator= as a
placeholder for the implicitly declared operator whose signature we don't
know yet.  In my patch for PR92918 I stopped doing that if the class has an
explicit operator=, but that was wrong; an operator= taking an unrelated
type doesn't prevent the implicit declaration.

When I was working on that patch, the change was necessary to avoid another
regression, but apparently it is no longer needed.

	PR c++/105223
	PR c++/92918

gcc/cp/ChangeLog:

	* class.cc (finish_struct): Always using op=.

gcc/testsuite/ChangeLog:

	* g++.dg/template/using31.C: New test.
---
 gcc/cp/class.cc                         | 19 ++++++++-----------
 gcc/testsuite/g++.dg/template/using31.C | 16 ++++++++++++++++
 2 files changed, 24 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/using31.C


base-commit: 6afb21b824dabf17c79e7b0a4230572f091307ec
  

Patch

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 40e17140db5..bfda0065bf4 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -7723,17 +7723,14 @@  finish_struct (tree t, tree attributes)
 	 lookup not to fail or recurse into bases.  This isn't added
 	 to the template decl list so we drop this at instantiation
 	 time.  */
-      if (!get_class_binding_direct (t, assign_op_identifier, false))
-	{
-	  tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
-					 NULL_TREE);
-	  DECL_CONTEXT (ass_op) = t;
-	  USING_DECL_SCOPE (ass_op) = t;
-	  DECL_DEPENDENT_P (ass_op) = true;
-	  DECL_ARTIFICIAL (ass_op) = true;
-	  DECL_CHAIN (ass_op) = TYPE_FIELDS (t);
-	  TYPE_FIELDS (t) = ass_op;
-	}
+      tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
+				     NULL_TREE);
+      DECL_CONTEXT (ass_op) = t;
+      USING_DECL_SCOPE (ass_op) = t;
+      DECL_DEPENDENT_P (ass_op) = true;
+      DECL_ARTIFICIAL (ass_op) = true;
+      DECL_CHAIN (ass_op) = TYPE_FIELDS (t);
+      TYPE_FIELDS (t) = ass_op;
 
       TYPE_SIZE (t) = bitsize_zero_node;
       TYPE_SIZE_UNIT (t) = size_zero_node;
diff --git a/gcc/testsuite/g++.dg/template/using31.C b/gcc/testsuite/g++.dg/template/using31.C
new file mode 100644
index 00000000000..bfeb94f2788
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using31.C
@@ -0,0 +1,16 @@ 
+// PR c++/105223
+
+struct ServiceReferenceBase {
+  void operator=(int);
+};
+
+template<class>
+struct ServiceReference : ServiceReferenceBase {
+  void foo() { operator=(0); }
+  using ServiceReferenceBase::operator=;
+};
+
+int main() {
+  ServiceReference<int> sr;
+  sr.foo();
+}