more lint code
authordick <none@none>
Mon, 6 Mar 1989 15:17:39 +0000 (15:17 +0000)
committerdick <none@none>
Mon, 6 Mar 1989 15:17:39 +0000 (15:17 +0000)
lang/cem/cemcom/Makefile
lang/cem/cemcom/ch7bin.c
lang/cem/cemcom/declar.g
lang/cem/cemcom/idf.c
lang/cem/cemcom/l_lint.c
lang/cem/cemcom/l_state.str
lang/cem/cemcom/l_states.c
lang/cem/cemcom/program.g
lang/cem/cemcom/stack.c
lang/cem/cemcom/statement.g

index b964ac1..9a87abd 100644 (file)
@@ -929,7 +929,6 @@ declar.o: field.h
 declar.o: file_info.h
 declar.o: idf.h
 declar.o: l_lint.h
-declar.o: l_state.h
 declar.o: label.h
 declar.o: level.h
 declar.o: lint.h
@@ -953,7 +952,6 @@ statement.o: expr.h
 statement.o: file_info.h
 statement.o: idf.h
 statement.o: l_lint.h
-statement.o: l_state.h
 statement.o: label.h
 statement.o: lint.h
 statement.o: nobitfield.h
@@ -986,7 +984,7 @@ program.o: def.h
 program.o: expr.h
 program.o: file_info.h
 program.o: idf.h
-program.o: l_state.h
+program.o: l_lint.h
 program.o: label.h
 program.o: lint.h
 program.o: nobitfield.h
index 0225351..72ee4ac 100644 (file)
@@ -280,10 +280,15 @@ ch7bin(expp, oper, expr)
                break;
 
        case ',':
-               if (is_cp_cst(*expp))
+               if (is_cp_cst(*expp)) {
+#ifdef LINT
+                       hwarning("constant expression ignored");
+#endif LINT
                        *expp = expr;
-               else
+               }
+               else {
                        *expp = new_oper(expr->ex_type, *expp, oper, expr);
+               }
                (*expp)->ex_flags |= EX_COMMA;
                break;
        }
index 92a501e..c14676c 100644 (file)
@@ -27,7 +27,6 @@
 #include       "level.h"
 #ifdef LINT
 #include       "l_lint.h"
-#include       "l_state.h"
 #endif LINT
 
 extern char options[];
index e648e83..64d4abb 100644 (file)
@@ -353,7 +353,7 @@ declare_idf(ds, dc, lvl)
                newdef->df_file = idf->id_file;
                newdef->df_line = idf->id_line;
 #ifdef LINT
-               newdef->df_set = (type->tp_fund == ARRAY);
+               newdef->df_set = 0;
                newdef->df_firstbrace = 0;
 #endif LINT
 
@@ -490,11 +490,17 @@ global_redecl(idf, new_sc, tp)
                                error("cannot redeclare %s to static",
                                        idf->id_text);
                        else    {
+#ifdef LINT                    /* warn unconditionally */
+                               warning("%s redeclared to static",
+                                               idf->id_text);
+#else  LINT
 #ifndef NOROPTION
+                               /* warn conditionally */
                                if (options['R'])
                                        warning("%s redeclared to static",
                                                idf->id_text);
-#endif
+#endif NOROPTION
+#endif LINT
                                def->df_sc = STATIC;
                        }
                        break;
index b591e11..f8d0de9 100644 (file)
@@ -255,14 +255,6 @@ oper2state(expr, val, used)
        case GREATEREQ:
        case EQUAL:
        case NOTEQUAL:
-               lint_relop(left, right, oper);
-               lint_relop(right, left, 
-                       oper == '<' ? '>' :
-                       oper == '>' ? '<' :
-                       oper == LESSEQ ? GREATEREQ :
-                       oper == GREATEREQ ? LESSEQ :
-                       oper
-               );
                goto dyadic;
 
        /* dyadic operators */
@@ -338,11 +330,16 @@ expr_ignored(expr)
                break;
 
        case Value:
-               hwarning("value as statement");
+               if (expr->VL_CLASS == Const) {
+                       hwarning("constant expression ignored");
+               }
+               else {
+                       hwarning("value ignored");
+               }
                break;
 
        default:                        /* String Float */
-               hwarning("constant as statement");
+               hwarning("constant ignored");
                break;
        }
 }
index 2ef9191..5f8f1b2 100644 (file)
  * control of the program.
  */
 
+#define        TEST_VAR        0               /* not a constant */
+#define        TEST_TRUE       1               /* always true */
+#define        TEST_FALSE      2               /* always false */
 
