From ad1feaf35cef689f3010d888550f8d7c37d69daf Mon Sep 17 00:00:00 2001 From: dick Date: Thu, 27 Mar 1986 18:17:48 +0000 Subject: [PATCH] expression nodes now can have a flag EX_ERROR --- lang/cem/cemcom/arith.c | 10 +++++----- lang/cem/cemcom/ch7.c | 24 ++++++++++++++++-------- lang/cem/cemcom/ch7bin.c | 6 ++---- lang/cem/cemcom/ch7mon.c | 11 +++-------- lang/cem/cemcom/dumpidf.c | 4 ++-- lang/cem/cemcom/error.c | 5 +++++ lang/cem/cemcom/expr.c | 6 +++--- lang/cem/cemcom/expr.str | 11 ++++++----- lang/cem/cemcom/ival.c | 3 +-- lang/cem/cemcom/program.g | 3 ++- lang/cem/cemcom/switch.c | 5 +++++ 11 files changed, 50 insertions(+), 38 deletions(-) diff --git a/lang/cem/cemcom/arith.c b/lang/cem/cemcom/arith.c index 29755d4d9..629fbac00 100644 --- a/lang/cem/cemcom/arith.c +++ b/lang/cem/cemcom/arith.c @@ -110,12 +110,10 @@ ch76pointer(expp, oper, tp) ) /* ch 7.7 */ ch7cast(expp, CAST, tp); else { - if ((*expp)->ex_type != error_type) - expr_error(*expp, "%s on %s and pointer", + expr_error(*expp, "%s on %s and pointer", symbol2str(oper), symbol2str((*expp)->ex_type->tp_fund) ); - (*expp)->ex_type = error_type; ch7cast(expp, oper, tp); } } @@ -177,8 +175,11 @@ erroneous2int(expp) /* the (erroneous) expression *expp is replaced by an int expression */ + int flags = (*expp)->ex_flags; + free_expression(*expp); *expp = intexpr((arith)0, INT); + (*expp)->ex_flags = (flags | EX_ERROR); } struct expr * @@ -291,8 +292,7 @@ opnd2integral(expp, oper) register int fund = (*expp)->ex_type->tp_fund; if (fund != INT && fund != LONG) { - if (fund != ERRONEOUS) - expr_error(*expp, "%s operand to %s", + expr_error(*expp, "%s operand to %s", symbol2str(fund), symbol2str(oper)); erroneous2int(expp); /* fund = INT; */ diff --git a/lang/cem/cemcom/ch7.c b/lang/cem/cemcom/ch7.c index 9812e8f85..0f39bcfd9 100644 --- a/lang/cem/cemcom/ch7.c +++ b/lang/cem/cemcom/ch7.c @@ -61,7 +61,6 @@ ch7sel(expp, oper, idf) /* filter out illegal expressions "non_lvalue.sel" */ if (!(*expp)->ex_lvalue) { expr_error(*expp, "dot requires lvalue"); - (*expp)->ex_type = error_type; return; } } @@ -102,6 +101,8 @@ ch7sel(expp, oper, idf) */ (*expp)->VL_VALUE += sd->sd_offset; (*expp)->ex_type = sd->sd_type; + if ((*expp)->ex_type == error_type) + (*expp)->ex_flags |= EX_ERROR; } else if ((*expp)->ex_class == Oper) { @@ -110,16 +111,20 @@ ch7sel(expp, oper, idf) if (op->op_oper == '.' || op->op_oper == ARROW) { op->op_right->VL_VALUE += sd->sd_offset; (*expp)->ex_type = sd->sd_type; + if ((*expp)->ex_type == error_type) + (*expp)->ex_flags |= EX_ERROR; } else *expp = new_oper(sd->sd_type, *expp, '.', intexpr(sd->sd_offset, INT)); } } - else /* oper == ARROW */ + else { + /* oper == ARROW */ *expp = new_oper(sd->sd_type, *expp, oper, intexpr(sd->sd_offset, INT)); - (*expp)->ex_lvalue = sd->sd_type->tp_fund != ARRAY; + } + (*expp)->ex_lvalue = (sd->sd_type->tp_fund != ARRAY); } ch7incr(expp, oper) @@ -152,8 +157,7 @@ ch7incr(expp, oper) addend = (arith)1; #endif NOBITFIELD else { - if ((*expp)->ex_type != error_type) - expr_error(*expp, "%s on %s", + expr_error(*expp, "%s on %s", symbol2str(oper), symbol2str((*expp)->ex_type->tp_fund) ); @@ -280,18 +284,22 @@ ch7cast(expp, oper, tp) (*expp)->ex_type = tp; } else + if (oldtp->tp_fund == ERRONEOUS) { + /* we just won't look */ + (*expp)->ex_type = tp; /* brute force */ + } + else if (oldtp->tp_size == tp->tp_size && oper == CAST) { expr_warning(*expp, "dubious conversion based on equal size"); (*expp)->ex_type = tp; /* brute force */ } - else - { + else { if (oldtp->tp_fund != ERRONEOUS && tp->tp_fund != ERRONEOUS) expr_error(*expp, "cannot convert %s to %s", symbol2str(oldtp->tp_fund), symbol2str(tp->tp_fund) ); - (*expp)->ex_type = tp; + (*expp)->ex_type = tp; /* brute force */ } } diff --git a/lang/cem/cemcom/ch7bin.c b/lang/cem/cemcom/ch7bin.c index 12d926786..217eecb55 100644 --- a/lang/cem/cemcom/ch7bin.c +++ b/lang/cem/cemcom/ch7bin.c @@ -64,9 +64,8 @@ ch7bin(expp, oper, expr) ch7mon('*', expp); } if ((*expp)->ex_type->tp_fund != FUNCTION) { - if ((*expp)->ex_type != error_type) - expr_error(*expp, "call of non-function (%s)", - symbol2str((*expp)->ex_type->tp_fund)); + expr_error(*expp, "call of non-function (%s)", + symbol2str((*expp)->ex_type->tp_fund)); /* leave the expression; it may still serve */ free_expression(expr); /* there go the parameters */ } @@ -202,7 +201,6 @@ ch7bin(expp, oper, expr) ) { if ((*expp)->ex_type != expr->ex_type) { expr_error(*expp, "illegal balance"); - (*expp)->ex_type = error_type; } } else { diff --git a/lang/cem/cemcom/ch7mon.c b/lang/cem/cemcom/ch7mon.c index 5c1441928..f18969f3f 100644 --- a/lang/cem/cemcom/ch7mon.c +++ b/lang/cem/cemcom/ch7mon.c @@ -28,11 +28,9 @@ ch7mon(oper, expp) if ((*expp)->ex_type->tp_fund == ARRAY) array2pointer(expp); if ((*expp)->ex_type->tp_fund != POINTER) { - if ((*expp)->ex_type != error_type) - expr_error(*expp, - "* applied to non-pointer (%s)", - symbol2str((*expp)->ex_type->tp_fund)); - (*expp)->ex_type = error_type; + expr_error(*expp, + "* applied to non-pointer (%s)", + symbol2str((*expp)->ex_type->tp_fund)); } else { expr = *expp; @@ -59,13 +57,11 @@ ch7mon(oper, expp) #ifndef NOBITFIELD if ((*expp)->ex_type->tp_fund == FIELD) { expr_error(*expp, "& applied to field variable"); - (*expp)->ex_type = error_type; } else #endif NOBITFIELD if (!(*expp)->ex_lvalue) { expr_error(*expp, "& applied to non-lvalue"); - (*expp)->ex_type = error_type; } else { /* assume that enums are already filtered out */ @@ -79,7 +75,6 @@ ch7mon(oper, expp) if (def->df_sc == REGISTER) { expr_error(*expp, "& on register variable not allowed"); - (*expp)->ex_type = error_type; break; /* break case '&' */ } def->df_register = REG_NONE; diff --git a/lang/cem/cemcom/dumpidf.c b/lang/cem/cemcom/dumpidf.c index 867b73174..1c20e88b5 100644 --- a/lang/cem/cemcom/dumpidf.c +++ b/lang/cem/cemcom/dumpidf.c @@ -318,11 +318,11 @@ p1_expr(lvl, expr) printf("NILEXPR\n"); return; } - printf("expr: L=%u, T=%s, %cV, F=%02o, D=%d, %s: ", + printf("expr: L=%u, T=%s, %cV, F=%03o, D=%d, %s: ", expr->ex_line, type2str(expr->ex_type), expr->ex_lvalue ? 'l' : 'r', - expr->ex_flags, + expr->ex_flags & 0xFF, expr->ex_depth, expr->ex_class == Value ? "Value" : expr->ex_class == String ? "String" : diff --git a/lang/cem/cemcom/error.c b/lang/cem/cemcom/error.c index 7b1629ecc..0917808d8 100644 --- a/lang/cem/cemcom/error.c +++ b/lang/cem/cemcom/error.c @@ -56,7 +56,10 @@ expr_error(expr, fmt, args) struct expr *expr; char *fmt; { + if (expr->ex_flags & EX_ERROR) + return; /* to prevent proliferation */ _error(ERROR, expr, fmt, &args); + expr->ex_flags |= EX_ERROR; } /*VARARGS1*/ @@ -71,6 +74,8 @@ expr_warning(expr, fmt, args) struct expr *expr; char *fmt; { + if (expr->ex_flags & EX_ERROR) + return; /* to prevent proliferation */ _error(WARNING, expr, fmt, &args); } diff --git a/lang/cem/cemcom/expr.c b/lang/cem/cemcom/expr.c index f343c6adb..ba07d30ca 100644 --- a/lang/cem/cemcom/expr.c +++ b/lang/cem/cemcom/expr.c @@ -169,12 +169,13 @@ idf2expr(expr) } /* now def != 0 */ if (def->df_type->tp_fund == LABEL) { - error("illegal use of label %s", idf->id_text); - expr->ex_type = error_type; + expr_error(expr, "illegal use of label %s", idf->id_text); } else { def->df_used = 1; expr->ex_type = def->df_type; + if (expr->ex_type == error_type) + expr->ex_flags |= EX_ERROR; } expr->ex_lvalue = ( def->df_type->tp_fund == FUNCTION || @@ -381,7 +382,6 @@ chk_cst_expr(expp) if (err) { erroneous2int(expp); - (*expp)->ex_type = error_type; } } diff --git a/lang/cem/cemcom/expr.str b/lang/cem/cemcom/expr.str index 5809dccae..2531672db 100644 --- a/lang/cem/cemcom/expr.str +++ b/lang/cem/cemcom/expr.str @@ -68,11 +68,12 @@ struct expr { /* some bits for the ex_flag field, to keep track of various interesting properties of an expression. */ -#define EX_SIZEOF 001 /* contains sizeof operator */ -#define EX_CAST 002 /* contains cast */ -#define EX_LOGICAL 004 /* contains logical operator */ -#define EX_COMMA 010 /* contains expression comma */ -#define EX_PARENS 020 /* the top level is parenthesized */ +#define EX_SIZEOF 0001 /* contains sizeof operator */ +#define EX_CAST 0002 /* contains cast */ +#define EX_LOGICAL 0004 /* contains logical operator */ +#define EX_COMMA 0010 /* contains expression comma */ +#define EX_PARENS 0020 /* the top level is parenthesized */ +#define EX_ERROR 0200 /* the expression is wrong */ #define NILEXPR ((struct expr *)0) diff --git a/lang/cem/cemcom/ival.c b/lang/cem/cemcom/ival.c index cbc7fb093..8e921e964 100644 --- a/lang/cem/cemcom/ival.c +++ b/lang/cem/cemcom/ival.c @@ -668,8 +668,7 @@ con_int(expr) illegal_init_cst(expr) struct expr *expr; { - if (expr->ex_type->tp_fund != ERRONEOUS) - expr_error(expr, "illegal initialisation constant"); + expr_error(expr, "illegal initialisation constant"); } too_many_initialisers(expr) diff --git a/lang/cem/cemcom/program.g b/lang/cem/cemcom/program.g index 5817aa0fd..36da56e5a 100644 --- a/lang/cem/cemcom/program.g +++ b/lang/cem/cemcom/program.g @@ -71,7 +71,8 @@ control_if_expression { #ifndef NOPP if (expr->ex_flags & EX_SIZEOF) - error("sizeof not allowed in preprocessor"); + expr_error(expr, + "sizeof not allowed in preprocessor"); ifval = expr->VL_VALUE; free_expression(expr); #endif NOPP diff --git a/lang/cem/cemcom/switch.c b/lang/cem/cemcom/switch.c index 7965c7009..28db313f8 100644 --- a/lang/cem/cemcom/switch.c +++ b/lang/cem/cemcom/switch.c @@ -129,6 +129,11 @@ code_case(expr) return; } + if (expr->ex_flags & EX_ERROR) { + /* is probably 0 anyway */ + return; + } + expr->ex_type = sh->sh_type; cut_size(expr);