compiler: avoid crash on erroneous type
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 14 Jun 2017 23:42:53 +0000 (23:42 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 14 Jun 2017 23:42:53 +0000 (23:42 +0000)
    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.

    Noticed while compiling a broken package.  The policy I've been
    following is to not commit a test case for a compiler crash on invalid
    code, so no test case.

    Reviewed-on: https://go-review.googlesource.com/45775

From-SVN: r249208

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

index 1f600d3e312312e939c618acf0b3a3830544babd..0eeac9b25d43ab0d9685c6a74f7089150832a9cf 100644 (file)
@@ -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 61a33635c1284a6c9874b51040d4591fa5c0560b..912a23e191857eb6d540abf698d81f6c73915bfa 100644 (file)
@@ -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 =