aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2010-12-24 00:13:35 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2010-12-24 00:13:35 +0000
commitae4aefdca359929e167b923949ba17c0c066010a (patch)
treedd07a8b32ace42a720939dce1f9528d84052efe1
parente99776d82aca5ed5ee7bbe2ad2f5f6191017110b (diff)
downloadgcc-ae4aefdca359929e167b923949ba17c0c066010a.zip
gcc-ae4aefdca359929e167b923949ba17c0c066010a.tar.gz
gcc-ae4aefdca359929e167b923949ba17c0c066010a.tar.bz2
Avoid endless loop inheriting interfaces.
From-SVN: r168216
-rw-r--r--gcc/go/gofrontend/types.cc27
1 files changed, 25 insertions, 2 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 1739965..2278c94 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -5548,7 +5548,7 @@ Interface_type::finalize_methods()
const Typed_identifier* p = &this->methods_->at(from);
if (!p->name().empty())
{
- size_t i = 0;
+ size_t i;
for (i = 0; i < to; ++i)
{
if (this->methods_->at(i).name() == p->name())
@@ -5594,7 +5594,30 @@ Interface_type::finalize_methods()
q != methods->end();
++q)
{
- if (q->name().empty() || this->find_method(q->name()) == NULL)
+ if (q->name().empty())
+ {
+ if (q->type() == p->type())
+ error_at(p->location(), "interface inheritance loop");
+ else
+ {
+ size_t i;
+ for (i = from + 1; i < this->methods_->size(); ++i)
+ {
+ const Typed_identifier* r = &this->methods_->at(i);
+ if (r->name().empty() && r->type() == q->type())
+ {
+ error_at(p->location(),
+ "inherited interface listed twice");
+ break;
+ }
+ }
+ if (i == this->methods_->size())
+ this->methods_->push_back(Typed_identifier(q->name(),
+ q->type(),
+ p->location()));
+ }
+ }
+ else if (this->find_method(q->name()) == NULL)
this->methods_->push_back(Typed_identifier(q->name(), q->type(),
p->location()));
else