The Go frontend used to erroneously permit the same function to be
declared multiple times.  This patch from Chris Manghane fixes that.
This fixes https://golang.org/issue/11573.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE     (revision 226527)
+++ gcc/go/gofrontend/MERGE     (working copy)
@@ -1,4 +1,4 @@
-2b1a79c6395991fc4e60e20312ff44065fdb816b
+7a6089333f4ab10449f9140c4639cfe741abcb25
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc   (revision 226527)
+++ gcc/go/gofrontend/gogo.cc   (working copy)
@@ -7408,16 +7408,10 @@ Bindings::new_definition(Named_object* o
 
     case Named_object::NAMED_OBJECT_FUNC_DECLARATION:
       {
-       Function_type* old_type = old_object->func_declaration_value()->type();
-       if (new_object->is_function_declaration())
-         {
-           Function_type* new_type =
-             new_object->func_declaration_value()->type();
-           if (old_type->is_valid_redeclaration(new_type, &reason))
-             return old_object;
-         }
        if (new_object->is_function())
          {
+            Function_type* old_type =
+                old_object->func_declaration_value()->type();
            Function_type* new_type = new_object->func_value()->type();
            if (old_type->is_valid_redeclaration(new_type, &reason))
              {
Index: gcc/go/gofrontend/parse.cc
===================================================================
--- gcc/go/gofrontend/parse.cc  (revision 226510)
+++ gcc/go/gofrontend/parse.cc  (working copy)
@@ -2231,9 +2231,11 @@ Parse::function_decl(bool saw_nointerfac
   std::string extern_name = this->lex_->extern_name();
   const Token* token = this->advance_token();
 
+  bool expected_receiver = false;
   Typed_identifier* rec = NULL;
   if (token->is_op(OPERATOR_LPAREN))
     {
+      expected_receiver = true;
       rec = this->receiver();
       token = this->peek_token();
     }
@@ -2304,7 +2306,8 @@ Parse::function_decl(bool saw_nointerfac
     {
       if (named_object == NULL && !Gogo::is_sink_name(name))
        {
-         if (fntype == NULL)
+         if (fntype == NULL
+              || (expected_receiver && rec == NULL))
            this->gogo_->add_erroneous_name(name);
          else
            {

Reply via email to