mirror of git://gcc.gnu.org/git/gcc.git
Check for duplicate methods.
Don't get into an endless loop given invalid recursive types. From-SVN: r167816
This commit is contained in:
parent
d4645ada25
commit
fd948ffb14
|
@ -53,9 +53,9 @@ Type::base()
|
||||||
switch (this->classification_)
|
switch (this->classification_)
|
||||||
{
|
{
|
||||||
case TYPE_NAMED:
|
case TYPE_NAMED:
|
||||||
return static_cast<Named_type*>(this)->real_type()->base();
|
return this->named_type()->named_base();
|
||||||
case TYPE_FORWARD:
|
case TYPE_FORWARD:
|
||||||
return static_cast<Forward_declaration_type*>(this)->real_type()->base();
|
return this->forward_declaration_type()->real_type()->base();
|
||||||
default:
|
default:
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,9 @@ Type::base() const
|
||||||
switch (this->classification_)
|
switch (this->classification_)
|
||||||
{
|
{
|
||||||
case TYPE_NAMED:
|
case TYPE_NAMED:
|
||||||
return static_cast<const Named_type*>(this)->real_type()->base();
|
return this->named_type()->named_base();
|
||||||
case TYPE_FORWARD:
|
case TYPE_FORWARD:
|
||||||
{
|
return this->forward_declaration_type()->real_type()->base();
|
||||||
const Forward_declaration_type* ftype =
|
|
||||||
static_cast<const Forward_declaration_type*>(this);
|
|
||||||
return ftype->real_type()->base();
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +220,7 @@ Type::is_error_type() const
|
||||||
case TYPE_ERROR:
|
case TYPE_ERROR:
|
||||||
return true;
|
return true;
|
||||||
case TYPE_NAMED:
|
case TYPE_NAMED:
|
||||||
return t->named_type()->real_type()->is_error_type();
|
return t->named_type()->is_named_error_type();
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5502,10 +5498,23 @@ Interface_type::finalize_methods()
|
||||||
const Typed_identifier* p = &this->methods_->at(from);
|
const Typed_identifier* p = &this->methods_->at(from);
|
||||||
if (!p->name().empty())
|
if (!p->name().empty())
|
||||||
{
|
{
|
||||||
if (from != to)
|
size_t i = 0;
|
||||||
this->methods_->set(to, *p);
|
for (i = 0; i < to; ++i)
|
||||||
|
{
|
||||||
|
if (this->methods_->at(i).name() == p->name())
|
||||||
|
{
|
||||||
|
error_at(p->location(), "duplicate method %qs",
|
||||||
|
Gogo::message_name(p->name()).c_str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == to)
|
||||||
|
{
|
||||||
|
if (from != to)
|
||||||
|
this->methods_->set(to, *p);
|
||||||
|
++to;
|
||||||
|
}
|
||||||
++from;
|
++from;
|
||||||
++to;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Interface_type* it = p->type()->interface_type();
|
Interface_type* it = p->type()->interface_type();
|
||||||
|
@ -6448,6 +6457,45 @@ Named_type::message_name() const
|
||||||
return this->named_object_->message_name();
|
return this->named_object_->message_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the base type for this type. We have to be careful about
|
||||||
|
// circular type definitions, which are invalid but may be seen here.
|
||||||
|
|
||||||
|
Type*
|
||||||
|
Named_type::named_base()
|
||||||
|
{
|
||||||
|
if (this->seen_)
|
||||||
|
return this;
|
||||||
|
this->seen_ = true;
|
||||||
|
Type* ret = this->type_->base();
|
||||||
|
this->seen_ = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type*
|
||||||
|
Named_type::named_base() const
|
||||||
|
{
|
||||||
|
if (this->seen_)
|
||||||
|
return this;
|
||||||
|
this->seen_ = true;
|
||||||
|
const Type* ret = this->type_->base();
|
||||||
|
this->seen_ = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return whether this is an error type. We have to be careful about
|
||||||
|
// circular type definitions, which are invalid but may be seen here.
|
||||||
|
|
||||||
|
bool
|
||||||
|
Named_type::is_named_error_type() const
|
||||||
|
{
|
||||||
|
if (this->seen_)
|
||||||
|
return false;
|
||||||
|
this->seen_ = true;
|
||||||
|
bool ret = this->type_->is_error_type();
|
||||||
|
this->seen_ = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Add a method to this type.
|
// Add a method to this type.
|
||||||
|
|
||||||
Named_object*
|
Named_object*
|
||||||
|
|
|
@ -2457,6 +2457,17 @@ class Named_type : public Type
|
||||||
is_builtin() const
|
is_builtin() const
|
||||||
{ return this->location_ == BUILTINS_LOCATION; }
|
{ return this->location_ == BUILTINS_LOCATION; }
|
||||||
|
|
||||||
|
// Return the base type for this type.
|
||||||
|
Type*
|
||||||
|
named_base();
|
||||||
|
|
||||||
|
const Type*
|
||||||
|
named_base() const;
|
||||||
|
|
||||||
|
// Return whether this is an error type.
|
||||||
|
bool
|
||||||
|
is_named_error_type() const;
|
||||||
|
|
||||||
// Add a method to this type.
|
// Add a method to this type.
|
||||||
Named_object*
|
Named_object*
|
||||||
add_method(const std::string& name, Function*);
|
add_method(const std::string& name, Function*);
|
||||||
|
|
Loading…
Reference in New Issue