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);
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)
{
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)
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))
}
// 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();
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);
+ }
+ }
}
}
++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);