aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-02-19 03:23:22 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-02-19 03:23:22 +0000
commit1e2afadbc0827357daf6d6b7322a9250aad3f4ab (patch)
tree3b70cef5fc6d58babeb9aa28c756473914d6bfe2 /gcc/go
parentf84ae14c4eeb561868722929e229213348d81dc9 (diff)
downloadgcc-1e2afadbc0827357daf6d6b7322a9250aad3f4ab.zip
gcc-1e2afadbc0827357daf6d6b7322a9250aad3f4ab.tar.gz
gcc-1e2afadbc0827357daf6d6b7322a9250aad3f4ab.tar.bz2
Fix struct with array of struct with field that points to first struct.
Don't crash converting an untyped complex constant to an integer type. Don't crash on unsafe.Sizeof of erroneous type. Don't crash on method expression of erroneous type. Don't crash when sink and global var are initialized from type guard. Don't crash initializing erroneous slice. Don't crash on erroneous method of type seen before definition. From-SVN: r170301
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/expressions.cc14
-rw-r--r--gcc/go/gofrontend/parse.cc2
-rw-r--r--gcc/go/gofrontend/types.cc32
3 files changed, 39 insertions, 9 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 940d418..e1d59be 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -716,7 +716,11 @@ Expression::float_constant_tree(mpfr_t val, tree type)
tree
Expression::complex_constant_tree(mpfr_t real, mpfr_t imag, tree type)
{
- if (TREE_CODE(type) == COMPLEX_TYPE)
+ if (type == error_mark_node)
+ return error_mark_node;
+ else if (TREE_CODE(type) == INTEGER_TYPE || TREE_CODE(type) == REAL_TYPE)
+ return Expression::float_constant_tree(real, type);
+ else if (TREE_CODE(type) == COMPLEX_TYPE)
{
REAL_VALUE_TYPE r1;
real_from_mpfr(&r1, real, TREE_TYPE(type), GMP_RNDN);
@@ -6960,6 +6964,8 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
if (arg_type->is_abstract())
return false;
tree arg_type_tree = arg_type->get_tree(this->gogo_);
+ if (arg_type_tree == error_mark_node)
+ return false;
unsigned long val_long;
if (this->code_ == BUILTIN_SIZEOF)
{
@@ -10325,7 +10331,11 @@ Selector_expression::lower_method_expression(Gogo* gogo)
gcc_assert(vno != NULL);
Expression* ve = Expression::make_var_reference(vno, location);
Expression* bm = Type::bind_field_or_method(gogo, nt, ve, name, location);
- gcc_assert(bm != NULL && !bm->is_error_expression());
+
+ // Even though we found the method above, if it has an error type we
+ // may see an error here.
+ if (bm->is_error_expression())
+ return bm;
Expression_list* args;
if (method_parameters == NULL)
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index 45ff33d..fc8771c 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -1865,6 +1865,8 @@ Named_object*
Parse::create_dummy_global(Type* type, Expression* init,
source_location location)
{
+ if (type == NULL && init == NULL)
+ type = Type::lookup_bool_type();
Variable* var = new Variable(type, init, true, false, false, location);
static int count;
char buf[30];
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 0d17ab4..2d7312b 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -4473,6 +4473,8 @@ Array_type::fill_in_tree(Gogo* gogo, tree struct_type)
gcc_assert(this->length_ == NULL);
tree element_type_tree = this->element_type_->get_tree(gogo);
+ if (element_type_tree == error_mark_node)
+ return error_mark_node;
tree field = TYPE_FIELDS(struct_type);
gcc_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__values") == 0);
gcc_assert(POINTER_TYPE_P(TREE_TYPE(field))
@@ -6923,12 +6925,12 @@ Named_type::do_verify()
}
// If this is a struct, then if any of the fields of the struct
- // themselves have struct type, then this struct must be converted
- // to the backend representation before the field's type is
- // converted. That may seem backward, but it works because if the
- // field's type refers to this one, e.g., via a pointer, then the
- // conversion process will pick up the half-built struct and do the
- // right thing.
+ // themselves have struct type, or array of struct type, then this
+ // struct must be converted to the backend representation before the
+ // field's type is converted. That may seem backward, but it works
+ // because if the field's type refers to this one, e.g., via a
+ // pointer, then the conversion process will pick up the half-built
+ // struct and do the right thing.
if (this->struct_type() != NULL)
{
const Struct_field_list* fields = this->struct_type()->fields();
@@ -6939,6 +6941,16 @@ Named_type::do_verify()
Struct_type* st = p->type()->struct_type();
if (st != NULL)
st->add_prerequisite(this);
+ else
+ {
+ Array_type* at = p->type()->array_type();
+ if (at != NULL && !at->is_open_array_type())
+ {
+ st = at->element_type()->struct_type();
+ if (st != NULL)
+ st->add_prerequisite(this);
+ }
+ }
}
}
@@ -7488,7 +7500,13 @@ Type::add_interface_methods_for_type(const Type* type,
++pm)
{
Function_type* fntype = pm->type()->function_type();
- gcc_assert(fntype != NULL && !fntype->is_method());
+ if (fntype == NULL)
+ {
+ // This is an error, but it should be reported elsewhere
+ // when we look at the methods for IT.
+ continue;
+ }
+ gcc_assert(!fntype->is_method());
fntype = fntype->copy_with_receiver(const_cast<Type*>(type));
Method* m = new Interface_method(pm->name(), pm->location(), fntype,
field_indexes, depth);