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.
This commit is contained in:
Daniel Kolesa 2018-05-13 16:57:42 +02:00
parent a923a94f85
commit 1f4f7e8597
1 changed files with 17 additions and 3 deletions

View File

@ -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);