Fixes issue 6637.
From-SVN: r218199
// Add temporary variables for all arguments that require type
// conversion.
Function_type* fntype = this->get_function_type();
- go_assert(fntype != NULL);
+ if (fntype == NULL)
+ {
+ go_assert(saw_errors());
+ return this;
+ }
if (this->args_ != NULL && !this->args_->empty()
&& fntype->parameters() != NULL && !fntype->parameters()->empty())
{
// interface. So introduce a temporary variable if necessary.
Expression*
-Interface_field_reference_expression::do_lower(Gogo*, Named_object*,
- Statement_inserter* inserter,
- int)
+Interface_field_reference_expression::do_flatten(Gogo*, Named_object*,
+ Statement_inserter* inserter)
{
if (!this->expr_->is_variable())
{
do_traverse(Traverse* traverse);
Expression*
- do_lower(Gogo*, Named_object*, Statement_inserter*, int);
+ do_flatten(Gogo*, Named_object*, Statement_inserter*);
Type*
do_type();
unsigned long val;
if (!this->length_->numeric_constant_value(&nc)
|| nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
- error_at(this->length_->location(), "invalid array length");
+ {
+ if (!this->issued_length_error_)
+ {
+ error_at(this->length_->location(), "invalid array length");
+ this->issued_length_error_ = true;
+ }
+ }
else
{
char buf[50];
unsigned long val;
if (!this->length_->numeric_constant_value(&nc)
|| nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
- error_at(this->length_->location(), "invalid array length");
+ {
+ if (!this->issued_length_error_)
+ {
+ error_at(this->length_->location(), "invalid array length");
+ this->issued_length_error_ = true;
+ }
+ }
else
{
char buf[50];
Forward_declaration_type::real_type()
{
if (this->is_defined())
- return this->named_object()->type_value();
+ {
+ Named_type* nt = this->named_object()->type_value();
+ if (!nt->is_valid())
+ return Type::make_error_type();
+ return this->named_object()->type_value();
+ }
else
{
this->warn();
Forward_declaration_type::real_type() const
{
if (this->is_defined())
- return this->named_object()->type_value();
+ {
+ const Named_type* nt = this->named_object()->type_value();
+ if (!nt->is_valid())
+ return Type::make_error_type();
+ return this->named_object()->type_value();
+ }
else
{
this->warn();
public:
Array_type(Type* element_type, Expression* length)
: Type(TYPE_ARRAY),
- element_type_(element_type), length_(length), blength_(NULL)
+ element_type_(element_type), length_(length), blength_(NULL),
+ issued_length_error_(false)
{ }
// Return the element type.
// The backend representation of the length.
// We only want to compute this once.
Bexpression* blength_;
+ // Whether or not an invalid length error has been issued for this type,
+ // to avoid knock-on errors.
+ mutable bool issued_length_error_;
};
// The type of a map.
bool
is_alias() const;
+ // Whether this named type is valid. A recursive named type is invalid.
+ bool
+ is_valid() const
+ { return !this->is_error_; }
+
// Whether this is a circular type: a pointer or function type that
// refers to itself, which is not possible in C.
bool