aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-04-14 06:55:20 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-04-14 06:55:20 -0700
commitd3064bd9a5116f57e60f3da91ffcf3f1a58b9ab0 (patch)
tree0a85191b0044e42e18d181d2ef71e5ccd696823e
parent71937179ae771612b60fd7c5b08212e38c6f0ddb (diff)
downloadegawk-d3064bd9a5116f57e60f3da91ffcf3f1a58b9ab0.tar.gz
egawk-d3064bd9a5116f57e60f3da91ffcf3f1a58b9ab0.tar.bz2
egawk-d3064bd9a5116f57e60f3da91ffcf3f1a58b9ab0.zip
@let: add self-checks to symbol management code.
* symbol.c (remove_common, install): Check the sanity of the installation and removal of parameter and alias symbols. This is purely compile-time so the cycles are worth it.
-rw-r--r--symbol.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/symbol.c b/symbol.c
index 9f40568a..f2a0ad89 100644
--- a/symbol.c
+++ b/symbol.c
@@ -247,10 +247,16 @@ remove_common(NODE *p)
tmp = make_string(p->vname, strlen(p->vname));
tmp2 = in_array(table, tmp);
- if (tmp2 != NULL && tmp2->dup_ent != NULL)
+ if (tmp2 == NULL) {
+ /* nothing: diagnosing this leads to certain false positives. */
+ } else if (tmp2->dup_ent == p) {
tmp2->dup_ent = tmp2->dup_ent->dup_ent;
- else
+ } else if (tmp2->dup_ent == NULL && tmp2 == p) {
(void) assoc_remove(table, tmp);
+ } else {
+ fatal(_("LIFO local variable allocation not observed (p %p, found %p, dup %p)"),
+ p, tmp2, tmp2->dup_ent);
+ }
unref(tmp);
}
@@ -436,10 +442,17 @@ install(const char *name, NODE *parm, NODETYPE type)
}
if (type == Node_param_list || type == Node_alias) {
+ NODE *dchk;
r->dup_ent = NULL;
prev = in_array(table, n_name);
if (prev == NULL)
goto simple;
+ if (prev == r)
+ fatal("primary symbol %s (%p/ type %d) entered twice into symbol table",
+ r->vname, r, r->type);
+ for (dchk = prev->dup_ent; dchk != NULL; dchk = dchk->dup_ent)
+ if (dchk == r)
+ fatal("shadowing symbol entered twice into symbol table");
r->dup_ent = prev->dup_ent;
prev->dup_ent = r;
unref(n_name);