From 015e1b776e0097980016f59ce1080b832eb6228f Mon Sep 17 00:00:00 2001 From: ceriel Date: Wed, 21 Oct 1987 11:29:52 +0000 Subject: [PATCH] Some corrections and additions to improve the mechanism for generating warnings on unused/uninitialized variables --- lang/m2/comp/Makefile | 1 + lang/m2/comp/Version.c | 2 +- lang/m2/comp/chk_expr.c | 22 ++++++++---------- lang/m2/comp/def.H | 6 +++-- lang/m2/comp/def.c | 9 ++++---- lang/m2/comp/defmodule.c | 8 +++---- lang/m2/comp/em_m2.6 | 4 ++++ lang/m2/comp/enter.c | 49 ++++++++++++++++++++++------------------ lang/m2/comp/lookup.c | 13 ++++++----- lang/m2/comp/main.c | 2 ++ lang/m2/comp/program.g | 4 +++- lang/m2/comp/scope.C | 7 +++--- lang/m2/comp/type.c | 6 ++--- lang/m2/comp/walk.c | 22 +++++++++++++++--- 14 files changed, 92 insertions(+), 63 deletions(-) diff --git a/lang/m2/comp/Makefile b/lang/m2/comp/Makefile index 5b8398508..b944a3b73 100644 --- a/lang/m2/comp/Makefile +++ b/lang/m2/comp/Makefile @@ -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 diff --git a/lang/m2/comp/Version.c b/lang/m2/comp/Version.c index 9be6dced6..c3c7688ca 100644 --- a/lang/m2/comp/Version.c +++ b/lang/m2/comp/Version.c @@ -1 +1 @@ -static char Version[] = "ACK Modula-2 compiler Version 0.21"; +static char Version[] = "ACK Modula-2 compiler Version 0.22"; diff --git a/lang/m2/comp/chk_expr.c b/lang/m2/comp/chk_expr.c index 2ee76d19f..a7048bfaa 100644 --- a/lang/m2/comp/chk_expr.c +++ b/lang/m2/comp/chk_expr.c @@ -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); } diff --git a/lang/m2/comp/def.H b/lang/m2/comp/def.H index 561f1ac8f..c85bec425 100644 --- a/lang/m2/comp/def.H +++ b/lang/m2/comp/def.H @@ -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 */ diff --git a/lang/m2/comp/def.c b/lang/m2/comp/def.c index bed3ceea9..613af6bab 100644 --- a/lang/m2/comp/def.c +++ b/lang/m2/comp/def.c @@ -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 diff --git a/lang/m2/comp/defmodule.c b/lang/m2/comp/defmodule.c index adb5e81fc..5cb99d821 100644 --- a/lang/m2/comp/defmodule.c +++ b/lang/m2/comp/defmodule.c @@ -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; diff --git a/lang/m2/comp/em_m2.6 b/lang/m2/comp/em_m2.6 index 45befce08..622eedc5d 100644 --- a/lang/m2/comp/em_m2.6 +++ b/lang/m2/comp/em_m2.6 @@ -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 diff --git a/lang/m2/comp/enter.c b/lang/m2/comp/enter.c index 5280d6314..c3f12db7f 100644 --- a/lang/m2/comp/enter.c +++ b/lang/m2/comp/enter.c @@ -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); } } diff --git a/lang/m2/comp/lookup.c b/lang/m2/comp/lookup.c index 0eb38a466..6656ea1c4 100644 --- a/lang/m2/comp/lookup.c +++ b/lang/m2/comp/lookup.c @@ -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; diff --git a/lang/m2/comp/main.c b/lang/m2/comp/main.c index ccfdf58cb..a7c416786 100644 --- a/lang/m2/comp/main.c +++ b/lang/m2/comp/main.c @@ -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 }, diff --git a/lang/m2/comp/program.g b/lang/m2/comp/program.g index 89ec9b448..31fbf66e8 100644 --- a/lang/m2/comp/program.g +++ b/lang/m2/comp/program.g @@ -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); } ]? diff --git a/lang/m2/comp/scope.C b/lang/m2/comp/scope.C index 87bae1a74..70eb52d8f 100644 --- a/lang/m2/comp/scope.C +++ b/lang/m2/comp/scope.C @@ -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))); diff --git a/lang/m2/comp/type.c b/lang/m2/comp/type.c index 213a65621..853945c59 100644 --- a/lang/m2/comp/type.c +++ b/lang/m2/comp/type.c @@ -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 diff --git a/lang/m2/comp/walk.c b/lang/m2/comp/walk.c index 9e522fa75..d91cdede5 100644 --- a/lang/m2/comp/walk.c +++ b/lang/m2/comp/walk.c @@ -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)) { -- 2.34.1