Some corrections and additions to improve the mechanism for
authorceriel <none@none>
Wed, 21 Oct 1987 11:29:52 +0000 (11:29 +0000)
committerceriel <none@none>
Wed, 21 Oct 1987 11:29:52 +0000 (11:29 +0000)
generating warnings on unused/uninitialized variables

14 files changed:
lang/m2/comp/Makefile
lang/m2/comp/Version.c
lang/m2/comp/chk_expr.c
lang/m2/comp/def.H
lang/m2/comp/def.c
lang/m2/comp/defmodule.c
lang/m2/comp/em_m2.6
lang/m2/comp/enter.c
lang/m2/comp/lookup.c
lang/m2/comp/main.c
lang/m2/comp/program.g
lang/m2/comp/scope.C
lang/m2/comp/type.c
lang/m2/comp/walk.c

index 5b83985..b944a3b 100644 (file)
@@ -318,6 +318,7 @@ walk.o: desig.h
 walk.o: f_info.h
 walk.o: idf.h
 walk.o: main.h
+walk.o: misc.h
 walk.o: node.h
 walk.o: scope.h
 walk.o: squeeze.h
index 9be6dce..c3c7688 100644 (file)
@@ -1 +1 @@
-static char Version[] = "ACK Modula-2 compiler Version 0.21";
+static char Version[] = "ACK Modula-2 compiler Version 0.22";
index 2ee76d1..a7048bf 100644 (file)
@@ -238,10 +238,10 @@ ChkLinkOrName(expp, flags)
        expp->nd_type = error_type;
 
        if (expp->nd_class == Name) {
-               expp->nd_def = df = lookfor(expp, CurrVis, 1);
+               df = lookfor(expp, CurrVis, 1, flags);
+               expp->nd_def = df;
                expp->nd_class = Def;
                expp->nd_type = RemoveEqual(df->df_type);
-               df->df_flags |= flags;
        }
        else if (expp->nd_class == Link) {
                /*      A selection from a record or a module.
@@ -265,11 +265,10 @@ ChkLinkOrName(expp, flags)
                        return 0;
                }
 
-               if (!(df = lookup(expp->nd_IDF, left->nd_type->rec_scope, 1))) {
+               if (!(df = lookup(expp->nd_IDF, left->nd_type->rec_scope, 1, flags))) {
                        id_not_declared(expp);
                        return 0;
                }
-               df->df_flags |= flags;
                expp->nd_def = df;
                expp->nd_type = RemoveEqual(df->df_type);
                expp->nd_class = Def;
@@ -467,7 +466,7 @@ ChkSet(expp)
        if (nd = expp->nd_left) {
                /* A type was given. Check it out
                */
-               if (! ChkDesignator(nd)) return 0;
+               if (! ChkDesig(nd, D_USED)) return 0;
                assert(nd->nd_class == Def);
                df = nd->nd_def;
 
@@ -575,7 +574,7 @@ getname(argp, kinds, bases, edf)
        */
        register t_node *left = nextarg(argp, edf);
 
-       if (!left || ! ChkDesignator(left)) return 0;
+       if (!left || ! ChkDesig(left, D_USED)) return 0;
 
        if (left->nd_class != Def) {
                return (t_node *)df_error(left, "identifier expected", edf);
@@ -1121,6 +1120,7 @@ ChkStandard(expp)
                free_it = 1;
                break;
 
+#ifndef STRICT_3RD_ED
        case S_NEW:
        case S_DISPOSE:
                {
@@ -1128,19 +1128,17 @@ ChkStandard(expp)
 
                        if (!warning_given) {
                                warning_given = 1;
-#ifndef STRICT_3RD_ED
                                if (! options['3'])
        node_warning(expp, W_OLDFASHIONED, "NEW and DISPOSE are obsolete");
                                else
-#endif
        node_error(expp, "NEW and DISPOSE are obsolete");
                        }
                }
-#ifdef STRICT_3RD_ED
-               return 0;
-#else
+               left = getvariable(&arg,
+                       edf,
+                       edf->df_value.df_stdname == S_NEW ? D_DEFINED : D_USED);
                expp->nd_type = 0;
-               if (! (left = getvariable(&arg, edf,D_DEFINED))) return 0;
+               if (! left) return 0;
                if (! (left->nd_type->tp_fund == T_POINTER)) {
                        return df_error(left, "pointer variable expected", edf);
                }
index 561f1ac..c85bec4 100644 (file)
@@ -98,13 +98,15 @@ struct def  {               /* list of definitions for a name */
 #define D_ERROR                0x4000  /* a compiler generated definition for an
                                   undefined variable
                                */
+#define D_IMP_BY_EXP   0x8000  /* imported definition by export */
 #define D_VALUE        (D_PROCEDURE|D_VARIABLE|D_FIELD|D_ENUM|D_CONST|D_PROCHEAD)
 #define D_ISTYPE       (D_HIDDEN|D_TYPE|D_FTYPE)
+#define D_IMPORTED     (D_IMPORT|D_IMP_BY_EXP)
 #define is_type(dfx)   ((dfx)->df_kind & D_ISTYPE)
        unsigned short  df_flags;
 #define D_NOREG                0x01    /* set if it may not reside in a register */
-#define D_USED         0x02    /* set if used (future use ???) */
-#define D_DEFINED      0x04    /* set if it is assigned a value (future use ???) */
+#define D_USED         0x02    /* set if used */
+#define D_DEFINED      0x04    /* set if it is assigned a value */
 #define D_VARPAR       0x08    /* set if it is a VAR parameter */
 #define D_VALPAR       0x10    /* set if it is a value parameter */
 #define D_EXPORTED     0x20    /* set if exported */
index bed3cee..613af6b 100644 (file)
@@ -73,7 +73,6 @@ MkDef(id, scope, kind)
        df->df_scope = scope;
        df->df_kind = kind;
        df->df_next = id->id_def;
-       df->df_flags = D_USED | D_DEFINED;
        id->id_def = df;
        if (kind == D_ERROR || kind == D_FORWARD) df->df_type = error_type;
 
@@ -97,14 +96,14 @@ define(id, scope, kind)
        */
        register t_def *df;
 
-       df = lookup(id, scope, 1);
+       df = lookup(id, scope, 1, 0);
        if (    /* Already in this scope */
                df
           ||   /* A closed scope, and id defined in the pervasive scope */
                ( 
                  scopeclosed(scope)
                &&
-                 (df = lookup(id, PervasiveScope, 1)))
+                 (df = lookup(id, PervasiveScope, 1, 0)))
           ) {
                switch(df->df_kind) {
                case D_HIDDEN:
@@ -191,7 +190,7 @@ RemoveImports(pdf)
        register t_def *df = *pdf;
 
        while (df) {
-               if (df->df_kind == D_IMPORT) {
+               if (df->df_kind & D_IMPORTED) {
                        RemoveFromIdList(df);
                        *pdf = df->df_nextinscope;
                        free_def(df);
@@ -260,7 +259,7 @@ DeclProc(type, id)
        else {
                char *name;
 
-               df = lookup(id, CurrentScope, 1);
+               df = lookup(id, CurrentScope, 1, 0);
                if (df && df->df_kind == D_PROCHEAD) {
                        /* C_exp already generated when we saw the definition
                           in the definition module
index adb5e81..5cb99d8 100644 (file)
@@ -97,14 +97,14 @@ GetDefinitionModule(id, incr)
        t_scope *newsc = CurrentScope;
 
        level += incr;
-       df = lookup(id, GlobalScope, 1);
+       df = lookup(id, GlobalScope, 1, 0);
        if (!df) {
                /* Read definition module. Make an exception for SYSTEM.
                */
                DefId = id;
                if (!strcmp(id->id_text, "SYSTEM")) {
                        do_SYSTEM();
-                       df = lookup(id, GlobalScope, 1);
+                       df = lookup(id, GlobalScope, 1, 0);
                }
                else {
                        extern int ForeignFlag;
@@ -115,7 +115,7 @@ GetDefinitionModule(id, incr)
                        if (!is_anon_idf(id) && GetFile(id->id_text)) {
 
                                DefModule();
-                               df = lookup(id, GlobalScope, 1);
+                               df = lookup(id, GlobalScope, 1, 0);
                                if (level == 1 &&
                                    (!df || !(df->df_flags & D_FOREIGN))) {
                                        /* The module is directly imported by
@@ -137,7 +137,7 @@ GetDefinitionModule(id, incr)
                                }
                        }
                        else {
-                               df = lookup(id, GlobalScope, 1);
+                               df = lookup(id, GlobalScope, 1, 0);
                                newsc->sc_name = id->id_text;
                        }
                        vis = CurrVis;
index 45befce..622eedc 100644 (file)
@@ -71,12 +71,16 @@ This is useful for interpreters that use the "real" MIN(INTEGER) to
 indicate "undefined".
 .IP \fB-R\fR
 disable all range checks.
+.IP \fB-3\fR
+only accept Modula-2 programs that strictly conform to [1].
 .LP
 .SH FILES
 .IR ~em/lib/em_m2 :
 binary of the Modula-2 compiler.
 .SH SEE ALSO
 \fIack\fR(1), \fImodula-2\fR(1)
+.IP [1]
+N. Wirth, \fIProgramming in Modula-2\fP, 3rd edition, Springer Verlag.
 .SH DIAGNOSTICS
 All warning and error messages are written on standard error output.
 .SH REMARKS
index 5280d63..c3f12db 100644 (file)
@@ -233,7 +233,7 @@ EnterParamList(ppr, Idlist, type, VARp, off)
 }
 
 STATIC
-DoImport(df, scope)
+DoImport(df, scope, kind)
        register t_def *df;
        t_scope *scope;
 {
@@ -241,9 +241,9 @@ DoImport(df, scope)
                Handle the case that it is an enumeration type or a module.
        */
 
-       define(df->df_idf, scope, D_IMPORT)->imp_def = df;
+       define(df->df_idf, scope, kind)->imp_def = df;
 
-       while (df->df_kind == D_IMPORT) {
+       while (df->df_kind & D_IMPORTED) {
                df = df->imp_def;
        }
 
@@ -251,7 +251,12 @@ DoImport(df, scope)
                /* Also import all enumeration literals
                */
                for (df = df->df_type->enm_enums; df; df = df->enm_next) {
-                       define(df->df_idf, scope, D_IMPORT)->imp_def = df;
+                       register t_def *df1 = define(df->df_idf, scope, kind);
+                       
+                       df1->imp_def = df;
+                       df1->df_flags |= D_USED;/* don't complain when these
+                                                  are not used
+                                               */
                }
        }
        else if (df->df_kind == D_MODULE) {
@@ -267,7 +272,12 @@ DoImport(df, scope)
                     df;
                     df = df->df_nextinscope) {
                        if (df->df_flags & D_EXPORTED) {
-                               define(df->df_idf,scope,D_IMPORT)->imp_def = df;
+                               register t_def *df1 =
+                                       define(df->df_idf, scope, kind);
+                       
+                               df1->imp_def = df;
+                               df1->df_flags |= D_USED;
+                               /* don't complain when these are not used */
                        }
                }
        }
@@ -312,7 +322,7 @@ ForwDef(ids, scope)
        */
        register t_def *df;
 
-       if (!(df = lookup(ids->nd_IDF, scope, 0))) {
+       if (!(df = lookup(ids->nd_IDF, scope, 0, 0))) {
                df = define(ids->nd_IDF, scope, D_FORWARD);
                df->for_node = MkLeaf(Name, &(ids->nd_token));
        }
@@ -331,7 +341,7 @@ EnterExportList(Idlist, qualified)
        register t_def *df, *df1;
 
        for (;idlist; idlist = idlist->nd_left) {
-               df = lookup(idlist->nd_IDF, CurrentScope, 0);
+               df = lookup(idlist->nd_IDF, CurrentScope, 0, 0);
 
                if (!df) {
                        /* undefined item in export list
@@ -356,9 +366,9 @@ EnterExportList(Idlist, qualified)
                        */
                        df1 = CurrentScope->sc_definedby->df_idf->id_def;
                        while (df1) {
-                               if (df1->df_kind == D_IMPORT &&
+                               if ((df1->df_kind & D_IMPORTED) &&
                                    df1->imp_def == CurrentScope->sc_definedby) {
-                                       DoImport(df, df1->df_scope);
+                                       DoImport(df, df1->df_scope, D_IMP_BY_EXP);
                                }
                                df1 = df1->df_next;
                        }
@@ -367,7 +377,7 @@ EnterExportList(Idlist, qualified)
                           scope imports it.
                        */
                        df1 = lookup(idlist->nd_IDF,
-                                    enclosing(CurrVis)->sc_scope, 1);
+                                    enclosing(CurrVis)->sc_scope, 1, 0);
                        if (df1) {
                                /* It was already defined in the enclosing
                                   scope. There are two legal possibilities,
@@ -375,12 +385,12 @@ EnterExportList(Idlist, qualified)
                                */
                                t_def *df2 = df;
 
-                               while (df2->df_kind == D_IMPORT) {
+                               while (df2->df_kind & D_IMPORTED) {
                                        df2 = df2->imp_def;
                                }
                                if (df1->df_kind == D_PROCHEAD &&
                                     df2->df_kind == D_PROCEDURE) {
-                                       df1->df_kind = D_IMPORT;
+                                       df1->df_kind = D_IMP_BY_EXP;
                                        df1->imp_def = df;
                                        continue;
                                }
@@ -392,7 +402,7 @@ EnterExportList(Idlist, qualified)
                                }
                        }
 
-                       DoImport(df, enclosing(CurrVis)->sc_scope);
+                       DoImport(df, enclosing(CurrVis)->sc_scope, D_IMP_BY_EXP);
                }
        }
        FreeNode(Idlist);
@@ -439,7 +449,7 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
 
        for (; idlist; idlist = idlist->nd_left) {
                if (forwflag) df = ForwDef(idlist, vis->sc_scope);
-               else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope, 0))) {
+               else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope, 0, 0))) {
                        if (! is_anon_idf(idlist->nd_IDF)) {
                                node_error(idlist,
                        "identifier \"%s\" not declared in module \"%s\"",
@@ -455,7 +465,7 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
                        module_name);
                        df->df_flags |= D_QEXPORTED;
                }
-               DoImport(df, CurrentScope);
+               DoImport(df, CurrentScope, D_IMPORT);
        }
 
        if (!forwflag) FreeNode(FromId);
@@ -473,7 +483,7 @@ EnterGlobalImportList(idlist)
        f = file_info;
 
        for (; idlist; idlist = idlist->nd_left) {
-               DoImport(GetDefinitionModule(idlist->nd_IDF, 1), CurrentScope);
+               DoImport(GetDefinitionModule(idlist->nd_IDF, 1), CurrentScope, D_IMPORT);
                file_info = f;
        }
 }
@@ -484,13 +494,8 @@ EnterImportList(idlist)
        /*      Import "idlist" from the enclosing scope.
        */
        t_scope *sc = enclosing(CurrVis)->sc_scope;
-       extern t_def *GetDefinitionModule();
 
        for (; idlist; idlist = idlist->nd_left) {
-               t_def *df;
-
-               DoImport(ForwDef(idlist, sc), CurrentScope);
-               df = lookup(idlist->nd_def, CurrentScope, 0);
-               df->df_flags |= D_EXPORTED;
+               DoImport(ForwDef(idlist, sc), CurrentScope, D_IMPORT);
        }
 }
index 0eb38a4..6656ea1 100644 (file)
@@ -24,7 +24,7 @@
 #include       "misc.h"
 
 t_def *
-lookup(id, scope, import)
+lookup(id, scope, import, flags)
        register t_idf *id;
        t_scope *scope;
 {
@@ -52,8 +52,9 @@ lookup(id, scope, import)
                        df->df_next = id->id_def;
                        id->id_def = df;
                }
+               df->df_flags |= flags;
                if (import) {
-                       while (df->df_kind == D_IMPORT) {
+                       while (df->df_kind & D_IMPORTED) {
                                assert(df->imp_def != 0);
                                df = df->imp_def;
                        }
@@ -63,24 +64,24 @@ lookup(id, scope, import)
 }
 
 t_def *
-lookfor(id, vis, give_error)
+lookfor(id, vis, message, flags)
        register t_node *id;
        t_scopelist *vis;
 {
        /*      Look for an identifier in the visibility range started by "vis".
                If it is not defined create a dummy definition and,
-               if "give_error" is set, give an error message.
+               if message is set, give an error message
        */
        register t_def *df;
        register t_scopelist *sc = vis;
 
        while (sc) {
-               df = lookup(id->nd_IDF, sc->sc_scope, 1);
+               df = lookup(id->nd_IDF, sc->sc_scope, 1, flags);
                if (df) return df;
                sc = nextvisible(sc);
        }
 
-       if (give_error) id_not_declared(id);
+       if (message) id_not_declared(id);
 
        df = MkDef(id->nd_IDF, vis->sc_scope, D_ERROR);
        return df;
index ccfdf58..a7c4167 100644 (file)
@@ -168,8 +168,10 @@ static struct stdproc {
        { "DEC",        S_DEC },
        { "INC",        S_INC },
        { "VAL",        S_VAL },
+#ifndef STRICT_3RD_ED
        { "NEW",        S_NEW },
        { "DISPOSE",    S_DISPOSE },
+#endif
        { "TRUNC",      S_TRUNC },
        { "SIZE",       S_SIZE },
        { "ORD",        S_ORD },
index 89ec9b4..31fbf66 100644 (file)
@@ -101,7 +101,9 @@ import(int local;)
 } :
        [ FROM
          IDENT         { FromId = dot2leaf(Name);
-                         if (local) df = lookfor(FromId,enclosing(CurrVis),0);
+                         if (local) {
+                               df = lookfor(FromId,enclosing(CurrVis),0,D_USED);
+                         }
                          else df = GetDefinitionModule(dot.TOK_IDF, 1);
                        }
        ]?
index 87bae1a..70eb52d 100644 (file)
@@ -121,7 +121,7 @@ chk_forw(pdf)
 
                        *pdf = df->df_nextinscope;
                        RemoveFromIdList(df);
-                       df = lookfor(nd, CurrVis, 1);
+                       df = lookfor(nd, CurrVis, 1, 0);
                        if (! df->df_kind & (D_ERROR|D_FTYPE|D_TYPE)) {
 node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
                        }
@@ -217,9 +217,8 @@ close_scope(flag)
 
        assert(sc != 0);
 
-       if (! sc->sc_end) {
-               sc->sc_end = dot2leaf(Link);
-       }
+       FreeNode(sc->sc_end);
+       sc->sc_end = dot2leaf(Link);
 
        if (flag) {
                DO_DEBUG(options['S'],(print("List of definitions in currently ended scope:\n"), DumpScope(sc->sc_def)));
index 213a656..853945c 100644 (file)
@@ -250,7 +250,7 @@ qualified_type(nd)
 {
        register t_def *df;
 
-       if (ChkDesignator(nd)) {
+       if (ChkDesig(nd, D_USED)) {
                if (nd->nd_class != Def) {
                        node_error(nd, "type expected");
                        FreeNode(nd);
@@ -606,7 +606,7 @@ type_or_forward(ptp)
        register t_node *nd;
        register t_def *df, *df1;
 
-       if ((df1 = lookup(dot.TOK_IDF, CurrentScope, 1))) {
+       if ((df1 = lookup(dot.TOK_IDF, CurrentScope, 1, D_USED))) {
                /* Either a Module or a Type, but in both cases defined
                   in this scope, so this is the correct identification
                */
@@ -618,7 +618,7 @@ type_or_forward(ptp)
                return 1;
        }
        nd = dot2leaf(0);
-       if ((df1 = lookfor(nd, CurrVis, 0))->df_kind == D_MODULE) {
+       if ((df1 = lookfor(nd, CurrVis, 0, D_USED))->df_kind == D_MODULE) {
                /* A Modulename in one of the enclosing scopes.
                   It is not clear from the language definition that
                   it is correct to handle these like this, but
index 9e522fa..d91cded 100644 (file)
@@ -37,6 +37,7 @@
 #include       "idf.h"
 #include       "chk_expr.h"
 #include       "walk.h"
+#include       "misc.h"
 #include       "warning.h"
 
 extern arith           NewPtr();
@@ -767,7 +768,6 @@ DoForInit(nd)
          if (!TstCompat(df->df_type, tpl) ||
              !TstCompat(df->df_type, tpr)) {
 node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
-               node_error(nd, "compatibility required in FOR statement");
          }
        } else
 #endif
@@ -851,11 +851,27 @@ static int
 UseWarnings(df)
        register t_def *df;
 {
-       if (df->df_kind & (D_IMPORT | D_VARIABLE | D_PROCEDURE)) {
+       if (is_anon_idf(df->df_idf)) return;
+       if (df->df_kind & (D_IMPORTED | D_VARIABLE | D_PROCEDURE)) {
                struct node *nd;
 
                if (df->df_flags & (D_EXPORTED | D_QEXPORTED)) return;
-               if (df->df_kind == D_IMPORT) df = df->imp_def;
+               if (df->df_kind & D_IMPORTED) {
+                       register t_def *df1 = df->imp_def;
+
+                       df1->df_flags |= df->df_flags & (D_USED|D_DEFINED);
+                       if (df->df_kind == D_IMPORT) {
+                               if (! (df->df_flags & (D_USED | D_DEFINED))) {
+                                       node_warning(
+                                               df->df_scope->sc_end,
+                                               W_ORDINARY,
+                                               "identifier \"%s\" imported but not used/assigned",
+                                               df->df_idf->id_text);
+                               }
+                               return;
+                       }
+                       df = df1;
+               }
                if (! (df->df_kind & (D_VARIABLE|D_PROCEDURE))) return;
                nd = df->df_scope->sc_end;
                if (! (df->df_flags & D_DEFINED)) {