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
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 =