Avoid infinite loop in field_reference.
From-SVN: r170457
This commit is contained in:
parent
acabc10c98
commit
cd34c84360
2 changed files with 40 additions and 2 deletions
|
@ -3583,7 +3583,8 @@ Struct_type::field_reference(Expression* struct_expr, const std::string& name,
|
|||
source_location location) const
|
||||
{
|
||||
unsigned int depth;
|
||||
return this->field_reference_depth(struct_expr, name, location, &depth);
|
||||
return this->field_reference_depth(struct_expr, name, location, NULL,
|
||||
&depth);
|
||||
}
|
||||
|
||||
// Return an expression for a field, along with the depth at which it
|
||||
|
@ -3593,6 +3594,7 @@ Field_reference_expression*
|
|||
Struct_type::field_reference_depth(Expression* struct_expr,
|
||||
const std::string& name,
|
||||
source_location location,
|
||||
Saw_named_type* saw,
|
||||
unsigned int* depth) const
|
||||
{
|
||||
const Struct_field_list* fields = this->fields_;
|
||||
|
@ -3628,13 +3630,41 @@ Struct_type::field_reference_depth(Expression* struct_expr,
|
|||
if (st == NULL)
|
||||
continue;
|
||||
|
||||
Saw_named_type* hold_saw = saw;
|
||||
Saw_named_type saw_here;
|
||||
Named_type* nt = pf->type()->named_type();
|
||||
if (nt == NULL)
|
||||
nt = pf->type()->deref()->named_type();
|
||||
if (nt != NULL)
|
||||
{
|
||||
Saw_named_type* q;
|
||||
for (q = saw; q != NULL; q = q->next)
|
||||
{
|
||||
if (q->nt == nt)
|
||||
{
|
||||
// If this is an error, it will be reported
|
||||
// elsewhere.
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (q != NULL)
|
||||
continue;
|
||||
saw_here.next = saw;
|
||||
saw_here.nt = nt;
|
||||
saw = &saw_here;
|
||||
}
|
||||
|
||||
// Look for a reference using a NULL struct expression. If we
|
||||
// find one, fill in the struct expression with a reference to
|
||||
// this field.
|
||||
unsigned int subdepth;
|
||||
Field_reference_expression* sub = st->field_reference_depth(NULL, name,
|
||||
location,
|
||||
saw,
|
||||
&subdepth);
|
||||
|
||||
saw = hold_saw;
|
||||
|
||||
if (sub == NULL)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1980,9 +1980,17 @@ class Struct_type : public Type
|
|||
do_export(Export*) const;
|
||||
|
||||
private:
|
||||
// Used to avoid infinite loops in field_reference_depth.
|
||||
struct Saw_named_type
|
||||
{
|
||||
Saw_named_type* next;
|
||||
Named_type* nt;
|
||||
};
|
||||
|
||||
Field_reference_expression*
|
||||
field_reference_depth(Expression* struct_expr, const std::string& name,
|
||||
source_location, unsigned int* depth) const;
|
||||
source_location, Saw_named_type*,
|
||||
unsigned int* depth) const;
|
||||
|
||||
static Type*
|
||||
make_struct_type_descriptor_type();
|
||||
|
|
Loading…
Add table
Reference in a new issue