-struct switch_states {
+struct loop_state {                    /* used in lint_end_state only */
+       int lps_test;                   /* is the test a constant? */
+       struct state *lps_body;
+       struct state *lps_loop;
+};
+
+struct switch_state {                  /* used in lint_end_state only */
        struct state *sws_case;
        struct state *sws_break;
        int sws_default_met;
 };
 
+/*     This union describes the (possibly incomplete) state at the end of the
+       mentioned construct.
+*/
+union lint_end_state {                 /* used in lint_stack_entry only */
+       struct state *ule_if;
+       struct loop_state ule_loop;
+       struct switch_state ule_switch;
+};
+
 struct lint_stack_entry {
        struct lint_stack_entry *next;
        struct lint_stack_entry *ls_previous;
-       short ls_class;         /* IF, WHILE, DO, FOR, SWITCH, CASE */
        int ls_level;
-       struct state *ls_current;               /* used by all classes */
-       union {
-               struct state *u_if_state;       /* used for IF-class */
-               struct state *u_end;            /* used for loop-classes */
-               struct switch_states u_switch;
-       } ls_states;    /* not used for CASE-class */
+       struct state *ls_current;       /* used by all classes */
+       short ls_class;                 /* IF, WHILE, DO, FOR, SWITCH, CASE */
+       union lint_end_state ls_end;
 };
 
-/* macros to access the union */
-#define LS_IF_STATE    ls_states.u_if_state
-#define LS_END         ls_states.u_end
-#define LS_CASE                ls_states.u_switch.sws_case
-#define LS_BREAK       ls_states.u_switch.sws_break
-#define LS_DEFAULT_MET ls_states.u_switch.sws_default_met
-
 /* ALLOCDEF "lint_stack_entry" 10 */
 
+/* macros to access the union */
+#define LS_IF          ls_end.ule_if
+#define LS_TEST                ls_end.ule_loop.lps_test
+#define LS_BODY                ls_end.ule_loop.lps_body
+#define LS_LOOP                ls_end.ule_loop.lps_loop
+#define LS_CASE                ls_end.ule_switch.sws_case
+#define LS_BREAK       ls_end.ule_switch.sws_break
+#define LS_DEFAULT_MET ls_end.ule_switch.sws_default_met
+
+/* describes a branch in the program, with its local idfs */
 struct state {
        struct state *next;             /* only used by memory allocator */
        struct auto_def *st_auto_list;
@@ -50,6 +67,7 @@ struct state {
 
 /* ALLOCDEF "state" 15 */
 
+/* describes the state of a local idf in a given branch of the program */
 struct auto_def {
        struct auto_def *next;
        struct idf *ad_idf;
@@ -61,13 +79,14 @@ struct auto_def {
 
 /* ALLOCDEF "auto_def" 20 */
 
-struct expr_state {
+/* describes the state of an idf during expression evaluation */
+struct expr_state {                    /*actually concerns idfs only */
        struct expr_state *next;
-       struct idf *es_idf;
+       struct idf *es_idf;             /* the idf with its offset */
        arith es_offset;
-       int es_used;
-       int es_referred;
-       int es_set;
+       int es_used;                    /* value has been used */
+       int es_referred;                /* address has been taken */
+       int es_set;                     /* has been assigned to */
 };
 
 /* ALLOCDEF "expr_state" 20 */
index ad47b97..78c4860 100644 (file)
@@ -13,8 +13,8 @@
 #include       "interface.h"
 #include       "assert.h"
 #include       "debug.h"
-#include       "arith.h"       /* definition arith */
-#include       "label.h"       /* definition label */
+#include       "arith.h"
+#include       "label.h"
 #include       "expr.h"
 #include       "idf.h"
 #include       "def.h"
 #include       "l_comment.h"
 #include       "l_outdef.h"
 
-#define min(a, b) ((a) < (b) ? (a) : (b))
+#ifdef DEBUG
+#define        dbg_lint_stack(m)       /*print_lint_stack(m)   /* or not */
+#else
+#define        dbg_lint_stack(m)
+#endif DEBUG
 
 extern char *symbol2str();
 extern char *func_name;
 extern struct type *func_type;
 extern int func_notypegiven;
 extern char loptions[];
+extern struct stack_level *local_level;
 
 /* global variables for the lint_stack */
-PRIVATE struct lint_stack_entry stack_bottom;
-PRIVATE struct lint_stack_entry *top_ls = &stack_bottom;
+PRIVATE struct lint_stack_entry *top_ls;
 
 /* global variables for the brace stack */
 PRIVATE int brace_count;
-PRIVATE struct brace brace_bottom;
-PRIVATE struct brace *top_br = &brace_bottom;
+PRIVATE struct brace *top_br;
+
+/* global variables for the function return */
+PRIVATE int valreturned;               /* see l_lint.h */
+PRIVATE int return_warned;
 
 PRIVATE end_brace();
 PRIVATE lint_1_local();
 PRIVATE lint_1_global();
+PRIVATE start_loop_stmt();
 PRIVATE check_autos();
-PRIVATE struct auto_def *copy_st_auto_list();
-PRIVATE free_st_auto_list();
+PRIVATE struct auto_def *copy_auto_list();
+PRIVATE free_auto_list();
 PRIVATE struct state *copy_state();
 PRIVATE Free_state();
 PRIVATE remove_settings();
 PRIVATE struct auto_def *merge_autos();
 PRIVATE merge_states();
 PRIVATE struct lint_stack_entry *find_wdf(), *find_wdfc(), *find_cs();
-PRIVATE cont_break_merge();
+PRIVATE cont_merge();
+PRIVATE break_merge();
+PRIVATE struct lint_stack_entry *mk_lint_stack_entry();
 PRIVATE lint_push();
 PRIVATE lint_pop();
 
 lint_init_stack()
 {
-/* Allocate some memory for the global stack_bottom
- */
-       stack_bottom.ls_current = new_state();
+/*     Allocate memory for the global lint-stack elements.
+*/
+       top_ls = new_lint_stack_entry();
+       top_ls->ls_current = new_state();
 }
 
 lint_start_local()
 {
        register struct brace *br = new_brace();
 
+       dbg_lint_stack("lint_start_local");
        brace_count++;
        br->br_count = brace_count;
        br->br_level = level;
@@ -82,24 +94,20 @@ lint_start_local()
        top_br = br;
 }      
 
-lint_local_level(stl)
+lint_end_local(stl)
        struct stack_level *stl;
 {
+
+       dbg_lint_stack("lint_end_local");
        if (s_NOTREACHED) {
                top_ls->ls_current->st_notreached = 1;
+               top_ls->ls_current->st_warned = 0;
                s_NOTREACHED = 0;
        }
 
        if (top_ls->ls_class == CASE && level == top_ls->ls_level) {
+               /* supply missing  break;  at end of switch */
                lint_break_stmt();
-                       /* To prevent a warning for the case
-                        *      switch (cond) {
-                        *      int i;
-                        *      case 0:
-                        *              i = 0;
-                        *              use(i);
-                        *      }
-                        */
        }
 
        check_autos();
@@ -111,6 +119,7 @@ end_brace(stl)
        struct stack_level *stl;
 {
        /*      Check if static variables and labels are used and/or set.
+               Automatic vars have already been checked by check_autos().
        */
        register struct stack_entry *se = stl->sl_entry;
        register struct brace *br;
@@ -125,6 +134,7 @@ end_brace(stl)
                se = se->next;
        }
 
+       /* remove entry from brace stack */
        br = top_br;
        top_br = br->next;
        free_brace(br);
@@ -159,11 +169,12 @@ lint_1_local(idf, def)
        }
 }
 
-lint_global_level(stl)
+lint_end_global(stl)
        struct stack_level *stl;
 {
        register struct stack_entry *se = stl->sl_entry;
 
+       dbg_lint_stack("lint_end_global");
        ASSERT(level == L_GLOBAL);
        while (se) {
                register struct idf *idf = se->se_idf;
@@ -198,38 +209,38 @@ lint_1_global(idf, def)
                         */
                        output_use(idf);
                }
-               else {
-                       if (sc == STATIC) {
-                               if (def->df_set) {
-                                       def_warning(def,
-                                               "%s %s %s set but not used",
-                                               symbol2str(sc),
-                                               symbol2str(fund),
-                                               idf->id_text);
-                               }
-                               else {
-                                       def_warning(def,
-                                               "%s %s %s not used anywhere",
-                                               symbol2str(sc),
-                                               symbol2str(fund),
-                                               idf->id_text);
-                               }
+
+               if (sc == STATIC && !def->df_used) {
+                       if (def->df_set) {
+                               def_warning(def,
+                                       "%s %s %s set but not used",
+                                       symbol2str(sc),
+                                       symbol2str(fund),
+                                       idf->id_text);
+                       }
+                       else {
+                               def_warning(def,
+                                       "%s %s %s not used anywhere",
+                                       symbol2str(sc),
+                                       symbol2str(fund),
+                                       idf->id_text);
                        }
-                       if (loptions['x']) {
-                               register char *fn = def->df_file;
-
-                               if (    (sc == EXTERN || sc == GLOBAL)
-                               &&      def->df_alloc == 0
-                               &&      !def->df_set
-                               &&      !def->df_initialized
-                               &&      strcmp(&fn[strlen(fn)-2], ".c") == 0
-                               ) {
-                                       def_warning(def,
-                                               "%s %s %s not used anywhere",
-                                               symbol2str(sc),
-                                               symbol2str(fund),
-                                               idf->id_text);
-                               }
+               }
+               if (loptions['x']) {
+                       register char *fn = def->df_file;
+
+                       if (    (sc == EXTERN || sc == GLOBAL)
+                       &&      def->df_alloc == 0
+                       &&      !def->df_set
+                       &&      !def->df_initialized
+                       &&      !def->df_used
+                       &&      strcmp(&fn[strlen(fn)-2], ".c") == 0
+                       ) {
+                               def_warning(def,
+                                       "%s %s %s not used anywhere",
+                                       symbol2str(sc),
+                                       symbol2str(fund),
+                                       idf->id_text);
                        }
                }
                break;
@@ -242,42 +253,44 @@ change_state(idf, to_state)
 {
 /* Changes the state of the variable identified by idf in the current state
  * on top of the stack.
- * For non-automatic variables, the fields in the def-descriptor are set too.
+ * The fields in the def-descriptor are set too.
  */
        register struct def *def = idf->id_def;
        register struct auto_def *a = top_ls->ls_current->st_auto_list;
 
-       if (def) {
-               switch (to_state) {
-               case SET:
-                       def->df_set = 1;
-                       break;
-               case USED:
-                       def->df_used = 1;
-                       break;
-               }
+       ASSERT(def);
 
-               if (def->df_firstbrace == 0) {
-                       def->df_firstbrace = brace_count;
-                       def->df_minlevel = level;
-               }
-               else {
-                       register struct brace *br = top_br;
+       switch (to_state) {
+       case SET:
+               def->df_set = 1;
+               break;
+       case USED:
+               def->df_used = 1;
+               break;
+       }
 
-                       /*      find the smallest brace range from which
-                               firstbrace is visible
-                       */
-                       while (br && br->br_count > def->df_firstbrace) {
-                               br = br->next;
-                       }
-                       ASSERT(br && def->df_minlevel >= br->br_level);
-                       def->df_minlevel = br->br_level;
+       /* adjust minimum required brace level */
+       if (def->df_firstbrace == 0) {
+               def->df_firstbrace = brace_count;
+               def->df_minlevel = level;
+       }
+       else {
+               register struct brace *br = top_br;
+
+               /*      find the smallest brace range from which
+                       firstbrace is visible
+               */
+               while (br && br->br_count > def->df_firstbrace) {
+                       br = br->next;
                }
+               ASSERT(br && def->df_minlevel >= br->br_level);
+               def->df_minlevel = br->br_level;
        }
 
+       /* search auto_list */
        while(a && a->ad_idf != idf)
                a = a->next;
-       if (a == 0)     /* identifier not in list */
+       if (a == 0)     /* identifier not in list, global definition */
                return;
 
        switch (to_state) {
@@ -298,30 +311,31 @@ change_state(idf, to_state)
        }
 }
 
-extern struct stack_level *local_level;
-
 add_auto(idf)  /* to current state on top of lint_stack */
        struct idf *idf;
 {
 /* Check if idf's definition is really an auto (or register).
  * It could be a static or extern too.
- * Watch out for register formal parameters.
+ * Watch out for formal parameters.
  */
        register struct def *def = idf->id_def;
-       register struct auto_def *a;
 
-       if (!def)
-               return;
+       ASSERT(def);
+
        switch (def->df_sc) {
+               register struct auto_def *a;
        case AUTO:
        case REGISTER:
                if (def->df_level < L_LOCAL)
-                       return;         /* a register formal */
+                       return;         /* a formal */
+
                a = new_auto_def();
+
                a->ad_idf = idf;
                a->ad_def = idf->id_def;
                a->ad_used = def->df_used;
                a->ad_set = def->df_set;
+
                a->next = top_ls->ls_current->st_auto_list;
                top_ls->ls_current->st_auto_list = a;
        }
@@ -330,37 +344,40 @@ add_auto(idf)     /* to current state on top of lint_stack */
 PRIVATE
 check_autos()
 {
-/* Before leaving a block remove the auto_defs of the automatic
+/* Before leaving a block, remove the auto_defs of the automatic
  * variables on this level and check if they are used
  */
-       register struct auto_def *a1 = top_ls->ls_current->st_auto_list;
-       register struct auto_def *a2;
+       register struct auto_def *a = top_ls->ls_current->st_auto_list;
 
-       ASSERT(!(a1 && a1->ad_def->df_level > level));
-       while (a1 && a1->ad_def->df_level == level) {
-               a2 = a1;
-               a1 = a1->next;
-               if (!a2->ad_used) {
-                       if (a2->ad_set || a2->ad_maybe_set) {
-                               def_warning(a2->ad_def,
+       ASSERT(!(a && a->ad_def->df_level > level));
+       while (a && a->ad_def->df_level == level) {
+               if (!a->ad_used) {
+                       if (a->ad_set || a->ad_maybe_set) {
+                               def_warning(a->ad_def,
                                        "%s set but not used in function %s",
-                                       a2->ad_idf->id_text, func_name);
+                                       a->ad_idf->id_text, func_name);
                        }
                        else {
-                               def_warning(a2->ad_def,
+                               def_warning(a->ad_def,
                                        "%s neither set nor used in function %s",
-                                       a2->ad_idf->id_text, func_name);
+                                       a->ad_idf->id_text, func_name);
                        }
                }
-               free_auto_def(a2);
+
+               {       /* free a */
+                       register struct auto_def *aux = a;
+                       a = a->next;
+                       free_auto_def(aux);
+               }
        }
-       top_ls->ls_current->st_auto_list = a1;
+       top_ls->ls_current->st_auto_list = a;
 }
 
-check_args_used()
+lint_end_formals()
 {
        register struct stack_entry *se = local_level->sl_entry;
 
+       dbg_lint_stack("lint_end_formals");
        ASSERT(level == L_FORMAL1);
        while (se) {
                register struct def *def = se->se_idf->id_def;
@@ -376,15 +393,18 @@ check_args_used()
 }
 
 PRIVATE struct auto_def *
-copy_st_auto_list(from_al, lvl)
+copy_auto_list(from_al, lvl)
        struct auto_def *from_al;
+       int lvl;
 {
        struct auto_def *start = 0;
        register struct auto_def **hook = &start;
 
+       /* skip too high levels */
        while (from_al && from_al->ad_def->df_level > lvl) {
                from_al = from_al->next;
        }
+
        while (from_al) {
                register struct auto_def *a = new_auto_def();
 
@@ -398,28 +418,27 @@ copy_st_auto_list(from_al, lvl)
 }
 
 PRIVATE
-free_st_auto_list(au)
-       register struct auto_def *au;
-{
+free_auto_list(a)
        register struct auto_def *a;
-
-       while (au) {
-               a = au;
-               au = au->next;
-               free_auto_def(a);
+{
+       while (a) {
+               register struct auto_def *aux = a;
+               a = a->next;
+               free_auto_def(aux);
        }
 }
 
 PRIVATE struct state *
 copy_state(from_st, lvl)
        struct state *from_st;
+       int lvl;
 {
 /* Memory for the struct state and the struct auto_defs is allocated
  * by this function
  */
        register struct state *st = new_state();
 
-       st->st_auto_list = copy_st_auto_list(from_st->st_auto_list, lvl);
+       st->st_auto_list = copy_auto_list(from_st->st_auto_list, lvl);
        st->st_notreached = from_st->st_notreached;
        st->st_warned = from_st->st_warned;
        return st;
@@ -431,19 +450,20 @@ Free_state(stp)
 {
 /* This function also frees the list of auto_defs
  */
-       free_st_auto_list((*stp)->st_auto_list);
+       free_auto_list((*stp)->st_auto_list);
        free_state(*stp);
        *stp = 0;
 }
 
 PRIVATE
-remove_settings(state, lvl)
-       struct state *state;
+remove_settings(st, lvl)
+       struct state *st;
+       int lvl;
 {
-/* The state of all variables on this level are set to 'not set' and
+/* The states of all variables on this level are set to 'not set' and
  * 'not maybe set'. (I think you have to read this twice.)
  */
-       register struct auto_def *a = state->st_auto_list;
+       register struct auto_def *a = st->st_auto_list;
 
        while (a && a->ad_def->df_level == lvl) {
                a->ad_set = a->ad_maybe_set = 0;
@@ -459,9 +479,48 @@ remove_settings(state, lvl)
 #define        CASE_BREAK      1
 #define        USE_ONLY        2
 
+PRIVATE
+merge_states(st1, st2, lvl, mode)
+       struct state *st1, *st2;
+       int lvl;
+       int mode;                       /* NORMAL or CASE_BREAK */
+{
+/* st2 becomes the result.
+ * st1 is left unchanged.
+ * The resulting state is the state the program gets in if st1 OR st2
+ * becomes the state. (E.g. the states at the end of an if-part and an
+ * end-part are merged by this function.)
+ */
+       if (st1->st_notreached) {
+               if (mode == NORMAL || st2->st_notreached) {
+                       st2->st_auto_list =
+                               merge_autos(st1->st_auto_list,
+                                       st2->st_auto_list, lvl, USE_ONLY);
+               }
+       }
+       else
+       if (st2->st_notreached) {
+               register struct auto_def *tmp = st2->st_auto_list;
+
+               st2->st_auto_list = copy_auto_list(st1->st_auto_list, lvl);
+               st2->st_notreached = 0;
+               st2->st_warned = 0;
+               st2->st_auto_list = merge_autos(tmp, st2->st_auto_list,
+                                                       lvl, USE_ONLY);
+               free_auto_list(tmp);
+       }
+       else {
+               /* both st1 and st2 reached */
+               st2->st_auto_list =
+                       merge_autos(st1->st_auto_list, st2->st_auto_list,
+                               lvl, mode);
+       }
+}
+
 PRIVATE struct auto_def *
 merge_autos(a1, a2, lvl, mode)
        struct auto_def *a1, *a2;
+       int lvl;
        int mode;
 {
 /* Returns a pointer to the result.
@@ -484,17 +543,23 @@ merge_autos(a1, a2, lvl, mode)
  */
        register struct auto_def *a;
 
+       /* skip too local entries */
        while (a1 && a1->ad_def->df_level > lvl) {
                a1 = a1->next;
        }
+
+       /* discard too local entries */
        while (a2 && a2->ad_def->df_level > lvl) {
-               a = a2;
+               register struct auto_def *aux = a2;
                a2 = a2->next;
-               free_auto_def(a);
+               free_auto_def(aux);
        }
+
        a = a2; /* pointer to the result */
        while (a1) {
                ASSERT(a2);
+
+               /* merge the auto_defs for one idf */
                ASSERT(a1->ad_idf == a2->ad_idf);
                if (a1->ad_used)
                        a2->ad_used = 1;
@@ -520,41 +585,6 @@ merge_autos(a1, a2, lvl, mode)
        return a;
 }
 
-PRIVATE
-merge_states(st1, st2, lvl, mode)
-       struct state *st1, *st2;
-       int mode;
-{
-/* st2 becomes the result.
- * st1 is left unchanged.
- * The resulting state is the state the program gets in if st1 OR st2
- * becomes the state. (E.g. the states at the end of an if-part and an
- * end-part are merged by this function.)
- */
-       if (st1->st_notreached) {
-               if (mode == NORMAL || st2->st_notreached) {
-                       st2->st_auto_list =
-                               merge_autos(st1->st_auto_list,
-                                       st2->st_auto_list, lvl, USE_ONLY);
-               }
-       }
-       else if (st2->st_notreached) {
-               register struct auto_def *tmp = st2->st_auto_list;
-
-               st2->st_auto_list = copy_st_auto_list(st1->st_auto_list, lvl);
-               st2->st_notreached = 0;
-               st2->st_warned = 0;
-               st2->st_auto_list = merge_autos(tmp, st2->st_auto_list,
-                                                       lvl, USE_ONLY);
-               free_st_auto_list(tmp);
-       }
-       else {
-               st2->st_auto_list =
-                       merge_autos(st1->st_auto_list, st2->st_auto_list,
-                               lvl, mode);
-       }
-}
-
 
 /******** L I N T   S T A C K   S E A R C H I N G ********/
 
@@ -567,7 +597,7 @@ find_wdf()
 {
        register struct lint_stack_entry *lse = top_ls;
 
-       while (lse != &stack_bottom) {
+       while (lse) {
                switch (lse->ls_class) {
                case WHILE:
                case DO:
@@ -584,7 +614,7 @@ find_wdfc()
 {
        register struct lint_stack_entry *lse = top_ls;
 
-       while (lse != &stack_bottom) {
+       while (lse) {
                switch (lse->ls_class) {
                case WHILE:
                case DO:
@@ -602,7 +632,7 @@ find_cs()
 {
        register struct lint_stack_entry *lse = top_ls;
 
-       while (lse != &stack_bottom) {
+       while (lse) {
                switch (lse->ls_class) {
                case CASE:
                case SWITCH:
@@ -613,139 +643,198 @@ find_cs()
        return 0;
 }
 
-/******** A C T I O N S ********/
+/******** A C T I O N S : I F ********/
 
 start_if_part(const)
 {
-/* Push a new stack entry on the lint_stack with class == IF
- * copy the ls_current to the top of this stack
- */
-       register struct lint_stack_entry *lse = new_lint_stack_entry();
+       register struct lint_stack_entry *new = mk_lint_stack_entry(IF);
 
+       dbg_lint_stack("start_if_part");
        if (const)
                hwarning("condition in if statement is constant");
 
-       lse->ls_class = IF;
-       lse->ls_current = copy_state(top_ls->ls_current, level);
-       lse->ls_level = level;
-       lint_push(lse);
+       lint_push(new);
+/*     ls_current:     the state at the start of the if-part
+*/
 }
 
 start_else_part()
 {
-/* Move ls_current to LS_IF_STATE
- * ls_current of the stack entry one below is copied to ls_current.
- */
+/*     ls_current:     the state at the end of the if-part
+       ls_previous->ls_current:        the state before the if-part
+*/
+
+       dbg_lint_stack("start_else_part");
        if (s_NOTREACHED) {
                top_ls->ls_current->st_notreached = 1;
+               top_ls->ls_current->st_warned = 0;
                s_NOTREACHED = 0;
        }
-       top_ls->LS_IF_STATE = top_ls->ls_current;
+       top_ls->LS_IF = top_ls->ls_current;
        /* this is the reason why ls_current is a pointer */
-       top_ls->ls_current = copy_state(top_ls->ls_previous->ls_current,
-                                                               level);
+       top_ls->ls_current =
+               copy_state(top_ls->ls_previous->ls_current, level);
        top_ls->ls_level = level;
+/*     ls_current:     the state before the if-part and the else-part
+       LS_IF:          the state at the end of the if-part
+*/
 }
 
 end_if_else_stmt()
 {
-       Free_state(&top_ls->ls_previous->ls_current);
-       merge_states(top_ls->LS_IF_STATE, top_ls->ls_current,
+/*     ls_current:     state at the end of the else-part
+       LS_IF:          state at the end of the if-part
+*/
+
+       dbg_lint_stack("end_if_else_stmt");
+       merge_states(top_ls->LS_IF, top_ls->ls_current,
                                        top_ls->ls_level, NORMAL);
-       Free_state(&top_ls->LS_IF_STATE);
+       Free_state(&top_ls->LS_IF);
+       Free_state(&top_ls->ls_previous->ls_current);
        top_ls->ls_previous->ls_current = top_ls->ls_current;
        lint_pop();
 }
 
 end_if_stmt()
 {
-/* No else-part met; merge ls_current with ls_current of previous
- * stack entry
- */
+/*     No else-part met.
+       ls_current:     state at the end of the if-part
+*/
+
+       dbg_lint_stack("end_if_stmt");
        merge_states(top_ls->ls_current, top_ls->ls_previous->ls_current,
                                                top_ls->ls_level, NORMAL);
        Free_state(&top_ls->ls_current);
        lint_pop();
 }
 
+/******** A C T I O N S : L O O P S ********/
+
+start_while_stmt(expr)
+       struct expr *expr;
+{
+       if (is_cp_cst(expr))    {
+               start_loop_stmt(WHILE, 1, expr->VL_VALUE != (arith)0);
+       }
+       else    {
+               start_loop_stmt(WHILE, 0, 0);
+       }
+}
+
+start_do_stmt()
+{
+       start_loop_stmt(DO, 1, 1);
+}
+
+start_for_stmt(expr)
+       struct expr *expr;
+{
+       if (!expr)      {
+               start_loop_stmt(FOR, 1, 1);
+       }
+       else
+       if (is_cp_cst(expr))    {
+               start_loop_stmt(FOR, 1, expr->VL_VALUE != (arith)0);
+       }
+       else    {
+               start_loop_stmt(FOR, 0, 0);
+       }
+}
+
+PRIVATE
 start_loop_stmt(looptype, const, cond)
 {
-/* If const, the condition is constant and given in cond */
-       register struct lint_stack_entry *lse = new_lint_stack_entry();
+/*     If const, the condition is a constant and its value is cond
+*/
+       register struct lint_stack_entry *new = mk_lint_stack_entry(looptype);
 
-       lse->ls_class = looptype;
-       lse->ls_current = copy_state(top_ls->ls_current, level);
-       lse->ls_level = level;
+       dbg_lint_stack("start_loop_stmt");
        if (const && !cond) {
                /* while (0) | for (;0;) */
                hwarning("condition in %s statement is constant",
                                                symbol2str(looptype));
-               lse->ls_current->st_notreached = 1;
+               new->ls_current->st_notreached = 1;
        }
        if (const && cond) {
                /* while (1) | for (;;) | do */
-               /*      omitting the copy for LS_END will force this loop
+               /*      omitting the copy for LS_LOOP will force this loop
                        to be treated as a do loop
                */
                top_ls->ls_current->st_notreached = 1;
+               top_ls->ls_current->st_warned = 0;
        }
        else {
-               lse->LS_END = copy_state(top_ls->ls_current, level);
+               new->LS_LOOP = copy_state(top_ls->ls_current, level);
        }
-       lint_push(lse);
+       new->LS_TEST = (!const ? TEST_VAR : cond ? TEST_TRUE : TEST_FALSE);
+       lint_push(new);
+
+/*     ls_current:     the state at the start of the body
+       LS_TEST:        info about the loop test
+       LS_BODY:        0, the state at the end of the body
+       LS_LOOP:        the state at the end of the loop, or 0 if the loop
+                       does not end
+*/
 }
 
-end_loop_stmt()
+end_loop_body()
 {
-       register struct lint_stack_entry *prev_ls = top_ls->ls_previous;
+       register struct lint_stack_entry *lse = find_wdf();
 
-       lint_continue_stmt();
-       top_ls->LS_END->st_notreached = prev_ls->ls_current->st_notreached;
-       top_ls->LS_END->st_warned = prev_ls->ls_current->st_warned;
-       Free_state(&top_ls->ls_current);
-       Free_state(&prev_ls->ls_current);
-       prev_ls->ls_current = top_ls->LS_END;
-       lint_pop();
+       dbg_lint_stack("end_loop_body");
+       ASSERT(lse == top_ls);
+       if (!lse->ls_current->st_notreached)
+               cont_merge(lse);
 }
 
-end_do_stmt(const, cond)
+end_loop_stmt()
 {
-       end_loop_stmt();
-       if (const)
-               hwarning("condition in do-while statement is constant");
-       if (const && cond && top_ls->ls_current->st_notreached) {
+       register struct lint_stack_entry *lse = find_wdf();
+
+       dbg_lint_stack("end_loop_stmt");
+       ASSERT(lse == top_ls);
+       if (lse->LS_TEST != TEST_TRUE)
+               break_merge(lse);
+
+       dbg_lint_stack("end_loop_stmt after break_merge");
+       if (!top_ls->LS_LOOP) {
                /* no break met; this is really an endless loop */
+               hwarning("endless %s loop", symbol2str(top_ls->ls_class));
+               Free_state(&top_ls->ls_current);
        }
        else {
-               top_ls->ls_current->st_notreached = 0;
+               Free_state(&top_ls->ls_current);
+               Free_state(&top_ls->ls_previous->ls_current);
+               top_ls->ls_previous->ls_current = top_ls->LS_LOOP;
        }
+       lint_pop();
 }
 
-PRIVATE
-cont_break_merge(lse)
-       struct lint_stack_entry *lse;
+end_do_stmt(const, cond)
 {
-       /* merge for continue and break statements */
-       if (lse->LS_END) {
-               merge_states(top_ls->ls_current, lse->LS_END,
-                                               lse->ls_level, NORMAL);
-       }
-       else {
-               lse->LS_END = copy_state(top_ls->ls_current, lse->ls_level);
-       }
+       register struct lint_stack_entry *lse = find_wdf();
+
+       dbg_lint_stack("end_do_stmt");
+       lse->LS_TEST = (!const ? TEST_VAR : cond ? TEST_TRUE : TEST_FALSE);
+       end_loop_stmt();
+
 }
 
 lint_continue_stmt()
 {
        register struct lint_stack_entry *lse = find_wdf();
 
+       dbg_lint_stack("lint_continue_stmt");
        if (!lse)
                return;         /* not inside a loop statement */
 
-       cont_break_merge(lse);
+       cont_merge(lse);
        top_ls->ls_current->st_notreached = 1;
+       top_ls->ls_current->st_warned = 0;
 }
 
+/******** A C T I O N S : S W I T C H ********/
+
 start_switch_part(expr)
        struct expr *expr;
 {
@@ -754,22 +843,25 @@ start_switch_part(expr)
  * following case parts. (Needed for variables declared in a compound
  * switch-block.)
  */
-       register struct lint_stack_entry *lse = new_lint_stack_entry();
+       register struct lint_stack_entry *new = mk_lint_stack_entry(SWITCH);
 
+       dbg_lint_stack("start_switch_part");
        if (is_cp_cst(expr))
                hwarning("value in switch statement is constant");
 
-       lse->ls_class = SWITCH;
-       lse->ls_current = copy_state(top_ls->ls_current, level);
-       lse->ls_level = level;
-       lse->LS_CASE = copy_state(top_ls->ls_current, level);
-       lse->ls_current->st_notreached = 1;
+       new->LS_CASE = copy_state(top_ls->ls_current, level);
+       new->ls_current->st_notreached = 1;
+       new->ls_current->st_warned = 0;
        top_ls->ls_current->st_notreached = 1;
-       lint_push(lse);
+       top_ls->ls_current->st_warned = 0;
+       lint_push(new);
+       lint_expr(expr, USED);  /*???*/
 }
 
 end_switch_stmt()
 {
+
+       dbg_lint_stack("end_switch_stmt");
        if (top_ls->ls_class == CASE) {
                /* no break after last case or default */
                lint_break_stmt();      /* introduce break */
@@ -814,30 +906,33 @@ end_switch_stmt()
 lint_case_stmt(dflt)
 {
 /* A default statement is just a special case statement */
-
-       register struct lint_stack_entry *lse;
        register struct lint_stack_entry *cs_entry = find_cs();
 
+       dbg_lint_stack("lint_case_stmt");
        if (!cs_entry)
                return;         /* not inside switch */
+
        if (cs_entry != top_ls) {
                warning("%s statement in strange context",
                        dflt ? "default" : "case");
                return;
        }
-       if (cs_entry->ls_class == SWITCH) {
+
+       switch (cs_entry->ls_class) {
+               register struct lint_stack_entry *new;
+
+       case SWITCH:
                if (dflt) {
                        cs_entry->LS_DEFAULT_MET = 1;
                }
-               lse = new_lint_stack_entry();
-               lse->ls_class = CASE;
-               lse->ls_current = copy_state(top_ls->ls_current, level);
-               remove_settings(lse->ls_current, level);
-               lse->ls_level = level;
-               lint_push(lse);
-       }
-       else {
-               ASSERT(cs_entry->ls_class == CASE);
+
+               new = mk_lint_stack_entry(CASE);
+               remove_settings(new->ls_current, level);
+               lint_push(new);
+               break;
+
+       case CASE:
+               ASSERT(top_ls->ls_previous->ls_class == SWITCH);
                if (dflt) {
                        cs_entry->ls_previous->LS_DEFAULT_MET = 1;
                }
@@ -851,6 +946,11 @@ lint_case_stmt(dflt)
                        copy_state(top_ls->ls_previous->ls_current,
                                        top_ls->ls_previous->ls_level);
                remove_settings(top_ls->ls_current, top_ls->ls_level);
+               break;
+
+       default:
+               NOTREACHED();
+               /*NOTREACHED*/
        }
 }
 
@@ -858,6 +958,7 @@ lint_break_stmt()
 {
        register struct lint_stack_entry *lse = find_wdfc();
 
+       dbg_lint_stack("lint_break_stmt");
        if (!lse)
                return;
 
@@ -867,7 +968,7 @@ lint_break_stmt()
        case DO:
                /* loop break */
                lse->ls_previous->ls_current->st_notreached = 0;
-               cont_break_merge(lse);
+               break_merge(lse);
                break;
 
        case CASE:
@@ -878,115 +979,145 @@ lint_break_stmt()
                merge_states(lse->ls_current, lse->ls_previous->ls_current,
                                        lse->ls_previous->ls_level, NORMAL);
                if (lse->ls_previous->LS_BREAK) {
-                       merge_states(top_ls->ls_current, lse->ls_previous->LS_BREAK,
-                                       lse->ls_previous->ls_level, NORMAL);
+                       merge_states(top_ls->ls_current,
+                               lse->ls_previous->LS_BREAK,
+                               lse->ls_previous->ls_level, NORMAL);
                }
                else {
-                       lse->ls_previous->LS_BREAK = copy_state(top_ls->ls_current,
-                                                lse->ls_previous->ls_level);
+                       lse->ls_previous->LS_BREAK =
+                               copy_state(top_ls->ls_current,
+                                        lse->ls_previous->ls_level);
                }
                if (lse == top_ls) {
                        Free_state(&lse->ls_current);
                        lint_pop();
                }
                break;
+
        default:
                NOTREACHED();
                /*NOTREACHED*/
        }
        top_ls->ls_current->st_notreached = 1;
+       top_ls->ls_current->st_warned = 0;
 }
 
+PRIVATE
+cont_merge(lse)
+       struct lint_stack_entry *lse;
+{
+       /* merge for continue statements */
+       if (lse->LS_BODY) {
+               merge_states(top_ls->ls_current, lse->LS_BODY,
+                                               lse->ls_level, NORMAL);
+       }
+       else {
+               lse->LS_BODY = copy_state(top_ls->ls_current, lse->ls_level);
+       }
+}
+
+PRIVATE
+break_merge(lse)
+       struct lint_stack_entry *lse;
+{
+       /* merge for break statements */
+       if (lse->LS_LOOP) {
+               merge_states(top_ls->ls_current, lse->LS_LOOP,
+                                               lse->ls_level, NORMAL);
+       }
+       else {
+               lse->LS_LOOP = copy_state(top_ls->ls_current, lse->ls_level);
+       }
+}
+
+/******** A C T I O N S : R E T U R N ********/
+
 lint_start_function()
 {
-       lint_return_stmt(-1);   /* initialization */
+
+       dbg_lint_stack("lint_start_function");
+       valreturned = NORETURN;         /* initialization */
+       return_warned = 0;
        lint_comment_function();
 }
 
 lint_end_function()
 {
-       extern struct outdef OutDef;
-       register int fund = func_type->tp_fund;
 
-       if (    OutDef.od_valreturned == NOVALRETURNED
-       &&      !func_notypegiven
-       &&      fund != VOID
-       ) {
-               warning("function %s declared %s%s but no value returned",
-                       func_name,
-                       (func_type->tp_unsigned && fund != POINTER) ?
-                               "unsigned " : "",
-                        symbol2str(fund)
-               );
-       }
+       dbg_lint_stack("lint_end_function");
        /* write the function definition record */
        outdef();
 
-       /* At this stage it is possible that stack_bottom.ls_current is
+       /* At this stage it is possible that top_ls->ls_current is
         * pointing to a state with a list of auto_defs.
         * These auto_defs must be freed and the state must be filled
         * with zeros.
         */
-       ASSERT(top_ls == &stack_bottom);
-       if (top_ls->ls_current->st_auto_list != 0)
-               free_st_auto_list(top_ls->ls_current->st_auto_list);
+       ASSERT(!top_ls->ls_previous);
+       free_auto_list(top_ls->ls_current->st_auto_list);
        top_ls->ls_current->st_auto_list = 0;
        top_ls->ls_current->st_notreached = 0;
        top_ls->ls_current->st_warned = 0;
 }
 
+lint_implicit_return()
+{
+
+       dbg_lint_stack("lint_implicit_return");
+       if (!top_ls->ls_current->st_notreached) {
+               lint_return_stmt(NOVALRETURNED);
+       }
+}
+
 lint_return_stmt(e)
        int e;
 {
-/* The statics of this function are initialized by calling it with e = -1. */
-
-       static int ret_e;
-                               /*-1    no return met yet
-                                * 0    return; met
-                                * 1    return with expression met
-                                */
-       static int warned;
-
-       switch (e) {
-       case -1:
-               ret_e = -1;
-               warned = 0;
-               return;
-       case 0:
-               if (top_ls->ls_current->st_notreached)
-                       break;
-               if (ret_e == 1 && !warned) {
-                       warning("function %s does not always return a value",
-                               func_name);
-                       warned = 1;
-               }
-               else
-                       ret_e = 0;
-               break;
-       case 1:
-               if (top_ls->ls_current->st_notreached)
-                       break;
-               if (ret_e == 0 && !warned) {
-                       warning("function %s does not always return a value",
-                               func_name);
-                       warned = 1;
+
+       dbg_lint_stack("lint_return_stmt");
+       if (valreturned == NORETURN) {
+               /* first return met */
+               register int fund = func_type->tp_fund;
+
+               if (    e == NOVALRETURNED
+               &&      !func_notypegiven
+               &&      fund != VOID
+               ) {
+                       warning("function %s declared %s%s but no value returned",
+                               func_name,
+                               (func_type->tp_unsigned && fund != POINTER) ?
+                                       "unsigned " : "",
+                                symbol2str(fund)
+                       );
+                       /* adjust */
+                       e = VALRETURNED;
                }
-               else
-                       ret_e = 1;
-               break;
+               valreturned = e;
+       }
+       else
+       if (valreturned != e && !return_warned) {
+               warning("function %s does not always return a value",
+                       func_name);
+               return_warned = 1;
+       }
+
+       if (!top_ls->ls_current->st_notreached) {
+               set_od_valreturned(valreturned);
        }
-       if (!top_ls->ls_current->st_notreached)
-               set_od_valreturned(e);
        top_ls->ls_current->st_notreached = 1;
+       top_ls->ls_current->st_warned = 0;
 }
 
+/******** A C T I O N S : J U M P ********/
+
 lint_jump_stmt(idf)
        struct idf *idf;
 {
+
+       dbg_lint_stack("lint_jump_stmt");
        top_ls->ls_current->st_notreached = 1;
-       if (!idf->id_def)
-               return;
-       idf->id_def->df_used = 1;
+       top_ls->ls_current->st_warned = 0;
+       if (idf->id_def)
+               idf->id_def->df_used = 1;
 }
 
 lint_label()
@@ -998,6 +1129,7 @@ lint_label()
 */
        register struct auto_def *a = top_ls->ls_current->st_auto_list;
 
+       dbg_lint_stack("lint_label");
        while (a) {
                a->ad_maybe_set = 0;
                a->ad_set = 1;
@@ -1005,12 +1137,17 @@ lint_label()
        }
 }
 
+/******** A C T I O N S : S T A T E M E N T ********/
+
 lint_statement()
 {
-/* Check if this statement can be reached
- */
+/*     Check if this statement can be reached
+*/
+
+       dbg_lint_stack("lint_statement");
        if (s_NOTREACHED) {
                top_ls->ls_current->st_notreached = 1;
+               top_ls->ls_current->st_warned = 0;
                s_NOTREACHED = 0;
        }
        if (DOT == '{' || DOT == ';')
@@ -1030,6 +1167,22 @@ lint_statement()
        }
 }
 
+PRIVATE struct lint_stack_entry *
+mk_lint_stack_entry(cl)
+       int cl;
+{
+/*     Prepare a new stack entry for the lint_stack with class cl.
+       Copy the top ls_current to this entry and set its level.
+*/
+       register struct lint_stack_entry *new = new_lint_stack_entry();
+       
+       new->ls_class = cl;
+       new->ls_current = copy_state(top_ls->ls_current, level);
+       new->ls_level = level;
+
+       return new;
+}
+
 PRIVATE
 lint_push(lse)
        struct lint_stack_entry *lse;
@@ -1049,64 +1202,59 @@ lint_pop()
 #ifdef DEBUG
 /* FOR DEBUGGING */
 
-print_lint_stack()
+PRIVATE
+pr_lint_state(nm, st)
+       char *nm;
+       struct state *st;
+{
+       print("%s: ", nm);
+       if (st) {
+               print("notreached == %d ", st->st_notreached);
+               print_autos(st->st_auto_list);
+       }
+       else {
+               print("NULL");
+       }
+       print("\n");
+}
+
+print_lint_stack(msg)
+       char *msg;
 {
        register struct lint_stack_entry *lse = top_ls;
 
+       print("Lint stack: %s(level=%d)\n", msg, level);
        while (lse) {
                print("  |-------------- level %d ------------\n",
                                        lse->ls_level);
-               print("  |cur: ");
-               if (lse->ls_current) {
-                       print_autos(lse->ls_current->st_auto_list);
-                       print("  |st_notreached == %d\n",
-                               lse->ls_current->st_notreached);
-               }
-               else
-                       print("\n");
+               pr_lint_state("  |cur", lse->ls_current);
+
                print("  |class == %s\n",
                        lse->ls_class ? symbol2str(lse->ls_class) : "{");
+
                switch (lse->ls_class) {
                case SWITCH:
-                       print("  |LS_BREAK: ");
-                       if (lse->LS_BREAK) {
-                               print_autos(lse->LS_BREAK->st_auto_list);
-                               print("  |st_notreached == %d\n",
-                                       lse->LS_BREAK->st_notreached);
-                       }
-                       else
-                               print("\n");
-                       print("  |LS_CASE:  ");
-                       if (lse->LS_CASE) {
-                               print_autos(lse->LS_CASE->st_auto_list);
-                               print("  |st_notreached == %d\n",
-                                       lse->LS_CASE->st_notreached);
-                       }
-                       else
-                               print("\n");
+                       pr_lint_state("   |LS_BREAK", lse->LS_BREAK);
+                       pr_lint_state("   |LS_CASE", lse->LS_CASE);
                        break;
+
                case DO:
                case WHILE:
                case FOR:
-                       print("  |LS_END:  ");
-                       if (lse->LS_END) {
-                               print_autos(lse->LS_END->st_auto_list);
-                               print("  |st_notreached == %d\n",
-                                       lse->LS_END->st_notreached);
-                       }
-                       else
-                               print("\n");
+                       print("   |LS_TEST == %s\n",
+                               lse->LS_TEST == TEST_VAR ? "TEST_VAR" :
+                               lse->LS_TEST == TEST_TRUE ? "TEST_TRUE" :
+                               lse->LS_TEST == TEST_FALSE ? "TEST_FALSE" :
+                               "<<BAD VALUE>>"
+                       );
+                       pr_lint_state("   |LS_BODY", lse->LS_BODY);
+                       pr_lint_state("   |LS_LOOP", lse->LS_LOOP);
                        break;
+
                case IF:
-                       print("  |LS_IF_STATE: ");
-                       if (lse->LS_IF_STATE) {
-                               print_autos(lse->LS_IF_STATE->st_auto_list);
-                               print("  |st_notreached == %d\n",
-                                       lse->LS_IF_STATE->st_notreached);
-                       }
-                       else
-                               print("\n");
+                       pr_lint_state("   |LS_IF", lse->LS_IF);
                        break;
+
                default:
                        break;
                }
@@ -1120,11 +1268,10 @@ print_autos(a)
 {
        while (a) {
                print("%s", a->ad_idf->id_text);
-               print("(l=%d)", a->ad_def->df_level);
+               print("(lvl=%d)", a->ad_def->df_level);
                print("(U%dS%dM%d) ", a->ad_used, a->ad_set, a->ad_maybe_set);
                a = a->next;
        }
-       print("\n");
 }
 #endif DEBUG
 
index 64a1158..7e2d00a 100644 (file)
@@ -58,7 +58,7 @@
 #include       "expr.h"
 #include       "def.h"
 #ifdef LINT
-#include       "l_state.h"
+#include       "l_lint.h"
 #endif LINT
 
 #ifndef NOPP
@@ -205,11 +205,11 @@ function(struct decspecs *ds; struct declarator *dc;)
        {
                end_proc(fbytes);
 #ifdef LINT
-               lint_return_stmt(0);    /* implicit return at end of function */
+               lint_implicit_return();
 #endif LINT
                unstack_level();        /* L_FORMAL2 declarations */
 #ifdef LINT
-               check_args_used();
+               lint_end_formals();
 #endif LINT
                unstack_level();        /* L_FORMAL1 declarations */
 #ifdef LINT
index 3be2dec..27724ec 100644 (file)
@@ -101,7 +101,7 @@ unstack_level()
 #endif DEBUG
 
 #ifdef LINT
-       lint_local_level(local_level);
+       lint_end_local(local_level);
 #endif LINT
 
        /*      The implementation below is more careful than strictly
@@ -177,7 +177,7 @@ unstack_world()
        register struct stack_entry *se = local_level->sl_entry;
 
 #ifdef LINT
-       lint_global_level(local_level);
+       lint_end_global(local_level);
 #endif LINT
 
        open_name_list();
index 53b0aeb..b8c2cfb 100644 (file)
 #include       "def.h"
 #ifdef LINT
 #include       "l_lint.h"
-#include       "l_state.h"
 #endif LINT
 
 extern int level;
 }
 
-/*     Each statement construction is stacked in order to trace a
+/*     Each statement construction is stacked in order to trace a ???
        statement to such a construction. Example: a case statement should
        be recognized as a piece of the most enclosing switch statement.
 */
@@ -209,18 +208,16 @@ while_statement
                                if (expr->VL_VALUE == (arith)0) {
                                        C_bra(l_break);
                                }
-#ifdef LINT
-                               start_loop_stmt(WHILE, 1,
-                                       expr->VL_VALUE != (arith)0);
-#endif LINT
                        }
                        else    {
                                code_expr(expr, RVAL, TRUE, l_body, l_break);
                                C_df_ilb(l_body);
+                       }
+
 #ifdef LINT
-                               start_loop_stmt(WHILE, 0, 0);
+                       start_while_stmt(expr);
 #endif LINT
-                       }
+
                }
        ')'
        statement
@@ -230,6 +227,7 @@ while_statement
                        unstack_stmt();
                        free_expression(expr);
 #ifdef LINT
+                       end_loop_body();
                        end_loop_stmt();
 #endif LINT
                }
@@ -246,13 +244,17 @@ do_statement
                {       C_df_ilb(l_body);
                        stack_stmt(l_break, l_continue);
 #ifdef LINT
-                       start_loop_stmt(DO, 1, 1);
+                       start_do_stmt();
 #endif LINT
                }
        statement
        WHILE
        '('
-               {       C_df_ilb(l_continue);
+               {
+#ifdef LINT
+                       end_loop_body();
+#endif LINT
+                       C_df_ilb(l_continue);
                }
        expression(&expr)
                {
@@ -287,9 +289,6 @@ for_statement
                label l_continue = text_label();
                label l_body = text_label();
                label l_test = text_label();
-#ifdef LINT
-               int const = 1, cond = 1;        /* the default case */
-#endif LINT
        }
 :
        FOR
@@ -312,17 +311,10 @@ for_statement
                                if (e_test->VL_VALUE == (arith)0)       {
                                        C_bra(l_break);
                                }
-#ifdef LINT
-                               const = 1,
-                                       cond = e_test->VL_VALUE != (arith)0;
-#endif LINT
                        }
                        else    {
                                code_expr(e_test, RVAL, TRUE, l_body, l_break);
                                C_df_ilb(l_body);
-#ifdef LINT
-                               const = 0, cond = 0;
-#endif LINT
                        }
                }
        ]?
@@ -331,13 +323,13 @@ for_statement
        ')'
                {
 #ifdef LINT
-                       start_loop_stmt(FOR, const, cond);
+                       start_for_stmt(e_test);
 #endif LINT
                }
        statement
                {
 #ifdef LINT
-                       end_loop_stmt();
+                       end_loop_body();
 #endif LINT
                        C_df_ilb(l_continue);
                        if (e_incr)
@@ -349,6 +341,9 @@ for_statement
                        free_expression(e_init);
                        free_expression(e_test);
                        free_expression(e_incr);
+#ifdef LINT
+                       end_loop_stmt();
+#endif LINT
                }
 ;
 
@@ -423,7 +418,7 @@ return_statement
                        do_return_expr(expr);
                        free_expression(expr);
 #ifdef LINT
-                       lint_return_stmt(1);
+                       lint_return_stmt(VALRETURNED);
 #endif LINT
                }
        |
@@ -431,7 +426,7 @@ return_statement
                {
                        do_return();
 #ifdef LINT
-                       lint_return_stmt(0);
+                       lint_return_stmt(NOVALRETURNED);
 #endif LINT
                }
        ]