This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Check for duplicate parameter/result names


This patch to the Go frontend checks for duplicate parameter/result
names in function declarations and interface method signatures.
Previously I only checked for duplicates in function definitions.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

diff -r 3311f9829d03 go/gogo.cc
--- a/go/gogo.cc	Tue Sep 20 08:48:07 2011 -0700
+++ b/go/gogo.cc	Tue Sep 20 09:43:58 2011 -0700
@@ -4482,6 +4482,12 @@
 
     case Named_object::NAMED_OBJECT_VAR:
     case Named_object::NAMED_OBJECT_RESULT_VAR:
+      // We have already given an error in the parser for cases where
+      // one parameter or result variable redeclares another one.
+      if ((new_object->is_variable()
+	   && new_object->var_value()->is_parameter())
+	  || new_object->is_result_variable())
+	return old_object;
       break;
 
     case Named_object::NAMED_OBJECT_SINK:
diff -r 3311f9829d03 go/parse.cc
--- a/go/parse.cc	Tue Sep 20 08:48:07 2011 -0700
+++ b/go/parse.cc	Tue Sep 20 09:43:58 2011 -0700
@@ -677,6 +677,32 @@
   return Type::make_channel_type(send, receive, element_type);
 }
 
+// Give an error for a duplicate parameter or receiver name.
+
+void
+Parse::check_signature_names(const Typed_identifier_list* params,
+			     Parse::Names* names)
+{
+  for (Typed_identifier_list::const_iterator p = params->begin();
+       p != params->end();
+       ++p)
+    {
+      if (p->name().empty() || Gogo::is_sink_name(p->name()))
+	continue;
+      std::pair<std::string, const Typed_identifier*> val =
+	std::make_pair(p->name(), &*p);
+      std::pair<Parse::Names::iterator, bool> ins = names->insert(val);
+      if (!ins.second)
+	{
+	  error_at(p->location(), "redefinition of %qs",
+		   Gogo::message_name(p->name()).c_str());
+	  inform(ins.first->second->location(),
+		 "previous definition of %qs was here",
+		 Gogo::message_name(p->name()).c_str());
+	}
+    }
+}
+
 // Signature      = Parameters [ Result ] .
 
 // RECEIVER is the receiver if there is one, or NULL.  LOCATION is the
@@ -691,18 +717,24 @@
   Typed_identifier_list* params;
   bool params_ok = this->parameters(&params, &is_varargs);
 
-  Typed_identifier_list* result = NULL;
+  Typed_identifier_list* results = NULL;
   if (this->peek_token()->is_op(OPERATOR_LPAREN)
       || this->type_may_start_here())
     {
-      if (!this->result(&result))
+      if (!this->result(&results))
 	return NULL;
     }
 
   if (!params_ok)
     return NULL;
 
-  Function_type* ret = Type::make_function_type(receiver, params, result,
+  Parse::Names names;
+  if (params != NULL)
+    this->check_signature_names(params, &names);
+  if (results != NULL)
+    this->check_signature_names(results, &names);
+
+  Function_type* ret = Type::make_function_type(receiver, params, results,
 						location);
   if (is_varargs)
     ret->set_is_varargs();
diff -r 3311f9829d03 go/parse.h
--- a/go/parse.h	Tue Sep 20 08:48:07 2011 -0700
+++ b/go/parse.h	Tue Sep 20 09:43:58 2011 -0700
@@ -131,6 +131,9 @@
   // A set of Enclosing_var entries.
   typedef std::set<Enclosing_var, Enclosing_var_comparison> Enclosing_vars;
 
+  // Used to detect duplicate parameter/result names.
+  typedef std::map<std::string, const Typed_identifier*> Names;
+
   // Peek at the current token from the lexer.
   const Token*
   peek_token();
@@ -165,6 +168,7 @@
   void field_decl(Struct_field_list*);
   Type* pointer_type();
   Type* channel_type();
+  void check_signature_names(const Typed_identifier_list*, Names*);
   Function_type* signature(Typed_identifier*, source_location);
   bool parameters(Typed_identifier_list**, bool* is_varargs);
   Typed_identifier_list* parameter_list(bool* is_varargs);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]