compiler: Don't allow tuple assignments to contain duplicate symbols.
authorIan Lance Taylor <ian@gcc.gnu.org>
Sat, 18 Oct 2014 00:41:42 +0000 (00:41 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Sat, 18 Oct 2014 00:41:42 +0000 (00:41 +0000)
Fixes issue 8436.

From-SVN: r216420

gcc/go/gofrontend/parse.cc

index b97ada19c84b57cb19e8fd29fd5b75992c841c51..c4bcf058d8eacd315eee97194fd1ee34054ee50e 100644 (file)
@@ -2088,6 +2088,9 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
   Typed_identifier_list til;
   til.push_back(Typed_identifier(name, NULL, location));
 
+  std::set<std::string> uniq_idents;
+  uniq_idents.insert(name);
+
   // We've seen one identifier.  If we see a comma now, this could be
   // "a, *p = 1, 2".
   if (this->peek_token()->is_op(OPERATOR_COMMA))
@@ -2102,6 +2105,7 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
          std::string id = token->identifier();
          bool is_id_exported = token->is_identifier_exported();
          Location id_location = token->location();
+         std::pair<std::set<std::string>::iterator, bool> ins;
 
          token = this->advance_token();
          if (!token->is_op(OPERATOR_COMMA))
@@ -2109,6 +2113,10 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
              if (token->is_op(OPERATOR_COLONEQ))
                {
                  id = this->gogo_->pack_hidden_name(id, is_id_exported);
+                 ins = uniq_idents.insert(id);
+                 if (!ins.second && !Gogo::is_sink_name(id))
+                   error_at(id_location, "multiple assignments to %s",
+                            Gogo::message_name(id).c_str());
                  til.push_back(Typed_identifier(id, NULL, location));
                }
              else
@@ -2119,6 +2127,10 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
            }
 
          id = this->gogo_->pack_hidden_name(id, is_id_exported);
+         ins = uniq_idents.insert(id);
+         if (!ins.second && !Gogo::is_sink_name(id))
+           error_at(id_location, "multiple assignments to %s",
+                    Gogo::message_name(id).c_str());
          til.push_back(Typed_identifier(id, NULL, location));
        }