Go patch committed: Permit duplicate methods from embedded interfaces

Message ID CAOyqgcUPNzHNT6rX94yaiJ3UysgsmvM9PfymBYgZtwMrYFeTRw@mail.gmail.com
State New
Headers show
Series
  • Go patch committed: Permit duplicate methods from embedded interfaces
Related show

Commit Message

Ian Lance Taylor Jan. 10, 2020, 2:27 p.m.
This patch to the Go frontend permits duplicate methods from embedded
interfaces.  This is a language change for Go 1.14.  Bootstrapped and
ran Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 280085)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-92ee4c2e295fc760105f187f6ea6dc65c81fa892
+98c4c21b52afd6384f9364527bd7f5f9a1c752cf
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 279848)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -8943,8 +8943,12 @@  Interface_type::finalize_methods()
 	  continue;
 	}
 
+      const Typed_identifier_list* imethods = it->parse_methods_;
+      if (imethods == NULL)
+	continue;
+
       Named_type* nt = t->named_type();
-      if (nt != NULL && it->parse_methods_ != NULL)
+      if (nt != NULL)
 	{
 	  std::vector<Named_type*>::const_iterator q;
 	  for (q = seen.begin(); q != seen.end(); ++q)
@@ -8960,22 +8964,26 @@  Interface_type::finalize_methods()
 	  seen.push_back(nt);
 	}
 
-      const Typed_identifier_list* imethods = it->parse_methods_;
-      if (imethods == NULL)
-	continue;
       for (Typed_identifier_list::const_iterator q = imethods->begin();
 	   q != imethods->end();
 	   ++q)
 	{
 	  if (q->name().empty())
 	    inherit.push_back(*q);
-	  else if (this->find_method(q->name()) == NULL)
-	    this->all_methods_->push_back(Typed_identifier(q->name(),
-							   q->type(), tl));
 	  else
-	    go_error_at(tl, "inherited method %qs is ambiguous",
-		     Gogo::message_name(q->name()).c_str());
+	    {
+	      const Typed_identifier* oldm = this->find_method(q->name());
+	      if (oldm == NULL)
+		this->all_methods_->push_back(Typed_identifier(q->name(),
+							       q->type(), tl));
+	      else if (!Type::are_identical(q->type(), oldm->type(),
+					    Type::COMPARE_TAGS, NULL))
+		go_error_at(tl, "duplicate method %qs",
+			    Gogo::message_name(q->name()).c_str());
+	    }
 	}
+
+      seen.pop_back();
     }
 
   if (!this->all_methods_->empty())
Index: gcc/testsuite/go.test/test/fixedbugs/bug211.go
===================================================================
--- gcc/testsuite/go.test/test/fixedbugs/bug211.go	(revision 279815)
+++ gcc/testsuite/go.test/test/fixedbugs/bug211.go	(nonexistent)
@@ -1,14 +0,0 @@ 
-// errorcheck
-
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-type R interface { duplicate() }
-type S interface { duplicate() }
-type T interface { R; S }	// ERROR "duplicate"
-
-func main() {
-}
Index: gcc/testsuite/go.test/test/fixedbugs/bug251.go
===================================================================
--- gcc/testsuite/go.test/test/fixedbugs/bug251.go	(revision 279815)
+++ gcc/testsuite/go.test/test/fixedbugs/bug251.go	(working copy)
@@ -1,18 +1,18 @@ 
 // errorcheck
 
-// Copyright 2010 The Go Authors.  All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 package main
 
-type I1 interface {
+type I1 interface { // GC_ERROR "invalid recursive type"
 	m() I2
 	I2 // GCCGO_ERROR "loop|interface"
 }
 
 type I2 interface {
-	I1 // ERROR "loop|interface"
+	I1 // GCCGO_ERROR "loop|interface"
 }