aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-09-28 20:23:43 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-09-28 20:23:43 +0000
commit7540a2c787301dc04f72c2fb236de8333ff41786 (patch)
treeb24baf9c4764aae0eebeb8e199fd1af5e9d4ab24
parent8d60fca50e7ccdfcc3c09e39068c1a1eb3a2e7cf (diff)
downloadgcc-7540a2c787301dc04f72c2fb236de8333ff41786.zip
gcc-7540a2c787301dc04f72c2fb236de8333ff41786.tar.gz
gcc-7540a2c787301dc04f72c2fb236de8333ff41786.tar.bz2
compiler: Avoid knockon errors for invalid uses of _.
From-SVN: r203006
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc6
-rw-r--r--gcc/go/gofrontend/gogo.cc21
-rw-r--r--gcc/go/gofrontend/gogo.h10
-rw-r--r--gcc/go/gofrontend/parse.cc10
-rw-r--r--gcc/go/gofrontend/types.cc6
5 files changed, 47 insertions, 6 deletions
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index 7813cc1..a95f290 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -1061,6 +1061,12 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
if (this->tree_ != NULL_TREE)
return this->tree_;
+ if (Gogo::is_erroneous_name(this->name_))
+ {
+ this->tree_ = error_mark_node;
+ return error_mark_node;
+ }
+
tree name;
if (this->classification_ == NAMED_OBJECT_TYPE)
name = NULL_TREE;
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 17cbb6b..9f918cb 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -1192,6 +1192,27 @@ Gogo::record_interface_type(Interface_type* itype)
this->interface_types_.push_back(itype);
}
+// Return an erroneous name that indicates that an error has already
+// been reported.
+
+std::string
+Gogo::erroneous_name()
+{
+ static int erroneous_count;
+ char name[50];
+ snprintf(name, sizeof name, "$erroneous%d", erroneous_count);
+ ++erroneous_count;
+ return name;
+}
+
+// Return whether a name is an erroneous name.
+
+bool
+Gogo::is_erroneous_name(const std::string& name)
+{
+ return name.compare(0, 10, "$erroneous") == 0;
+}
+
// Return a name for a thunk object.
std::string
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 6a87f2d..23968d4a 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -387,6 +387,16 @@ class Gogo
void
mark_locals_used();
+ // Return a name to use for an error case. This should only be used
+ // after reporting an error, and is used to avoid useless knockon
+ // errors.
+ static std::string
+ erroneous_name();
+
+ // Return whether the name indicates an error.
+ static bool
+ is_erroneous_name(const std::string&);
+
// Return a name to use for a thunk function. A thunk function is
// one we create during the compilation, for a go statement or a
// defer statement or a method expression.
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index befe4bc..e68f175 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -213,7 +213,7 @@ Parse::qualified_ident(std::string* pname, Named_object** ppackage)
if (name == "_")
{
error_at(this->location(), "invalid use of %<_%>");
- name = "blank";
+ name = Gogo::erroneous_name();
}
if (package->name() == this->gogo_->package_name())
@@ -3104,7 +3104,7 @@ Parse::selector(Expression* left, bool* is_type_switch)
if (token->identifier() == "_")
{
error_at(this->location(), "invalid use of %<_%>");
- name = this->gogo_->pack_hidden_name("blank", false);
+ name = Gogo::erroneous_name();
}
this->advance_token();
return Expression::make_selector(left, name, location);
@@ -4929,7 +4929,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
{
error_at(recv_var_loc,
"no new variables on left side of %<:=%>");
- recv_var = "blank";
+ recv_var = Gogo::erroneous_name();
}
*is_send = false;
*varname = gogo->pack_hidden_name(recv_var, is_rv_exported);
@@ -4965,7 +4965,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
{
error_at(recv_var_loc,
"no new variables on left side of %<:=%>");
- recv_var = "blank";
+ recv_var = Gogo::erroneous_name();
}
*is_send = false;
if (recv_var != "_")
@@ -5502,7 +5502,7 @@ Parse::package_clause()
if (name == "_")
{
error_at(this->location(), "invalid package name _");
- name = "blank";
+ name = Gogo::erroneous_name();
}
this->advance_token();
}
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 32f827d..a4a6070 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -9269,7 +9269,11 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
}
else
{
- if (!ambig1.empty())
+ if (Gogo::is_erroneous_name(name))
+ {
+ // An error was already reported.
+ }
+ else if (!ambig1.empty())
error_at(location, "%qs is ambiguous via %qs and %qs",
Gogo::message_name(name).c_str(), ambig1.c_str(),
ambig2.c_str());