Skip to content

Commit

Permalink
compiler: Avoid knock-on errors with impossibly large types.
Browse files Browse the repository at this point in the history
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.

Change-Id: If985b99a4ab54955be3dbd514fb94f3e271ef7b8
Reviewed-on: https://go-review.googlesource.com/16234
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
Chris Manghane authored and ianlancetaylor committed Jan 26, 2016
1 parent ee4272b commit 731941c
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions go/types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 731941c

Please sign in to comment.