123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* $Id$ */
- /* Lint evaluation order checking */
- #include "lint.h"
- #ifdef LINT
- #include <alloc.h> /* for st_free */
- #include "interface.h"
- #include "assert.h"
- #ifdef ANSI
- #include <flt_arith.h>
- #endif /* ANSI */
- #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 "l_lint.h"
- #include "l_state.h"
- extern char *symbol2str();
- PRIVATE check_ev_order();
- check_and_merge(expr, espp, esp)
- struct expr *expr;
- struct expr_state **espp, *esp;
- {
- /* Checks for undefined evaluation orders in case of a non-sequencing 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;
- int oper = expr->OP_OPER;
- int is_sequencer =
- (oper == '?' || oper == OR || oper == AND || oper ==',');
- for (p1 = *espp; p1; p1 = p1->next) {
- /* scan the list esp for the same variable */
- p2 = esp;
- pp = &esp;
- while (p2) {
- if ( /* p1 and p2 refer to the same location */
- p1->es_idf == p2->es_idf
- && p1->es_offset == p2->es_offset
- ) {
- /* check */
- if (!is_sequencer)
- check_ev_order(p1, p2, expr);
- /* merge the info */
- p1->es_used |= p2->es_used;
- p1->es_referred |= p2->es_referred;
- p1->es_set |= p2->es_set;
- /* and remove the entry from esp */
- *pp = p2->next;
- free_expr_state(p2);
- p2 = *pp;
- }
- else {
- /* skip over the entry in esp */
- pp = &p2->next;
- p2 = p2->next;
- }
- }
- }
- /* If there is anything left in the list esp, this is put in
- front of the list *espp is now pointing to, and *espp will be
- left pointing to this new list.
- */
- if (!esp)
- return;
- p1 = *espp;
- *espp = esp;
- while (esp->next)
- esp = esp->next;
- esp->next = p1;
- }
- PRIVATE
- check_ev_order(esp1, esp2, expr)
- struct expr_state *esp1, *esp2;
- struct expr *expr;
- {
- if ( (esp1->es_used && esp2->es_set)
- || (esp1->es_set && esp2->es_used)
- || (esp1->es_set && esp2->es_set)
- ) {
- expr_warning(expr,
- "result of %s depends on evaluation order on %s",
- symbol2str(expr->OP_OPER),
- esp1->es_idf->id_text);
- }
- }
- #endif /* LINT */
|