aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-09-27 17:46:33 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-09-27 17:46:33 +0000
commit233557133c4c2db3f39b1bff7b8a7713523d43ab (patch)
treec9d2a60d8775d143e4dd645a0f4d43ac10c46e7e
parent0a53d3c8f8380b51a6875e7155df48cc7ff11592 (diff)
compiler: fix crash on struct that embeds pointer type
The type verification code that enforces rules about the types of embedded struct fields was not properly handling the case where the pointed-to type is a pointer type, e.g. type s *struct{ C int } type t struct{ *s } which is illegal according to the spec. Tweak the verifier to catch this case, and add a guard in the lowering pass to make sure that we don't crash on invalid accesses to field "C" in type "t" above. Fixes golang/go#22050 Reviewed-on: https://go-review.googlesource.com/66530 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253236 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/types.cc10
2 files changed, 10 insertions, 2 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index de1369dedac..12cba43421a 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-cdf1f58c7578980e1d1949680c7e404961b7c153
+11b7dae7de94215e92eb46e703cfecd76c0a3282
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/types.cc b/gcc/go/gofrontend/types.cc
index a00b80a7e6c..b6323f8135e 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -5842,7 +5842,9 @@ Struct_type::do_verify()
Type* t = p->type();
if (p->is_anonymous())
{
- if (t->named_type() != NULL && t->points_to() != NULL)
+ if ((t->named_type() != NULL && t->points_to() != NULL)
+ || (t->named_type() == NULL && t->points_to() != NULL
+ && t->points_to()->points_to() != NULL))
{
go_error_at(p->location(), "embedded type may not be a pointer");
p->set_type(Type::make_error_type());
@@ -11848,6 +11850,12 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
go_assert(expr->type()->struct_type() == st);
}
ret = st->field_reference(expr, name, location);
+ if (ret == NULL)
+ {
+ go_error_at(location, "type has no field %qs",
+ Gogo::message_name(name).c_str());
+ return Expression::make_error(location);
+ }
}
else if (it != NULL && it->find_method(name) != NULL)
ret = Expression::make_interface_field_reference(expr, name,