diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-26 22:35:20 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-26 22:35:20 +0000 |
commit | 619bb79bfb6cc0cc174a8ba85f0553fbb7fe736a (patch) | |
tree | 9ed10d3f86c009a9d7a6a5f5809193047cb3c303 | |
parent | 7cf9b89548642f062fbe22ff2433251842da849b (diff) | |
download | gcc-619bb79bfb6cc0cc174a8ba85f0553fbb7fe736a.tar.gz |
compiler: Avoid knock-on errors with impossibly large types.
The gofrontend asks the backend compiler for the architecture
appropriate size of a given type. For array types, it is possible
to construct a type too large to fit on the machine. This patch does
two things: 1. When an impossibly large type is encountered, we mark
the type as erroneous and later calls to discover the size of that
type are short-circuited. 2. When generating the GC symbol data for
an impossibly large array of arrays, we avoid generating symbol data
as soon as we find an array that is too large to be expressed.
Fixes golang/go#12938.
Reviewed-on: https://go-review.googlesource.com/16234
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232855 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 6 |
2 files changed, 5 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index b4c90ef8892..9540d16b4c8 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -c375f3bf470f94220149b486c947bb3eb57cde7d +731941c155214d6158fa800e52ab3225c0b55f73 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 802a17dc0e3..52a1e4da886 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -2550,6 +2550,8 @@ Type::backend_type_size(Gogo* gogo, int64_t *psize) { if (!this->is_backend_type_size_known(gogo)) return false; + if (this->is_error_type()) + return false; Btype* bt = this->get_backend_placeholder(gogo); *psize = gogo->backend()->type_size(bt); if (*psize == -1) @@ -6453,7 +6455,7 @@ Array_type::slice_gc_symbol(Gogo* gogo, Expression_list** vals, (*vals)->push_back(Expression::make_integer_ul(opval, uintptr_type, bloc)); (*vals)->push_back(*offset); - if (element_size != 0) + if (element_size != 0 && ok) (*vals)->push_back(Expression::make_gc_symbol(element_type)); this->advance_gc_offset(offset); } @@ -6488,7 +6490,7 @@ Array_type::array_gc_symbol(Gogo* gogo, Expression_list** vals, Type* element_type = this->element_type(); if (bound < 1 || !element_type->has_pointer()) this->advance_gc_offset(offset); - else if (bound == 1 || iwidth <= 4 * pwidth) + else if (ok && (bound == 1 || iwidth <= 4 * pwidth)) { for (unsigned int i = 0; i < bound; ++i) Type::gc_symbol(gogo, element_type, vals, offset, stack_size); |