fixed some problems:

- removed null-reference in illegal use of pointers in constant expressions
- FOR-loops that count downwards did not work
- POINTER TO mechanism changed; works better now
This commit is contained in:
ceriel 1988-11-15 14:45:59 +00:00
parent 090f27251e
commit f1245e2e00
8 changed files with 86 additions and 49 deletions

View file

@ -161,7 +161,8 @@ ChkArrow(expp)
return ex_error(expp, "illegal operand type");
}
expp->nd_type = RemoveEqual(PointedtoType(tp));
if ((tp = RemoveEqual(PointedtoType(tp))) == 0) tp = error_type;
expp->nd_type = tp;
return 1;
}

View file

@ -71,7 +71,9 @@ struct dforward {
struct forwtype {
struct node *f_node;
struct def *f_def;
#define df_forw_node df_value.df_fortype.f_node
#define df_forw_def df_value.df_fortype.f_def
};
struct def { /* list of definitions for a name */
@ -94,14 +96,13 @@ struct def { /* list of definitions for a name */
#define D_FORWARD 0x0400 /* not yet defined */
#define D_FORWMODULE 0x0800 /* module must be declared later */
#define D_FORWTYPE 0x1000 /* forward type */
#define D_FTYPE 0x2000 /* resolved forward type */
#define D_ERROR 0x4000 /* a compiler generated definition for an
undefined variable
*/
#define D_INUSE 0x8000 /* identification in this scope (like D_IMPORT)
*/
#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_ISTYPE (D_HIDDEN|D_TYPE)
#define D_IMPORTED (D_IMPORT|D_INUSE)
#define is_type(dfx) ((dfx)->df_kind & D_ISTYPE)
unsigned short df_flags;

View file

@ -157,10 +157,7 @@ define(id, scope, kind)
if (kind == D_FORWTYPE) return df;
break;
case D_FORWTYPE:
if (kind == D_FORWTYPE) return df;
if (kind == D_TYPE) {
df->df_kind = D_FTYPE;
}
if (kind & (D_FORWTYPE|D_TYPE)) return df;
else {
error("identifier \"%s\" must be a type",
id->id_text);

View file

@ -251,8 +251,7 @@ ImportEffects(idef, scope, flag)
}
tp = BaseType(df->df_type);
if ((df->df_kind & (D_TYPE|D_FTYPE)) &&
tp->tp_fund == T_ENUMERATION) {
if (df->df_kind == D_TYPE && tp->tp_fund == T_ENUMERATION) {
/* Also import all enumeration literals
*/
for (df = tp->enm_enums; df; df = df->enm_next) {
@ -416,7 +415,7 @@ EnterExportList(Idlist, qualified)
continue;
}
if (df1->df_kind == D_HIDDEN &&
(df2->df_kind & (D_TYPE|D_FTYPE))) {
df2->df_kind == D_TYPE) {
DeclareType(idlist, df1, df2->df_type);
df1->df_kind = D_TYPE;
continue;

View file

@ -189,6 +189,7 @@ definition
[ %persistent
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
[ '=' type(&(df->df_type))
{ SolveForwardTypeRefs(df); }
| /* empty */
/*
Here, the exported type has a hidden implementation.

View file

@ -109,34 +109,10 @@ chk_forw(pdf)
while (df = *pdf) {
if (df->df_kind == D_FORWTYPE) {
register t_def *df1 = df;
register t_node *nd = df->df_forw_node;
*pdf = df->df_nextinscope;
RemoveFromIdList(df);
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);
}
while (nd) {
nd->nd_type->tp_next = df->df_type;
nd = nd->nd_right;
}
FreeNode(df1->df_forw_node);
free_def(df1);
ForceForwardTypeDef(df); /* removes df */
continue;
}
else if (df->df_kind == D_FTYPE) {
register t_node *nd = df->df_forw_node;
df->df_kind = D_TYPE;
while (nd) {
nd->nd_type->tp_next = df->df_type;
nd = nd->nd_right;
}
FreeNode(df->df_forw_node);
}
else if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
/* These definitions must be found in
the enclosing closed scope, which of course
may be the scope that is now closed!

View file

@ -269,7 +269,11 @@ node_error(nd,"type \"%s\" not (yet) declared", df->df_idf->id_text);
}
FreeNode(nd);
if (df->df_kind == D_FORWTYPE) {
df->df_kind = D_FTYPE;
/* Here, df->df_type was already set,
so there is an actual definition in the
surrounding scope, which is now used.
*/
ForceForwardTypeDef(df);
}
return df->df_type;
}
@ -646,6 +650,58 @@ DeclareType(nd, df, tp)
CheckForImports(df);
}
}
SolveForwardTypeRefs(df);
}
SolveForwardTypeRefs(df)
register t_def *df;
{
register t_node *nd;
if (df->df_kind == D_FORWTYPE) {
nd = df->df_forw_node;
df->df_kind = D_TYPE;
while (nd) {
nd->nd_type->tp_next = df->df_type;
nd = nd->nd_right;
}
FreeNode(df->df_forw_node);
}
}
ForceForwardTypeDef(df)
register t_def *df;
{
register t_def *df1 = df, *df2;
register t_node *nd = df->df_forw_node;
while (df && df->df_kind == D_FORWTYPE) {
RemoveFromIdList(df);
if ((df2 = df->df_scope->sc_def) == df) {
df->df_scope->sc_def = df->df_nextinscope;
}
else {
while (df2->df_nextinscope != df) {
df2 = df2->df_nextinscope;
}
df2->df_nextinscope = df->df_nextinscope;
}
df = df->df_forw_def;
}
df = lookfor(nd, CurrVis, 1, 0);
if (! df->df_kind & (D_ERROR|D_TYPE)) {
node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
}
while (df1 && df1->df_kind == D_FORWTYPE) {
t_def *df2 = df1->df_forw_def;
df1->df_type = df->df_type;
SolveForwardTypeRefs(df1);
free_def(df1);
df1 = df2;
}
}
t_type *
@ -686,6 +742,8 @@ type_or_forward(ptp)
existing compilers do it like this, and the
alternative is difficult with a lookahead of only
one token.
This path should actually only be taken if the next token
is a '.'.
???
*/
FreeNode(nd);
@ -697,17 +755,17 @@ type_or_forward(ptp)
same scope.
*/
df = define(nd->nd_IDF, CurrentScope, D_FORWTYPE);
assert(df->df_kind == D_FORWTYPE);
df->df_flags |= D_USED | D_DEFINED;
if (df->df_kind == D_TYPE) {
(*ptp)->tp_next = df->df_type;
FreeNode(nd);
return 0;
}
nd->nd_type = *ptp;
df->df_forw_node = nd;
if (df1->df_kind == D_TYPE) {
if (df != df1 && (df1->df_kind & (D_TYPE | D_FORWTYPE))) {
/* "df1" refers to a possible identification, but
we cannot be sure at this point. For the time
being, however, we use this one.
*/
df->df_type = df1->df_type;
df->df_forw_def = df1;
}
return 0;
}

View file

@ -552,8 +552,10 @@ WalkStat(nd, exit_label)
C_lol(tmp);
if (uns) C_cmu(int_size);
else C_cmi(int_size);
C_zgt(l2);
if (left->nd_INT >= 0) C_zgt(l2);
else C_zlt(l2);
C_lol(tmp2);
RangeCheck(nd->nd_type, left->nd_left->nd_type);
CodeDStore(nd);
C_lol(tmp);
ForLoopVarExpr(nd);
@ -736,6 +738,7 @@ DoForInit(nd)
{
register t_node *left = nd->nd_left;
register t_def *df;
register t_type *base_tp;
t_type *tpl, *tpr;
nd->nd_left = nd->nd_right = 0;
@ -778,12 +781,13 @@ DoForInit(nd)
return 1;
}
base_tp = BaseType(df->df_type);
tpl = left->nd_left->nd_type;
tpr = left->nd_right->nd_type;
#ifndef STRICT_3RD_ED
if (! options['3']) {
if (!ChkAssCompat(&(left->nd_left), df->df_type, "FOR statement") ||
!ChkAssCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) {
if (!ChkAssCompat(&(left->nd_left), base_tp, "FOR statement") ||
!ChkAssCompat(&(left->nd_right), base_tp, "FOR statement")) {
return 1;
}
if (!TstCompat(df->df_type, tpl) ||
@ -792,8 +796,8 @@ node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
}
} else
#endif
if (!ChkCompat(&(left->nd_left), df->df_type, "FOR statement") ||
!ChkCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) {
if (!ChkCompat(&(left->nd_left), base_tp, "FOR statement") ||
!ChkCompat(&(left->nd_right), base_tp, "FOR statement")) {
return 1;
}