Skip to content

Commit 2a305b8

Browse files
author
ian
committed
compiler: Report errors from very large types.
The gcc backend throws an internal error when trying to get the size of a type which is larger than the amount of address space on the machine. This patch catches this error and reports it in a user friendly way. Fixes golang/go#11554. Reviewed-on: https://go-review.googlesource.com/13684 * go-gcc.cc (Gcc_backend::type_size): Return -1 for unrepresentable size. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227656 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent 291858c commit 2a305b8

File tree

5 files changed

+81
-19
lines changed

5 files changed

+81
-19
lines changed

gcc/go/ChangeLog

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2015-09-10 Chris Manghane <[email protected]>
2+
3+
* go-gcc.cc (Gcc_backend::type_size): Return -1 for
4+
unrepresentable size.
5+
16
2015-08-24 Marek Polacek <[email protected]>
27

38
PR tree-optimization/67284

gcc/go/go-gcc.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,8 @@ Gcc_backend::type_size(Btype* btype)
10991099
gcc_assert(tree_fits_uhwi_p (t));
11001100
unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
11011101
int64_t ret = static_cast<int64_t>(val_wide);
1102-
gcc_assert(ret >= 0 && static_cast<unsigned HOST_WIDE_INT>(ret) == val_wide);
1102+
if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide)
1103+
return -1;
11031104
return ret;
11041105
}
11051106

gcc/go/gofrontend/MERGE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
913b47c957ea91db2f724491d88cb20e8f9be8c7
1+
7ba569544420d1de0eb607707ced6d23f8865186
22

33
The first line of this file holds the git revision number of the last
44
merge done from the gofrontend repository.

gcc/go/gofrontend/expressions.cc

