aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Manghane <cmang@google.com>2015-09-10 18:24:28 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2015-09-10 18:24:28 +0000
commitec23e5b3950ab5a907aecdb0860340b86702ed13 (patch)
treec3d6323633f32f5fef3f497f47e7bb3718941bd3
parent8b661145105bf5d8d7be3f2e57b51c8b8d2c27b7 (diff)
downloadgcc-ec23e5b3950ab5a907aecdb0860340b86702ed13.zip
gcc-ec23e5b3950ab5a907aecdb0860340b86702ed13.tar.gz
gcc-ec23e5b3950ab5a907aecdb0860340b86702ed13.tar.bz2
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. From-SVN: r227656
-rw-r--r--gcc/go/ChangeLog5
-rw-r--r--gcc/go/go-gcc.cc3
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc60
-rw-r--r--gcc/go/gofrontend/types.cc30
5 files changed, 81 insertions, 19 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 90520de..2fa56ab 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,8 @@
+2015-09-10 Chris Manghane <cmang@google.com>
+
+ * go-gcc.cc (Gcc_backend::type_size): Return -1 for
+ unrepresentable size.
+
2015-08-24 Marek Polacek <polacek@redhat.com>
PR tree-optimization/67284
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index cb4c2e5..1314344 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -1099,7 +1099,8 @@ Gcc_backend::type_size(Btype* btype)
gcc_assert(tree_fits_uhwi_p (t));
unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
int64_t ret = static_cast<int64_t>(val_wide);
- gcc_assert(ret >= 0 && static_cast<unsigned HOST_WIDE_INT>(ret) == val_wide);
+ if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide)
+ return -1;
return ret;
}
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index a4ec924..ddf4637 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-913b47c957ea91db2f724491d88cb20e8f9be8c7
+7ba569544420d1de0eb607707ced6d23f8865186
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/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 21b4f14..dc37cf0 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -3626,8 +3626,13 @@ Unary_expression::do_flatten(Gogo* gogo, Named_object*,
Type* ptype = this->expr_->type()->points_to();
if (!ptype->is_void_type())
{
- Btype* pbtype = ptype->get_backend(gogo);
- int64_t s = gogo->backend()->type_size(pbtype);
+ int64_t s;
+ bool ok = ptype->backend_type_size(gogo, &s);
+ if (!ok)
+ {
+ go_assert(saw_errors());
+ return Expression::make_error(this->location());
+ }
if (s >= 4096 || this->issue_nil_check_)
{
Temporary_statement* temp =
@@ -4131,7 +4136,13 @@ Unary_expression::do_get_backend(Translate_context* context)
Btype* pbtype = ptype->get_backend(gogo);
if (!ptype->is_void_type())
{
- int64_t s = gogo->backend()->type_size(pbtype);
+ int64_t s;
+ bool ok = ptype->backend_type_size(gogo, &s);
+ if (!ok)
+ {
+ go_assert(saw_errors());
+ return gogo->backend()->error_expression();
+ }
if (s >= 4096 || this->issue_nil_check_)
{
go_assert(this->expr_->is_variable());
@@ -8339,8 +8350,14 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
Expression::make_conditional(cond, arg1_len, arg2_len, location);
Type* element_type = at->element_type();
- Btype* element_btype = element_type->get_backend(gogo);
- int64_t element_size = gogo->backend()->type_size(element_btype);
+ int64_t element_size;
+ bool ok = element_type->backend_type_size(gogo, &element_size);
+ if (!ok)
+ {
+ go_assert(saw_errors());
+ return gogo->backend()->error_expression();
+ }
+
Expression* size_expr = Expression::make_integer_int64(element_size,
length->type(),
location);
@@ -8381,8 +8398,12 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
{
arg2_val = at->get_value_pointer(gogo, arg2);
arg2_len = at->get_length(gogo, arg2);
- Btype* element_btype = element_type->get_backend(gogo);
- size = gogo->backend()->type_size(element_btype);
+ bool ok = element_type->backend_type_size(gogo, &size);
+ if (!ok)
+ {
+ go_assert(saw_errors());
+ return gogo->backend()->error_expression();
+ }
}
Expression* element_size =
Expression::make_integer_int64(size, NULL, location);
@@ -11539,14 +11560,20 @@ Allocation_expression::do_get_backend(Translate_context* context)
Gogo* gogo = context->gogo();
Location loc = this->location();
- Btype* btype = this->type_->get_backend(gogo);
if (this->allocate_on_stack_)
{
- int64_t size = gogo->backend()->type_size(btype);
+ int64_t size;
+ bool ok = this->type_->backend_type_size(gogo, &size);
+ if (!ok)
+ {
+ go_assert(saw_errors());
+ return gogo->backend()->error_expression();
+ }
return gogo->backend()->stack_allocation_expression(size, loc);
}
- Bexpression* space =
+ Btype* btype = this->type_->get_backend(gogo);
+ Bexpression* space =
gogo->allocate_memory(this->type_, loc)->get_backend(context);
Btype* pbtype = gogo->backend()->pointer_type(btype);
return gogo->backend()->convert_expression(pbtype, space, loc);
@@ -13731,23 +13758,28 @@ Type_info_expression::do_type()
Bexpression*
Type_info_expression::do_get_backend(Translate_context* context)
{
- Btype* btype = this->type_->get_backend(context->gogo());
Gogo* gogo = context->gogo();
+ bool ok = true;
int64_t val;
switch (this->type_info_)
{
case TYPE_INFO_SIZE:
- val = gogo->backend()->type_size(btype);
+ ok = this->type_->backend_type_size(gogo, &val);
break;
case TYPE_INFO_ALIGNMENT:
- val = gogo->backend()->type_alignment(btype);
+ ok = this->type_->backend_type_align(gogo, &val);
break;
case TYPE_INFO_FIELD_ALIGNMENT:
- val = gogo->backend()->type_field_alignment(btype);
+ ok = this->type_->backend_type_field_align(gogo, &val);
break;
default:
go_unreachable();
}
+ if (!ok)
+ {
+ go_assert(saw_errors());
+ return gogo->backend()->error_expression();
+ }
Expression* e = Expression::make_integer_int64(val, this->type(),
this->location());
return e->get_backend(context);
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 8331678..dcc6bc8 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -2524,6 +2524,20 @@ Type::backend_type_size(Gogo* gogo, int64_t *psize)
return false;
Btype* bt = this->get_backend_placeholder(gogo);
*psize = gogo->backend()->type_size(bt);
+ if (*psize == -1)
+ {
+ if (this->named_type() != NULL)
+ error_at(this->named_type()->location(),
+ "type %s larger than address space",
+ Gogo::message_name(this->named_type()->name()).c_str());
+ else
+ error("type %s larger than address space",
+ this->reflection(gogo).c_str());
+
+ // Make this an error type to avoid knock-on errors.
+ this->classification_ = TYPE_ERROR;
+ return false;
+ }
return true;
}
@@ -6400,8 +6414,12 @@ Array_type::slice_gc_symbol(Gogo* gogo, Expression_list** vals,
// Differentiate between slices with zero-length and non-zero-length values.
Type* element_type = this->element_type();
- Btype* ebtype = element_type->get_backend(gogo);
- int64_t element_size = gogo->backend()->type_size(ebtype);
+ int64_t element_size;
+ bool ok = element_type->backend_type_size(gogo, &element_size);
+ if (!ok) {
+ go_assert(saw_errors());
+ element_size = 4;
+ }
Type* uintptr_type = Type::lookup_integer_type("uintptr");
unsigned long opval = element_size == 0 ? GC_APTR : GC_SLICE;
@@ -6432,7 +6450,13 @@ Array_type::array_gc_symbol(Gogo* gogo, Expression_list** vals,
Btype* pbtype = gogo->backend()->pointer_type(gogo->backend()->void_type());
int64_t pwidth = gogo->backend()->type_size(pbtype);
- int64_t iwidth = gogo->backend()->type_size(this->get_backend(gogo));
+ int64_t iwidth;
+ bool ok = this->backend_type_size(gogo, &iwidth);
+ if (!ok)
+ {
+ go_assert(saw_errors());
+ iwidth = 4;
+ }
Type* element_type = this->element_type();
if (bound < 1 || !element_type->has_pointer())