📄 uno_lts.c
字号:
for (r = curgraph->locs; r; r = r->nxt) if (r->sm == t) return r->status; return 0;}voidcould_be_fct(char *s){ Graphs *g; for (g = graph; g; g = g->nxt) if (strcmp(s, g->fctnm) == 0) { if (debug) printf("uno: marking %s as fct in disguise\n", s); g->status |= 4; /* cannot tell when this fct is called */ break; }}static voidmark_locs(symentry_t *t, treenode *n, int status){ Graphs *g; SymRef *r; if (0) printf("%d: mark_locs %s -- status %d\n", n->hdr.line, t->nme->str, status); for (r = curgraph->locs; r; r = r->nxt) if (r->sm == t) { r->status |= (status & ~FCALL); if (n && (status & USEbeforedef)) r->n = n; return; } if (!(status & USE) || (status & FCALL)) return; for (g = graph; g; g = g->nxt) if (strcmp(t->nme->str, g->fctnm) == 0) { Gst *k; if (debug) printf("uno: status %d old status %d, decl_level %d marking %s at %s:%d as hide\n", status, g->status, t->decl_level, t->nme->str, n->hdr.fnm, n->hdr.line); g->status |= 4; /* cannot tell when this fct is called */ add_fcall(t, n, USE|HIDE); /* ptr to fct name */#if 1 if (Verbose) printf("%s:%d fct %s is called via ptr\n", n->hdr.fnm, n->hdr.line, t->nme->str); k = (Gst *) emalloc(sizeof(Gst)); k->gnm = find_graph(t->nme->str); k->nxt = frst; frst = k;#endif break; }}static voidana_locs(Graphs *g){ SymRef *r; if (uno != 4) return; if (g) for (r = g->locs; r; r = r->nxt) { /* status: USE||USEbeforedef|DEF|ALIAS */ if (r->status & ALIAS) continue; /* can't tell */ if (r->status & USEbeforedef) /* at least one use before def */ { if (r->status & DEREF) /* a local ptr, zero/non_zero test is ok */ { treenode *rn = r->n; if (r->n->hdr.type == TN_IF) rn = ((if_node *)r->n)->cond; if (simple_zero(r->sm, rn) || simple_nonzero(r->sm, rn)) { if (debug) uno_warn("[non-]zero test of uninit ptr", r->n, r->sm); continue; } } if (r->status & PARAM) { /* check if this is a fct name, if so mark g->status |= 4 */ could_be_fct(r->sm->nme->str); continue; } if (r->status & DEF) /* at least one def before use */ uno_warn("possibly uninitialized variable", r->n, r->sm); else { if (debug) printf("status: %d\n", r->status); uno_warn("uninitialized variable", r->n, r->sm); } continue; } if (usecheck) if (!(r->status & USE)) /* there may or may not be a DEF */ uno_warn("local variable never used (evaluated)", r->n, r->sm); }}static voidmark_defuse(symentry_t *t, treenode *n, int st){ SymRef *r; for (r = curgraph->def_use; r; r = r->nxt) if (r->sm == t) { r->status |= st; if (n && (st & DEREF)) r->n = n; return; } r = uno_getref(t); r->n = n; r->status = st; r->nxt = curgraph->def_use; curgraph->def_use = r;}static voidattach_nut(char *pref, symentry_t *t, treenode *n){ char nr[16]; char *newnut; Nuts *q; if (!t || !n) return; sprintf(nr, "%d", n->hdr.line); if (!n->hdr.fnm) n->hdr.fnm = "--"; newnut = (char *) emalloc( strlen(pref) + strlen("\t\t\t") + strlen(t->nme->str) + strlen(n->hdr.fnm) + strlen(nr) + 1); sprintf(newnut, "%s\t%s\t%s\t%s", pref, t->nme->str, n->hdr.fnm?n->hdr.fnm:"", nr); for (q = n->hdr.nuts; q; q = q->nxt) if (strcmp(q->nut, newnut) == 0) break; /* already there */ if (!q) { q = (Nuts *) emalloc(sizeof(Nuts)); q->nut = newnut; q->nxt = n->hdr.nuts; n->hdr.nuts = q; curgraph->hasnuts = 1; }}static voidadd_defs(symentry_t *t, treenode *n){ mark_defuse(t, n, DEF); attach_nut("D", t, n);}static voidadd_uses(symentry_t *t, treenode *n){ mark_defuse(t, n, USE); if (!on_glob(t)) { make_suspect(t, n, USE); /* use of non-ptrs only */ attach_nut("U", t, n); }}static voidadd_derefs(symentry_t *t, treenode *n){ mark_defuse(t, n, USE|DEREF); if (on_glob(t)) { make_suspect(t, n, USE|DEREF); /* pointer dereference */ attach_nut("R", t, n); }}#if 0static inton_uses(symentry_t *t){ SymRef *r; for (r = curgraph->def_use; r; r = r->nxt) if (r->sm == t) return (r->status & USE); return 0;}#endifstatic voidadd_safe(symentry_t *t, treenode *n){ SymRef *r; r = uno_getref(t); r->n = n; r->nxt = safe_stack->symrefs; safe_stack->symrefs = r;}static SymRef *add_gstack(symentry_t *t, treenode *n, int mark){ SymRef *r, *s, *lr; int x; uno_assert((int) dfstack, "no dfstack - add_gstack");/* if (is_enum_const(t)) return; */ if (debug) printf("\tadd_gstack %s [%s:%d] + %d\n", t->nme->str, n->hdr.fnm, n->hdr.line, mark); if (!dfstack->globrefs) /* empty list */ { r = uno_getref(t); r->n = n; r->status = mark; dfstack->globrefs = r; goto done; } lr = (SymRef *) 0; for (r = dfstack->globrefs; r; lr = r, r = r->nxt) /* keep list sorted */ { if (debug) printf("\t<%s> status: [%d]\n", r->sm->nme->str, r->status); x = strcmp(r->sm->nme->str, t->nme->str); if (x < 0) continue; if (x == 0) r->status |= mark; else { s = uno_getref(t); s->n = n; s->status = mark; s->nxt = r; /* insert before r */ if (!lr) /* at head of list */ dfstack->globrefs = s; else lr->nxt = s; r = s; } goto done; } /* fell off the end of the list - item should go at the end */ r = uno_getref(t); r->n = n; r->status = mark; lr->nxt = r; /* list had at least 1 item, so lr is set */done: if (!(r->status & DEF)) return r; return (SymRef *) 0;}static voidadd_stack(symentry_t *t, treenode *n) /* locals only */{ SymRef *r; uno_assert((int) dfstack, "no dfstack - add_stack"); r = uno_getref(t); r->n = n; r->nxt = dfstack->symrefs; dfstack->symrefs = r;}static voiddel_stack(symentry_t *t) /* locals only */{ SymRef *r, *or = (SymRef *) 0; if (dfstack) for (r = dfstack->symrefs; r; or = r, r = r->nxt) if (r->sm == t) { if (!or) dfstack->symrefs = r->nxt; else or->nxt = r->nxt; r->nxt = dfs_free; dfs_free = r; break; }}static inton_stack(symentry_t *t) /* locals only */{ SymRef *r; if (dfstack) for (r = dfstack->symrefs; r; r = r->nxt) if (r->sm == t) return 1; return 0;}static inton_safe(symentry_t *t){ SymRef *r; if (safe_stack) for (r = safe_stack->symrefs; r; r = r->nxt) if (r->sm == t) return 1; return 0;}intsnap_add(State *s, SymRef *r){ SymRef *t; for (t = s->snapshot; t; t = t->nxt) if (t->sm == r->sm && t->status == r->status) return 0; t = uno_getref(r->sm); t->status = r->status; t->n = r->n; t->nxt = s->snapshot; s->snapshot = t; return 1;}static SymRef *copy_list(SymRef *s){ SymRef *r; if (!s) return (SymRef *) 0; r = uno_getref(s->sm); r->n = s->n; r->status = s->status; r->s_val = s->s_val; r->nxt = copy_list(s->nxt); return r; /* maintains list in order */}static intrelevant(treenode *n){ if (!n) return 0; if (n->syment && (on_glob(n->syment) || on_stack(n->syment))) { if (debug) printf("---%s is relevant (%d)\n", n->syment->nme->str, on_glob(n->syment)); return 1; } if (n->hdr.which == LEAF_T) return 0; return relevant(n->lnode) || relevant(n->rnode);}static PathCond *copy_pc(PathCond *n){ PathCond *r; PathCond *s = n; while (s && !relevant(s->exp)) /* ! was missing... gjh 3/19/2002 */ s = s->nxt; if (!s) return (PathCond *) 0; r = getpathframe(); r->exp = s->exp; r->val = s->val; r->nxt = copy_pc(s->nxt); return r; /* maintains list in order */}static intin_lst(SymRef *list, SymRef *r){ SymRef *q; for (q = list; q; q = q->nxt) if (q->sm == r->sm && (q->status & DEF) == (r->status & DEF)) return 1; return 0;}static intsame_pc(State *s) /* for comments see 'covered(...)' */{ PathCond *r, *q, *lq; int cnt = 0; if (!pathcond) {here: if (!s->seennone) { s->seennone = 1; cnt++; if (debug) printf("seenone (%u)\n", pathcond); } goto done; } if (!s->pc) { s->pc = copy_pc(pathcond); s->ip = copy_pc(s->pc); if (!s->pc) /* nothing was relevant */ goto here; cnt++; if (debug) printf("first setting of pc and ip (%u, %u)\n", s->pc, s->ip); goto done; } for (r = pathcond; r; r = r->nxt) { if (!relevant(r->exp)) continue; for (q = s->pc; q; q = q->nxt) if (q->exp == r->exp && q->val == r->val) break; if (!q) { q = getpathframe(); q->exp = r->exp; q->val = r->val; q->nxt = s->pc; s->pc = q; cnt++; if (debug) printf("adding to pc\n"); } } lq = (PathCond *) 0; for (r = s->ip; r; r = r->nxt) { for (q = pathcond; q; q = q->nxt) if (q->exp == r->exp && q->val == r->val) break; if (!q) { if (!lq) s->ip = r->nxt; else lq->nxt = r->nxt; cnt++; if (debug) printf("adding to ip\n"); } else lq = r; }done: if (debug) { printf("PC Covered %s:\n", (cnt==0)?"yes":"no"); for (r = pathcond; r; r = r->nxt) { printf(" %s", x_stmnt(r->exp)); printf(" %s\n", x_stmnt(r->val)); } printf("PC:\n"); for (r = s->pc; r; r = r->nxt) { printf(" %s", x_stmnt(r->exp)); printf(" %s\n", x_stmnt(r->val)); } printf("IP:\n"); for (r = s->ip; r; r = r->nxt) { printf(" %s", x_stmnt(r->exp)); printf(" %s\n", x_stmnt(r->val)); } } return (cnt == 0);}static intcovered(State *s, SymRef *gr){ SymRef *r, *q, *lq; int cnt = 0;#if 0 this check secures coverage of global variables use only we are interested in U or R before D errors so the presence or absence of a DEF (1) on any gvar is important and determines its uniqueness we do not care about combinations of variables - just if individual variables have been seen with certain flags#endif /* 1: each var in gr must have appeared in at least one * previous visit with the same DEF status, as recorded * in a list s->gi stored at state s for this purpose */ if (!gr) { if (!s->seenempty) { s->seenempty = 1; cnt++; } goto done; } if (!(s->gi)) /* first visit */ { s->gi = copy_list(gr); /* seed initial visit list */ s->il = copy_list(gr); /* seed intersection list */ cnt++; goto done; } else for (r = gr; r; r = r->nxt) /* each var in gr (dfstack->globrefs) */ { for (q = s->gi; q; q = q->nxt) /* see if already covered in s->gi */ if (q->sm == r->sm && (r->status & DEF) == (q->status & DEF)) break; if (!q) /* not covered yet */ { q = uno_copy_ref(r); q->nxt = s->gi; s->gi = q; cnt++; } } /* 2: each var absent from gr must have been absent in at least one previous visit i.e., must be absent from the intersection list */ lq = (SymRef *) 0; for (r = s->il; r; r = r->nxt) { if (!in_lst(gr, r)) /* should drop r from il */ { if (!lq) s->il = r->nxt; else lq->nxt = r->nxt; cnt++; } else lq = r; /* good, it's there */ }done: if (debug) { printf("Covered %s:\n", (cnt==0)?"yes":"no"); for (r = gr; r; r = r->nxt) printf(" %s %d\n", r->sm->nme->str, r->status); printf("GI:\n"); for (r = s->gi; r; r = r->nxt) printf(" %s %d\n", r->sm->nme->str, r->status); printf("IL:\n"); for (r = s->il; r; r = r->nxt) printf(" %s %d\n", r->sm->nme->str, r->status); } return (cnt == 0); /* true if nothing needed adding */}static intdfs_push(State *s){ DfStack *d; SymRef *r, *n; int any_added = 0; d = uno_getframe(); if (debug) printf(" --dfs_push <%u>\n", dfstack); if (dfstack) { for (r = dfstack->symrefs; r; r = r->nxt) { if (debug) printf("\t--cp symrefs %s status %d\n", r->sm->nme->str, r->status); if (snap_add(s, r)) /* local var not tracked from s before */ { n = uno_getref(r->sm); n->n = r->n; n->nxt = d->symrefs; d->symrefs = n; any_added = 1; } } if (!covered(s, dfstack->globrefs)) any_added = 1; /* don't combine with next if */ if (!same_pc(s)) /* matching path conditions */ any_added = 1; if (any_added) d->globrefs = copy_list(dfstack->globrefs); /* preserves order */ } d->nxt = dfstack; dfstack = d; d = uno_getframe(); if (safe_stack) for (r = safe_stack->symrefs; r; r = r->nxt) /* copy sym refs */ { n = uno_getref(r->sm); n->n = r->n; n->nxt = d->symrefs; d->symrefs = n; } d->nxt = safe_stack;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -