compiler: fix crash on struct that embeds pointer type
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 27 Sep 2017 17:46:33 +0000 (17:46 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 27 Sep 2017 17:46:33 +0000 (17:46 +0000)
    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

From-SVN: r253236

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/types.cc

index de1369dedac416ba843e8299e692f9359133d1fe..12cba43421a04cce61b5aefa3572c47e79824400 100644 (file)
@@ -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.
index a00b80a7e6c414e5767133ea94135c2048fed1e1..b6323f8135e88aa37682d9ab0f269f931bb7a153 100644 (file)
@@ -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,