Patchwork Go patch committed: Don't merge dot-import names

login
register
mail settings
Submitter Ian Taylor
Date July 20, 2014, 3:13 p.m.
Message ID <mcrmwc4jc5o.fsf@iant-glaptop.roam.corp.google.com>
Download mbox | patch
Permalink /patch/371932/
State New
Headers show

Comments

Ian Taylor - July 20, 2014, 3:13 p.m.
This patch to the Go frontend fixes it so that a name included because
of a dot import (import . "package") is not merged with the same name
defined in an earlier file.  Without this patch, the Go compiler would
incorrectly accept code that used a name defined by a dot import in a
later file.  I've sent out a change to add a test to the master
testsuite: http://codereview.appspot.com/118000043 .  For this patch,
bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

Patch

diff -r 0e313c250b05 go/gogo.cc
--- a/go/gogo.cc	Sun Jul 20 08:08:44 2014 -0700
+++ b/go/gogo.cc	Sun Jul 20 08:11:43 2014 -0700
@@ -473,7 +473,7 @@ 
 		 bindings->begin_declarations();
 	       p != bindings->end_declarations();
 	       ++p)
-	    this->add_named_object(p->second);
+	    this->add_dot_import_object(p->second);
 	}
       else if (ln == "_")
 	package->set_uses_sink_alias();
@@ -1968,11 +1968,32 @@ 
   return Named_object::make_sink();
 }
 
-// Add a named object.
+// Add a named object for a dot import.
 
 void
-Gogo::add_named_object(Named_object* no)
-{
+Gogo::add_dot_import_object(Named_object* no)
+{
+  // If the name already exists, then it was defined in some file seen
+  // earlier.  If the earlier name is just a declaration, don't add
+  // this name, because that will cause the previous declaration to
+  // merge to this imported name, which should not happen.  Just add
+  // this name to the list of file block names to get appropriate
+  // errors if we see a later definition.
+  Named_object* e = this->package_->bindings()->lookup(no->name());
+  if (e != NULL && e->package() == NULL)
+    {
+      if (e->is_unknown())
+	e = e->resolve();
+      if (e->package() == NULL
+	  && (e->is_type_declaration()
+	      || e->is_function_declaration()
+	      || e->is_unknown()))
+	{
+	  this->add_file_block_name(no->name(), no->location());
+	  return;
+	}
+    }
+
   this->current_bindings()->add_named_object(no);
 }
 
diff -r 0e313c250b05 go/gogo.h
--- a/go/gogo.h	Sun Jul 20 08:08:44 2014 -0700
+++ b/go/gogo.h	Sun Jul 20 08:11:43 2014 -0700
@@ -397,7 +397,7 @@ 
   // Add a named object to the current namespace.  This is used for
   // import . "package".
   void
-  add_named_object(Named_object*);
+  add_dot_import_object(Named_object*);
 
   // Add an identifier to the list of names seen in the file block.
   void
diff -r 0e313c250b05 go/import.cc
--- a/go/import.cc	Sun Jul 20 08:08:44 2014 -0700
+++ b/go/import.cc	Sun Jul 20 08:11:43 2014 -0700
@@ -431,7 +431,7 @@ 
   Typed_identifier tid(name, type, this->location_);
   Named_object* no = this->package_->add_constant(tid, expr);
   if (this->add_to_globals_)
-    this->gogo_->add_named_object(no);
+    this->gogo_->add_dot_import_object(no);
 }
 
 // Import a type.
@@ -464,7 +464,7 @@ 
   Named_object* no;
   no = this->package_->add_variable(name, var);
   if (this->add_to_globals_)
-    this->gogo_->add_named_object(no);
+    this->gogo_->add_dot_import_object(no);
 }
 
 // Import a function into PACKAGE.  PACKAGE is normally
@@ -518,7 +518,7 @@ 
     {
       no = package->add_function_declaration(name, fntype, loc);
       if (this->add_to_globals_)
-	this->gogo_->add_named_object(no);
+	this->gogo_->add_dot_import_object(no);
     }
   return no;
 }
diff -r 0e313c250b05 go/unsafe.cc
--- a/go/unsafe.cc	Sun Jul 20 08:08:44 2014 -0700
+++ b/go/unsafe.cc	Sun Jul 20 08:11:43 2014 -0700
@@ -66,7 +66,7 @@ 
   fntype->set_is_builtin();
   no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
   if (add_to_globals)
-    this->add_named_object(no);
+    this->add_dot_import_object(no);
 
   // Offsetof.
   results = new Typed_identifier_list;
@@ -76,7 +76,7 @@ 
   fntype->set_is_builtin();
   no = bindings->add_function_declaration("Offsetof", package, fntype, bloc);
   if (add_to_globals)
-    this->add_named_object(no);
+    this->add_dot_import_object(no);
 
   // Alignof.
   results = new Typed_identifier_list;
@@ -86,7 +86,7 @@ 
   fntype->set_is_builtin();
   no = bindings->add_function_declaration("Alignof", package, fntype, bloc);
   if (add_to_globals)
-    this->add_named_object(no);
+    this->add_dot_import_object(no);
 
   if (!this->imported_unsafe_)
     {