diff mbox

Go patch committed: Avoid crash on erroneous type

Message ID CAOyqgcXCa3Xr5fcvFdMhyL7jOUdVX2ZBnXcxEZepzXXiPp_6TA@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor June 14, 2017, 11:43 p.m. UTC
This patch to the Go frontend avoids crashing the compiler on an
erroneous type.  If there is an error constructing the backend type,
the GCC backend will report that the size is 1.  That will then cause
construction of the ptrmask to crash.  Avoid that case by just
generating an empty ptrmask.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 249205)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-372e75503c1dc9a38d9978aa6b67631283d5d6dd
+6449e2832eef94eacf89c88fa16bede637f729ba
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 249205)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -2570,16 +2570,16 @@  Type::make_gc_symbol_var(Gogo* gogo)
 bool
 Type::needs_gcprog(Gogo* gogo, int64_t* ptrsize, int64_t* ptrdata)
 {
+  Type* voidptr = Type::make_pointer_type(Type::make_void_type());
+  if (!voidptr->backend_type_size(gogo, ptrsize))
+    go_unreachable();
+
   if (!this->backend_type_ptrdata(gogo, ptrdata))
     {
       go_assert(saw_errors());
       return false;
     }
 
-  Type* voidptr = Type::make_pointer_type(Type::make_void_type());
-  if (!voidptr->backend_type_size(gogo, ptrsize))
-    go_unreachable();
-
   return *ptrdata / *ptrsize > max_ptrmask_bytes;
 }
 
@@ -2795,7 +2795,13 @@  Bvariable*
 Type::gc_ptrmask_var(Gogo* gogo, int64_t ptrsize, int64_t ptrdata)
 {
   Ptrmask ptrmask(ptrdata / ptrsize);
-  ptrmask.set_from(gogo, this, ptrsize, 0);
+  if (ptrdata >= ptrsize)
+    ptrmask.set_from(gogo, this, ptrsize, 0);
+  else
+    {
+      // This can happen in error cases.  Just build an empty gcbits.
+      go_assert(saw_errors());
+    }
   std::string sym_name = "runtime.gcbits." + ptrmask.symname();
   Bvariable* bvnull = NULL;
   std::pair<GC_gcbits_vars::iterator, bool> ins =