diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-09-20 16:46:46 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-09-20 16:46:46 +0000 |
commit | 458692b00c947e500d42d2704c3a38604ee6b451 (patch) | |
tree | f418101b123973bea669d8eed9ad229dbf0a64be /gcc | |
parent | 40ebf57b67ae30304a7c12fcbac885a8eb6463ce (diff) | |
download | gcc-458692b00c947e500d42d2704c3a38604ee6b451.zip gcc-458692b00c947e500d42d2704c3a38604ee6b451.tar.gz gcc-458692b00c947e500d42d2704c3a38604ee6b451.tar.bz2 |
Check for duplicate parameter/result names.
From-SVN: r179010
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 6 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 38 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.h | 4 |
3 files changed, 45 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 221826b..be7592b 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -4482,6 +4482,12 @@ Bindings::new_definition(Named_object* old_object, Named_object* new_object) 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 --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index 06281db..29f4c69 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -677,6 +677,32 @@ Parse::channel_type() 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 @@ Parse::signature(Typed_identifier* receiver, source_location location) Typed_identifier_list* params; bool params_ok = this->parameters(¶ms, &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 --git a/gcc/go/gofrontend/parse.h b/gcc/go/gofrontend/parse.h index f072fd3..0da86fb 100644 --- a/gcc/go/gofrontend/parse.h +++ b/gcc/go/gofrontend/parse.h @@ -131,6 +131,9 @@ class Parse // 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 @@ class Parse 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); |