+46-14
Original file line numberDiff line numberDiff line change
@@ -3626,8 +3626,13 @@ Unary_expression::do_flatten(Gogo* gogo, Named_object*,
36263626
Type* ptype = this->expr_->type()->points_to();
36273627
if (!ptype->is_void_type())
36283628
{
3629-
Btype* pbtype = ptype->get_backend(gogo);
3630-
int64_t s = gogo->backend()->type_size(pbtype);
3629+
int64_t s;
3630+
bool ok = ptype->backend_type_size(gogo, &s);
3631+
if (!ok)
3632+
{
3633+
go_assert(saw_errors());
3634+
return Expression::make_error(this->location());
3635+
}
36313636
if (s >= 4096 || this->issue_nil_check_)
36323637
{
36333638
Temporary_statement* temp =
@@ -4131,7 +4136,13 @@ Unary_expression::do_get_backend(Translate_context* context)
41314136
Btype* pbtype = ptype->get_backend(gogo);
41324137
if (!ptype->is_void_type())
41334138
{
4134-
int64_t s = gogo->backend()->type_size(pbtype);
4139+
int64_t s;
4140+
bool ok = ptype->backend_type_size(gogo, &s);
4141+
if (!ok)
4142+
{
4143+
go_assert(saw_errors());
4144+
return gogo->backend()->error_expression();
4145+
}
41354146
if (s >= 4096 || this->issue_nil_check_)
41364147
{
41374148
go_assert(this->expr_->is_variable());
@@ -8339,8 +8350,14 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
83398350
Expression::make_conditional(cond, arg1_len, arg2_len, location);
83408351

83418352
Type* element_type = at->element_type();
8342-
Btype* element_btype = element_type->get_backend(gogo);
8343-
int64_t element_size = gogo->backend()->type_size(element_btype);
8353+
int64_t element_size;
8354+
bool ok = element_type->backend_type_size(gogo, &element_size);
8355+
if (!ok)
8356+
{
8357+
go_assert(saw_errors());
8358+
return gogo->backend()->error_expression();
8359+
}
8360+
83448361
Expression* size_expr = Expression::make_integer_int64(element_size,
83458362
length->type(),
83468363
location);
@@ -8381,8 +8398,12 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
83818398
{
83828399
arg2_val = at->get_value_pointer(gogo, arg2);
83838400
arg2_len = at->get_length(gogo, arg2);
8384-
Btype* element_btype = element_type->get_backend(gogo);
8385-
size = gogo->backend()->type_size(element_btype);
8401+
bool ok = element_type->backend_type_size(gogo, &size);
8402+
if (!ok)
8403+
{
8404+
go_assert(saw_errors());
8405+
return gogo->backend()->error_expression();
8406+
}
83868407
}
83878408
Expression* element_size =
83888409
Expression::make_integer_int64(size, NULL, location);
@@ -11539,14 +11560,20 @@ Allocation_expression::do_get_backend(Translate_context* context)
1153911560
Gogo* gogo = context->gogo();
1154011561
Location loc = this->location();
1154111562

11542-
Btype* btype = this->type_->get_backend(gogo);
1154311563
if (this->allocate_on_stack_)
1154411564
{
11545-
int64_t size = gogo->backend()->type_size(btype);
11565+
int64_t size;
11566+
bool ok = this->type_->backend_type_size(gogo, &size);
11567+
if (!ok)
11568+
{
11569+
go_assert(saw_errors());
11570+
return gogo->backend()->error_expression();
11571+
}
1154611572
return gogo->backend()->stack_allocation_expression(size, loc);
1154711573
}
1154811574

11549-
Bexpression* space =
11575+
Btype* btype = this->type_->get_backend(gogo);
11576+
Bexpression* space =
1155011577
gogo->allocate_memory(this->type_, loc)->get_backend(context);
1155111578
Btype* pbtype = gogo->backend()->pointer_type(btype);
1155211579
return gogo->backend()->convert_expression(pbtype, space, loc);
@@ -13731,23 +13758,28 @@ Type_info_expression::do_type()
1373113758
Bexpression*
1373213759
Type_info_expression::do_get_backend(Translate_context* context)
1373313760
{
13734-
Btype* btype = this->type_->get_backend(context->gogo());
1373513761
Gogo* gogo = context->gogo();
13762+
bool ok = true;
1373613763
int64_t val;
1373713764
switch (this->type_info_)
1373813765
{
1373913766
case TYPE_INFO_SIZE:
13740-
val = gogo->backend()->type_size(btype);
13767+
ok = this->type_->backend_type_size(gogo, &val);
1374113768
break;
1374213769
case TYPE_INFO_ALIGNMENT:
13743-
val = gogo->backend()->type_alignment(btype);
13770+
ok = this->type_->backend_type_align(gogo, &val);
1374413771
break;
1374513772
case TYPE_INFO_FIELD_ALIGNMENT:
13746-
val = gogo->backend()->type_field_alignment(btype);
13773+
ok = this->type_->backend_type_field_align(gogo, &val);
1374713774
break;
1374813775
default:
1374913776
go_unreachable();
1375013777
}
13778+
if (!ok)
13779+
{
13780+
go_assert(saw_errors());
13781+
return gogo->backend()->error_expression();
13782+
}
1375113783
Expression* e = Expression::make_integer_int64(val, this->type(),
1375213784
this->location());
1375313785
return e->get_backend(context);

gcc/go/gofrontend/types.cc

+27-3
Original file line numberDiff line numberDiff line change
@@ -2524,6 +2524,20 @@ Type::backend_type_size(Gogo* gogo, int64_t *psize)
25242524
return false;
25252525
Btype* bt = this->get_backend_placeholder(gogo);
25262526
*psize = gogo->backend()->type_size(bt);
2527+
if (*psize == -1)
2528+
{
2529+
if (this->named_type() != NULL)
2530+
error_at(this->named_type()->location(),
2531+
"type %s larger than address space",
2532+
Gogo::message_name(this->named_type()->name()).c_str());
2533+
else
2534+
error("type %s larger than address space",
2535+
this->reflection(gogo).c_str());
2536+
2537+
// Make this an error type to avoid knock-on errors.
2538+
this->classification_ = TYPE_ERROR;
2539+
return false;
2540+
}
25272541
return true;
25282542
}
25292543

@@ -6400,8 +6414,12 @@ Array_type::slice_gc_symbol(Gogo* gogo, Expression_list** vals,
64006414

64016415
// Differentiate between slices with zero-length and non-zero-length values.
64026416
Type* element_type = this->element_type();
6403-
Btype* ebtype = element_type->get_backend(gogo);
6404-
int64_t element_size = gogo->backend()->type_size(ebtype);
6417+
int64_t element_size;
6418+
bool ok = element_type->backend_type_size(gogo, &element_size);
6419+
if (!ok) {
6420+
go_assert(saw_errors());
6421+
element_size = 4;
6422+
}
64056423

64066424
Type* uintptr_type = Type::lookup_integer_type("uintptr");
64076425
unsigned long opval = element_size == 0 ? GC_APTR : GC_SLICE;
@@ -6432,7 +6450,13 @@ Array_type::array_gc_symbol(Gogo* gogo, Expression_list** vals,
64326450

64336451
Btype* pbtype = gogo->backend()->pointer_type(gogo->backend()->void_type());
64346452
int64_t pwidth = gogo->backend()->type_size(pbtype);
6435-
int64_t iwidth = gogo->backend()->type_size(this->get_backend(gogo));
6453+
int64_t iwidth;
6454+
bool ok = this->backend_type_size(gogo, &iwidth);
6455+
if (!ok)
6456+
{
6457+
go_assert(saw_errors());
6458+
iwidth = 4;
6459+
}
64366460

64376461
Type* element_type = this->element_type();
64386462
if (bound < 1 || !element_type->has_pointer())

0 commit comments

Comments
 (0)