aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-11-26 16:11:28 -0800
committerIan Lance Taylor <iant@golang.org>2020-11-28 07:01:41 -0800
commitb1adbc27c4a85ded4db81ed65b1cefce4cee8d15 (patch)
tree43770b3d503fd73e08fa5647f8a892d4c4ba6b54 /gcc/go
parent822ea13e499db20af2080b48fc3bb530e429bb8d (diff)
downloadgcc-b1adbc27c4a85ded4db81ed65b1cefce4cee8d15.zip
gcc-b1adbc27c4a85ded4db81ed65b1cefce4cee8d15.tar.gz
gcc-b1adbc27c4a85ded4db81ed65b1cefce4cee8d15.tar.bz2
compiler: avoid follow-on errors for bad types
Mark bad types as erroneous, to avoid generating further errors. This required some code using array types to check for errors. For https://golang.org/issue/19880 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/273626
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc39
-rw-r--r--gcc/go/gofrontend/types.cc45
-rw-r--r--gcc/go/gofrontend/types.h4
4 files changed, 82 insertions, 8 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 5964832..4695907 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-66669bb6cae475eda6666a94f6ff4f616ffa77d7
+16ab9b001c214cf831bc52a7bca5a2d18e9e4f3c
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 448888b..dc7399e 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -15303,9 +15303,22 @@ Array_construction_expression::do_is_static_initializer() const
void
Array_construction_expression::do_determine_type(const Type_context*)
{
+ if (this->is_error_expression())
+ {
+ go_assert(saw_errors());
+ return;
+ }
+
if (this->vals() == NULL)
return;
- Type_context subcontext(this->type_->array_type()->element_type(), false);
+ Array_type* at = this->type_->array_type();
+ if (at == NULL || at->is_error() || at->element_type()->is_error())
+ {
+ go_assert(saw_errors());
+ this->set_is_error();
+ return;
+ }
+ Type_context subcontext(at->element_type(), false);
for (Expression_list::const_iterator pv = this->vals()->begin();
pv != this->vals()->end();
++pv)
@@ -15320,10 +15333,22 @@ Array_construction_expression::do_determine_type(const Type_context*)
void
Array_construction_expression::do_check_types(Gogo*)
{
+ if (this->is_error_expression())
+ {
+ go_assert(saw_errors());
+ return;
+ }
+
if (this->vals() == NULL)
return;
Array_type* at = this->type_->array_type();
+ if (at == NULL || at->is_error() || at->element_type()->is_error())
+ {
+ go_assert(saw_errors());
+ this->set_is_error();
+ return;
+ }
int i = 0;
Type* element_type = at->element_type();
for (Expression_list::const_iterator pv = this->vals()->begin();
@@ -15348,6 +15373,12 @@ Expression*
Array_construction_expression::do_flatten(Gogo*, Named_object*,
Statement_inserter* inserter)
{
+ if (this->is_error_expression())
+ {
+ go_assert(saw_errors());
+ return this;
+ }
+
if (this->vals() == NULL)
return this;
@@ -15384,6 +15415,12 @@ Array_construction_expression::do_flatten(Gogo*, Named_object*,
void
Array_construction_expression::do_add_conversions()
{
+ if (this->is_error_expression())
+ {
+ go_assert(saw_errors());
+ return;
+ }
+
if (this->vals() == NULL)
return;
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index c4570b4..286ecc1 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -261,6 +261,15 @@ Type::is_error_type() const
}
}
+// Note that this type is an error. This is called by children when
+// they discover an error during the verify_types pass.
+
+void
+Type::set_is_error()
+{
+ this->classification_ = TYPE_ERROR;
+}
+
// If this is a pointer type, return the type to which it points.
// Otherwise, return NULL.
@@ -5871,6 +5880,7 @@ Struct_type::do_verify()
{
go_error_at(p->location(), "embedded type may not be a pointer");
p->set_type(Type::make_error_type());
+ this->set_is_error();
}
else if (t->points_to() != NULL
&& t->points_to()->interface_type() != NULL)
@@ -5878,6 +5888,7 @@ Struct_type::do_verify()
go_error_at(p->location(),
"embedded type may not be pointer to interface");
p->set_type(Type::make_error_type());
+ this->set_is_error();
}
}
}
@@ -7236,6 +7247,13 @@ Array_type::verify_length()
Type_context context(Type::lookup_integer_type("int"), false);
this->length_->determine_type(&context);
+ if (this->length_->is_error_expression()
+ || this->length_->type()->is_error())
+ {
+ go_assert(saw_errors());
+ return false;
+ }
+
if (!this->length_->is_constant())
{
go_error_at(this->length_->location(), "array bound is not constant");
@@ -7310,7 +7328,10 @@ Array_type::do_verify()
if (this->element_type()->is_error_type())
return false;
if (!this->verify_length())
- this->length_ = Expression::make_error(this->length_->location());
+ {
+ this->length_ = Expression::make_error(this->length_->location());
+ this->set_is_error();
+ }
return true;
}
@@ -8125,11 +8146,20 @@ Map_type::do_verify()
{
// The runtime support uses "map[void]void".
if (!this->key_type_->is_comparable() && !this->key_type_->is_void_type())
- go_error_at(this->location_, "invalid map key type");
+ {
+ go_error_at(this->location_, "invalid map key type");
+ this->set_is_error();
+ }
if (!this->key_type_->in_heap())
- go_error_at(this->location_, "go:notinheap map key not allowed");
+ {
+ go_error_at(this->location_, "go:notinheap map key not allowed");
+ this->set_is_error();
+ }
if (!this->val_type_->in_heap())
- go_error_at(this->location_, "go:notinheap map value not allowed");
+ {
+ go_error_at(this->location_, "go:notinheap map value not allowed");
+ this->set_is_error();
+ }
return true;
}
@@ -8660,8 +8690,11 @@ Channel_type::do_verify()
// We have no location for this error, but this is not something the
// ordinary user will see.
if (!this->element_type_->in_heap())
- go_error_at(Linemap::unknown_location(),
- "chan of go:notinheap type not allowed");
+ {
+ go_error_at(Linemap::unknown_location(),
+ "chan of go:notinheap type not allowed");
+ this->set_is_error();
+ }
return true;
}
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 5965d5a..d097029 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -1141,6 +1141,10 @@ class Type
virtual void
do_export(Export*) const;
+ // For children to call when they detect that they are in error.
+ void
+ set_is_error();
+
// Return whether a method expects a pointer as the receiver.
static bool
method_expects_pointer(const Named_object*);