/* * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ /* $Header$ */ /* Lint evaluation order checking */ #include "lint.h" #ifdef LINT #include /* for st_free */ #include "assert.h" #include "arith.h" /* definition arith */ #include "label.h" /* definition label */ #include "expr.h" #include "idf.h" #include "def.h" #include "code.h" /* RVAL etc */ #include "LLlex.h" #include "Lpars.h" #include "stack.h" #include "type.h" #include "level.h" #include "nofloat.h" #include "l_lint.h" #include "l_state.h" extern char *symbol2str(); check_and_merge(espp, esp, com_oper) struct expr_state **espp, *esp; { /* Checks for undefined evaluation orders in case of a commutative operator. * In addition the sets of used and set variables of both expressions are * united. * *espp will be pointing to this new list. esp is used for this list. */ register struct expr_state **pp, *p1, *p2; for (p1 = *espp; p1; p1 = p1->next) { p2 = esp; pp = &esp; while (p2) { if ( /* p1 and p2 are the same */ p1->es_idf == p2->es_idf && p1->es_offset == p2->es_offset ) { if (com_oper) check_ev_order(p1, p2, com_oper); p1->es_used |= p2->es_used; p1->es_set |= p2->es_set; *pp = p2->next; free_expr_state(p2); p2 = *pp; } else { pp = &p2->next; p2 = p2->next; } } } /* The rest of the list esp is pointing to, is put in front of the list * *espp is now pointing to. * *espp will be pointing to this new list. */ if (!esp) return; p1 = *espp; *espp = esp; while (esp->next) esp = esp->next; esp->next = p1; } check_ev_order(esp1, esp2, com_oper) struct expr_state *esp1, *esp2; { if ( (esp1->es_used && esp2->es_set) || (esp1->es_set && esp2->es_used) || (esp1->es_set && esp2->es_set) ) { warning("result of %s depends on evaluation order on %s", symbol2str(com_oper), esp1->es_idf->id_text); } } add_expr_state(value, to_state, espp) struct value value; struct expr_state **espp; { register struct expr_state *esp = *espp; ASSERT(value.vl_class == Name); while ( esp && !( esp->es_idf == value.vl_data.vl_idf && esp->es_offset == value.vl_value ) ) { esp = esp->next; } if (!esp) { /* create new expr_state */ esp = new_expr_state(); esp->es_idf = value.vl_data.vl_idf; esp->es_offset = value.vl_value; esp->next = *espp; *espp = esp; } if (to_state == SET) esp->es_set = 1; else /* USED */ esp->es_used = 1; } #endif LINT