diff options
author | Daniel Kolesa <d.kolesa@samsung.com> | 2018-05-13 16:57:42 +0200 |
---|---|---|
committer | Daniel Kolesa <d.kolesa@samsung.com> | 2018-05-13 17:06:12 +0200 |
commit | 1f4f7e859795c175fddcdceafc25ee89ac78511b (patch) | |
tree | 3cc21b8699753c2c96845bdbcc299ea41b16cdc9 | |
parent | a923a94f85f15b97397fc3a0f5bd9728a74b98f3 (diff) | |
download | efl-1f4f7e859795c175fddcdceafc25ee89ac78511b.tar.gz |
eolian: cycle checks for all toplevel decls in static analyzer
This is necessary because e.g. typedecls can introduce cycles into
the system by self-referencing in struct field expressions.
-rw-r--r-- | src/lib/eolian/database_check.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/lib/eolian/database_check.c b/src/lib/eolian/database_check.c index 75e4e8dcec..c1eb899e2e 100644 --- a/src/lib/eolian/database_check.c +++ b/src/lib/eolian/database_check.c @@ -5,6 +5,16 @@ #include "eo_lexer.h" #include "eolian_priv.h" +static Eina_Bool +_check_cycle(Eina_Hash *chash, const Eolian_Object *obj) +{ + /* need to check this for classes, typedecls, vars (toplevel objects) */ + if (eina_hash_find(chash, &obj)) + return EINA_TRUE; + eina_hash_add(chash, &obj, obj); + return EINA_FALSE; +} + static void _check_class(const Eolian_Class *cl, Eina_Hash *depset, Eina_Hash *chash); static void _check_typedecl(const Eolian_Typedecl *tp, Eina_Hash *depset, @@ -112,10 +122,8 @@ _check_function(const Eolian_Function *f, Eina_Hash *depset, Eina_Hash *chash) static void _check_class(const Eolian_Class *cl, Eina_Hash *depset, Eina_Hash *chash) { - /* kill cyclic dependencies before stack overflow */ - if (eina_hash_find(chash, &cl)) + if (_check_cycle(chash, &cl->base)) return; - eina_hash_add(chash, &cl, cl); if (!eina_hash_find(depset, &cl->base.unit)) eina_hash_add(depset, &cl->base.unit, cl->base.unit); @@ -154,6 +162,9 @@ _check_class(const Eolian_Class *cl, Eina_Hash *depset, Eina_Hash *chash) static void _check_typedecl(const Eolian_Typedecl *tp, Eina_Hash *depset, Eina_Hash *chash) { + if (_check_cycle(chash, &tp->base)) + return; + if (!eina_hash_find(depset, &tp->base.unit)) eina_hash_add(depset, &tp->base.unit, tp->base.unit); @@ -189,6 +200,9 @@ _check_typedecl(const Eolian_Typedecl *tp, Eina_Hash *depset, Eina_Hash *chash) static void _check_variable(const Eolian_Variable *v, Eina_Hash *depset, Eina_Hash *chash) { + if (_check_cycle(chash, &v->base)) + return; + if (!eina_hash_find(depset, &v->base.unit)) eina_hash_add(depset, &v->base.unit, v->base.unit); |