summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2018-05-13 16:57:42 +0200
committerDaniel Kolesa <d.kolesa@samsung.com>2018-05-13 17:06:12 +0200
commit1f4f7e859795c175fddcdceafc25ee89ac78511b (patch)
tree3cc21b8699753c2c96845bdbcc299ea41b16cdc9
parenta923a94f85f15b97397fc3a0f5bd9728a74b98f3 (diff)
downloadefl-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.c20
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);