diff options
author | Florian Brosch <flo.brosch@gmail.com> | 2014-09-10 13:07:11 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2018-12-18 09:16:01 +0100 |
commit | 2f6febbba3051cb9df862f823569d641e35eca1c (patch) | |
tree | 815d272a32724ac75bf20d39d6109404f7ee87d5 | |
parent | a06c2632071f9d4fd7c71a70e7d354a95c3d665b (diff) | |
download | vala-2f6febbba3051cb9df862f823569d641e35eca1c.tar.gz |
vala: Break possible endless loop in SymbolResolver.get_type_for_struct()
Required to deal with invalid code containing base struct cycles.
Fixes https://gitlab.gnome.org/GNOME/vala/issues/444
-rw-r--r-- | vala/valasymbolresolver.vala | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala index db31aa0ce..d24cc06bf 100644 --- a/vala/valasymbolresolver.vala +++ b/vala/valasymbolresolver.vala @@ -88,7 +88,7 @@ public class Vala.SymbolResolver : CodeVisitor { if (base_type != null) { if (base_type.is_subtype_of (st)) { st.error = true; - Report.error (base_type.source_reference, "Base struct cycle (`%s' and `%s')".printf (st.get_full_name (), base_type.get_full_name ())); + Report.error (st.source_reference, "Base struct cycle (`%s' and `%s')".printf (st.get_full_name (), base_type.get_full_name ())); return; } } @@ -263,10 +263,33 @@ public class Vala.SymbolResolver : CodeVisitor { } } + bool has_base_struct_cycle (Struct st, Struct loop_st) { + if (!(st.base_type is UnresolvedType)) { + return false; + } + + var sym = resolve_symbol (((UnresolvedType) st.base_type).unresolved_symbol); + unowned Struct? base_struct = sym as Struct; + if (base_struct == null) { + return false; + } + + if (base_struct == loop_st) { + return true; + } + + return has_base_struct_cycle (base_struct, loop_st); + } + DataType get_type_for_struct (Struct st, Struct base_struct) { if (st.base_type != null) { // make sure that base type is resolved + if (has_base_struct_cycle (st, st)) { + // recursive declaration in base type + return new StructValueType (st); + } + if (current_scope == st.scope) { // recursive declaration in generic base type return new StructValueType (st); |