From 1f7115fa8d0693dbcb0f38388d8dc1777660d64b Mon Sep 17 00:00:00 2001 From: dick Date: Fri, 16 Sep 1988 23:19:50 +0000 Subject: [PATCH] error messages and error handling --- lang/cem/cemcom/.distr | 12 ++++++ lang/cem/cemcom/LLlex.c | 4 +- lang/cem/cemcom/arith.c | 1 - lang/cem/cemcom/ch7.c | 4 +- lang/cem/cemcom/ch7bin.c | 1 + lang/cem/cemcom/ch7mon.c | 4 +- lang/cem/cemcom/code.c | 9 ++--- lang/cem/cemcom/conversion.c | 1 + lang/cem/cemcom/declar.g | 1 - lang/cem/cemcom/declarator.c | 4 +- lang/cem/cemcom/decspecs.c | 4 +- lang/cem/cemcom/def.str | 2 +- lang/cem/cemcom/error.c | 78 +++++++++++++++--------------------- lang/cem/cemcom/eval.c | 5 ++- lang/cem/cemcom/expr.c | 3 +- lang/cem/cemcom/idf.c | 12 +++--- lang/cem/cemcom/idf.str | 4 +- lang/cem/cemcom/ival.g | 2 +- lang/cem/cemcom/main.c | 13 +++--- lang/cem/cemcom/options.c | 18 +++++---- lang/cem/cemcom/program.g | 1 - lang/cem/cemcom/replace.c | 1 + lang/cem/cemcom/scan.c | 2 +- lang/cem/cemcom/stack.c | 1 + lang/cem/cemcom/statement.g | 8 ++-- lang/cem/cemcom/struct.c | 2 +- lang/cem/cemcom/switch.c | 15 ++++--- 27 files changed, 111 insertions(+), 101 deletions(-) diff --git a/lang/cem/cemcom/.distr b/lang/cem/cemcom/.distr index 919dfb389..1a1169499 100644 --- a/lang/cem/cemcom/.distr +++ b/lang/cem/cemcom/.distr @@ -7,6 +7,7 @@ LLlex.h LLmessage.c SmallPars BigPars +LintPars align.h arith.c arith.h @@ -87,3 +88,14 @@ type.c type.str util.str util.c +acklint +l_class.h +l_comment.c +l_ev_ord.c +l_lint.c +l_lint.h +l_misc.c +l_outdef.c +l_outdef.str +l_state.str +l_states.c diff --git a/lang/cem/cemcom/LLlex.c b/lang/cem/cemcom/LLlex.c index 89ec3392c..9b6bbf322 100644 --- a/lang/cem/cemcom/LLlex.c +++ b/lang/cem/cemcom/LLlex.c @@ -234,8 +234,8 @@ firstline: LoadChar(ch); if (ch != nch) { PushBack(); - lexerror("illegal combination '=%c'", - nch); + lexerror("illegal operator '=%c%c'", + nch, ch); } return ptok->tk_symb = nch == '<' ? LEFTAB : RIGHTAB; diff --git a/lang/cem/cemcom/arith.c b/lang/cem/cemcom/arith.c index 3d87fbd7b..b8928a1bf 100644 --- a/lang/cem/cemcom/arith.c +++ b/lang/cem/cemcom/arith.c @@ -11,7 +11,6 @@ semantics of C is a mess. */ -#include "botch_free.h" #include #include "nofloat.h" #include "nobitfield.h" diff --git a/lang/cem/cemcom/ch7.c b/lang/cem/cemcom/ch7.c index d0997df4c..3fd3919ee 100644 --- a/lang/cem/cemcom/ch7.c +++ b/lang/cem/cemcom/ch7.c @@ -207,8 +207,10 @@ ch7cast(expp, oper, tp) else /* !oldi && !i */ float2float(expp, tp); #else NOFLOAT - else + else { crash("(ch7cast) floats not implemented\n"); + /*NOTREACHED*/ + } #endif NOFLOAT } else diff --git a/lang/cem/cemcom/ch7bin.c b/lang/cem/cemcom/ch7bin.c index d9a997fb2..b34957749 100644 --- a/lang/cem/cemcom/ch7bin.c +++ b/lang/cem/cemcom/ch7bin.c @@ -35,6 +35,7 @@ ch7bin(expp, oper, expr) /* apply binary operator oper between *expp and expr. NB: don't swap operands if op is one of the op= operators!!! */ + any2opnd(expp, oper); any2opnd(&expr, oper); switch (oper) { diff --git a/lang/cem/cemcom/ch7mon.c b/lang/cem/cemcom/ch7mon.c index 102f72561..dabefba71 100644 --- a/lang/cem/cemcom/ch7mon.c +++ b/lang/cem/cemcom/ch7mon.c @@ -53,12 +53,12 @@ ch7mon(oper, expp) break; case '&': if ((*expp)->ex_type->tp_fund == ARRAY) { - warning("& before array: ignored"); + warning("& before array ignored"); array2pointer(*expp); } else if ((*expp)->ex_type->tp_fund == FUNCTION) { - warning("& before function: ignored"); + warning("& before function ignored"); function2pointer(*expp); } else diff --git a/lang/cem/cemcom/code.c b/lang/cem/cemcom/code.c index e1564f7bb..fea6ff8b4 100644 --- a/lang/cem/cemcom/code.c +++ b/lang/cem/cemcom/code.c @@ -29,7 +29,6 @@ #include "assert.h" #include "noRoption.h" #include "file_info.h" - label lab_count = 1; label datlab_count = 1; @@ -48,7 +47,7 @@ static int pro_id; #endif USE_TMP extern char options[]; -char *symbol2str(); +extern char *symbol2str(); init_code(dst_file) char *dst_file; @@ -65,7 +64,6 @@ init_code(dst_file) C_insertpart(tmp_id = C_getid()); #endif USE_TMP } - static struct string_cst *str_list = 0; code_string(val, len, dlb) @@ -425,7 +423,7 @@ code_declaration(idf, expr, lvl, sc) break; default: crash("bad local storage class"); - break; + /*NOTREACHED*/ } } } @@ -446,7 +444,8 @@ loc_init(expr, id) case ARRAY: case STRUCT: case UNION: - error("no automatic aggregate initialisation"); + error("automatic %s cannot be initialized in declaration", + symbol2str(tp->tp_fund)); free_expression(e); return; } diff --git a/lang/cem/cemcom/conversion.c b/lang/cem/cemcom/conversion.c index afc7ec524..903f2454a 100644 --- a/lang/cem/cemcom/conversion.c +++ b/lang/cem/cemcom/conversion.c @@ -102,6 +102,7 @@ conversion(from_type, to_type) #endif NOFLOAT default: crash("(conversion) illegal type conversion"); + /*NOTREACHED*/ } if ((int)(to_type->tp_size) < (int)word_size #ifndef NOFLOAT diff --git a/lang/cem/cemcom/declar.g b/lang/cem/cemcom/declar.g index 944607c63..2a6e5a51f 100644 --- a/lang/cem/cemcom/declar.g +++ b/lang/cem/cemcom/declar.g @@ -24,7 +24,6 @@ #include "expr.h" #include "sizes.h" #include "level.h" - extern char options[]; } diff --git a/lang/cem/cemcom/declarator.c b/lang/cem/cemcom/declarator.c index 2ee03aa3a..c6727b581 100644 --- a/lang/cem/cemcom/declarator.c +++ b/lang/cem/cemcom/declarator.c @@ -97,12 +97,12 @@ check_array_subscript(expr) arith size = expr->VL_VALUE; if (size < 0) { - error("negative number of array elements"); + error("array size is negative"); expr->VL_VALUE = (arith)1; } else if (size == 0) { - warning("empty array declaration"); + warning("array size is 0"); } else if (size & ~max_unsigned) { /* absolutely ridiculous */ diff --git a/lang/cem/cemcom/decspecs.c b/lang/cem/cemcom/decspecs.c index 7fc45a2fb..10a07cd90 100644 --- a/lang/cem/cemcom/decspecs.c +++ b/lang/cem/cemcom/decspecs.c @@ -6,6 +6,7 @@ /* D E C L A R A T I O N S P E C I F I E R C H E C K I N G */ #include "nofloat.h" +#include "assert.h" #include "Lpars.h" #include "decspecs.h" #include "arith.h" @@ -28,8 +29,7 @@ do_decspecs(ds) */ register struct type *tp = ds->ds_type; - if (level == L_FORMAL1) - crash("do_decspecs"); + ASSERT(level != L_FORMAL1); if ( level == L_GLOBAL && (ds->ds_sc == AUTO || ds->ds_sc == REGISTER) diff --git a/lang/cem/cemcom/def.str b/lang/cem/cemcom/def.str index 5de425ea1..3c30fb659 100644 --- a/lang/cem/cemcom/def.str +++ b/lang/cem/cemcom/def.str @@ -20,7 +20,7 @@ struct def { /* for ordinary tags */ char df_alloc; /* 0, ALLOC_SEEN or ALLOC_DONE */ char df_used; /* set if idf is used */ char *df_file; /* file containing the definition */ - long df_line; /* line number of the definition */ + unsigned int df_line; /* line number of the definition */ char df_formal_array; /* to warn if sizeof is taken */ arith df_address; }; diff --git a/lang/cem/cemcom/error.c b/lang/cem/cemcom/error.c index bf3236a5e..68f4bd76c 100644 --- a/lang/cem/cemcom/error.c +++ b/lang/cem/cemcom/error.c @@ -26,18 +26,14 @@ */ /* error classes */ -#define ERROR 1 -#define WARNING 2 -#define LEXERROR 3 -#define LEXWARNING 4 -#define CRASH 5 -#define FATAL 6 +#define WARNING 1 +#define ERROR 2 +#define CRASH 3 +#define FATAL 4 int err_occurred = 0; -extern char *symbol2str(); extern char options[]; - /* There are three general error-message functions: lexerror() lexical and pre-processor error messages error() syntactic and semantic error messages @@ -49,6 +45,8 @@ extern char options[]; expression, whereas other errors use the information in the token. */ +static _error(); + /*VARARGS*/ error(va_alist) /* fmt, args */ va_dcl @@ -57,7 +55,7 @@ error(va_alist) /* fmt, args */ va_start(ap); { - _error(ERROR, NILEXPR, ap); + _error(ERROR, dot.tk_file, dot.tk_line, ap); } va_end(ap); } @@ -74,7 +72,7 @@ expr_error(va_alist) /* expr, fmt, args */ if (!(expr->ex_flags & EX_ERROR)) { /* to prevent proliferation */ - _error(ERROR, expr, ap); + _error(ERROR, expr->ex_file, expr->ex_line, ap); expr->ex_flags |= EX_ERROR; } } @@ -89,7 +87,7 @@ warning(va_alist) /* fmt, args */ va_start(ap); { - _error(WARNING, NILEXPR, ap); + _error(WARNING, dot.tk_file, dot.tk_line, ap); } va_end(ap); } @@ -106,7 +104,7 @@ expr_warning(va_alist) /* expr, fmt, args */ if (!(expr->ex_flags & EX_ERROR)) { /* to prevent proliferation */ - _error(WARNING, expr, ap); + _error(WARNING, expr->ex_file, expr->ex_line, ap); } } va_end(ap); @@ -120,7 +118,7 @@ lexerror(va_alist) /* fmt, args */ va_start(ap); { - _error(LEXERROR, NILEXPR, ap); + _error(ERROR, FileName, LineNumber, ap); } va_end(ap); } @@ -134,7 +132,7 @@ lexwarning(va_alist) /* fmt, args */ va_start(ap); { - _error(LEXWARNING, NILEXPR, ap); + _error(WARNING, FileName, LineNumber, ap); } va_end(ap); } @@ -148,7 +146,7 @@ crash(va_alist) /* fmt, args */ va_start(ap); { - _error(CRASH, NILEXPR, ap); + _error(CRASH, FileName, LineNumber, ap); } va_end(ap); @@ -169,17 +167,20 @@ fatal(va_alist) /* fmt, args */ va_start(ap); { - _error(FATAL, NILEXPR, ap); + _error(FATAL, FileName, LineNumber, ap); } va_end(ap); if (C_busy()) C_close(); sys_stop(S_EXIT); + /*NOTREACHED*/ } -_error(class, expr, ap) +static +_error(class, fn, ln, ap) int class; - struct expr *expr; + char *fn; + unsigned int ln; va_list ap; { /* _error attempts to limit the number of error messages @@ -188,9 +189,7 @@ _error(class, expr, ap) static char *last_fn = 0; static unsigned int last_ln = 0; static int e_seen = 0; - char *fn = 0; - unsigned int ln = 0; - char *remark = 0; + char *remark; char *fmt = va_arg(ap, char *); /* Since name and number are gathered from different places @@ -199,50 +198,39 @@ _error(class, expr, ap) */ /* preliminaries */ switch (class) { + case WARNING: + if (options['w']) + return; + break; + case ERROR: - case LEXERROR: case CRASH: case FATAL: if (C_busy()) C_ms_err(); err_occurred = 1; break; - - case WARNING: - case LEXWARNING: - if (options['w']) - return; - break; } /* the remark */ switch (class) { case WARNING: - case LEXWARNING: remark = "(warning)"; break; + + case ERROR: + remark = 0; + break; + case CRASH: remark = "CRASH\007"; break; + case FATAL: remark = "fatal error --"; break; - } - - /* the place */ - switch (class) { - case WARNING: - case ERROR: - fn = expr ? expr->ex_file : dot.tk_file; - ln = expr ? expr->ex_line : dot.tk_line; - break; - case LEXWARNING: - case LEXERROR: - case CRASH: - case FATAL: - fn = FileName; - ln = LineNumber; - break; + default: + /*NOTREACHED*/; } if (ln == last_ln && fn && last_fn && strcmp(fn, last_fn) == 0) { diff --git a/lang/cem/cemcom/eval.c b/lang/cem/cemcom/eval.c index f3312e926..f28278ac2 100644 --- a/lang/cem/cemcom/eval.c +++ b/lang/cem/cemcom/eval.c @@ -904,16 +904,17 @@ load_val(expr, rlval) } else { register struct idf *id = expr->VL_IDF; - register struct def *df; + register struct def *df = id->id_def; ASSERT(expr->VL_CLASS == Name); - if ((df = id->id_def)->df_type->tp_fund == FUNCTION) + if (df->df_type->tp_fund == FUNCTION) { /* the previous statement tried to catch a function identifier, which may be cast to a pointer to a function. ASSERT(!(rvalue)); ??? */ C_lpi(id->id_text); + } else if (df->df_level == L_GLOBAL) { if (rvalue) { diff --git a/lang/cem/cemcom/expr.c b/lang/cem/cemcom/expr.c index 788f26be5..5b8d8ef76 100644 --- a/lang/cem/cemcom/expr.c +++ b/lang/cem/cemcom/expr.c @@ -149,7 +149,7 @@ dot2expr(expp) #endif NOFLOAT default: crash("bad conversion to expression"); - break; + /*NOTREACHED*/ } } @@ -304,6 +304,7 @@ fill_int_expr(ex, ivalue, fund) break; default: crash("(intexpr) bad fund %s\n", symbol2str(fund)); + /*NOTREACHED*/ } ex->ex_class = Value; ex->VL_CLASS = Const; diff --git a/lang/cem/cemcom/idf.c b/lang/cem/cemcom/idf.c index b990c91d8..4a1a8018c 100644 --- a/lang/cem/cemcom/idf.c +++ b/lang/cem/cemcom/idf.c @@ -246,7 +246,7 @@ declare_idf(ds, dc, lvl) sc = GLOBAL; else if (sc == REGISTER) { - error("function has illegal storage class"); + error("function storage class cannot be register"); ds->ds_sc = sc = GLOBAL; } } @@ -444,7 +444,7 @@ global_redecl(idf, new_sc, tp) break; default: crash("bad storage class"); - break; + /*NOTREACHED*/ } break; case GLOBAL: @@ -469,7 +469,7 @@ global_redecl(idf, new_sc, tp) break; default: crash("bad storage class"); - break; + /*NOTREACHED*/ } break; case STATIC: @@ -492,7 +492,7 @@ global_redecl(idf, new_sc, tp) break; default: crash("bad storage class"); - break; + /*NOTREACHED*/ } break; case IMPLICIT: @@ -511,7 +511,7 @@ global_redecl(idf, new_sc, tp) break; default: crash("bad storage class"); - break; + /*NOTREACHED*/ } break; case ENUM: @@ -520,7 +520,7 @@ global_redecl(idf, new_sc, tp) break; default: crash("bad storage class"); - break; + /*NOTREACHED*/ } } diff --git a/lang/cem/cemcom/idf.str b/lang/cem/cemcom/idf.str index adf1e2f0b..3fe7c2444 100644 --- a/lang/cem/cemcom/idf.str +++ b/lang/cem/cemcom/idf.str @@ -34,8 +34,8 @@ struct idf { int id_resmac; /* if nonzero: keyword of macroproc. */ #endif NOPP int id_reserved; /* non-zero for reserved words */ - char *id_file; /* used for warnings */ - long id_line; + char *id_file; /* file containing the occurrence */ + unsigned int id_line; /* line number of the occurrence */ struct def *id_def; /* variables, typedefs, enum-constants */ struct sdef *id_sdef; /* selector tags */ struct tag *id_struct; /* struct and union tags */ diff --git a/lang/cem/cemcom/ival.g b/lang/cem/cemcom/ival.g index 34afa9672..88fd557a5 100644 --- a/lang/cem/cemcom/ival.g +++ b/lang/cem/cemcom/ival.g @@ -27,7 +27,6 @@ #include "noRoption.h" #include "estack.h" #include "code.h" - #define con_nullbyte() C_con_ucon("0", (arith)1) #define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT) @@ -530,6 +529,7 @@ check_ival(expp, tp) break; default: crash("check_ival"); + /*NOTREACHED*/ } } diff --git a/lang/cem/cemcom/main.c b/lang/cem/cemcom/main.c index ffc6efe40..71b520b8e 100644 --- a/lang/cem/cemcom/main.c +++ b/lang/cem/cemcom/main.c @@ -118,7 +118,8 @@ main(argc, argv) hash_stat(); #endif DEBUG - exit(err_occurred); + sys_stop(err_occurred ? S_EXIT : S_END); + /*NOTREACHED*/ } char *source = 0; @@ -130,7 +131,6 @@ compile(argc, argv) { char *result; register char *destination = 0; - #ifdef DEBUG #ifndef NOPP int pp_only = options['E'] || options['P'] || options['C']; @@ -146,6 +146,7 @@ compile(argc, argv) #endif fatal("%s: destination file not specified", prog_name); break; + case 2: destination = argv[1]; break; @@ -157,6 +158,7 @@ compile(argc, argv) fatal("use: %s source destination [namelist]", prog_name); break; } + if (strcmp(argv[0], "-")) FileName = source = argv[0]; else { @@ -164,8 +166,6 @@ compile(argc, argv) FileName = "standard input"; } - if (destination && strcmp(destination, "-") == 0) - destination = 0; if (!InsertFile(source, (char **) 0, &result)) /* read the source file */ fatal("%s: no source file %s\n", prog_name, FileName); File_Inserted = 1; @@ -185,9 +185,8 @@ compile(argc, argv) #endif NOPP #endif DEBUG { - - init_code(destination); - + init_code(destination && strcmp(destination, "-") != 0 ? + destination : 0); /* compile the source text */ C_program(); diff --git a/lang/cem/cemcom/options.c b/lang/cem/cemcom/options.c index 3d664fe1f..ec61dc11d 100644 --- a/lang/cem/cemcom/options.c +++ b/lang/cem/cemcom/options.c @@ -31,21 +31,26 @@ extern int inc_total; char options[128]; /* one for every char */ extern int idfsize; -int txt2int(); +static int txt2int(); do_option(text) char *text; { register char opt; +next_option: /* to allow combined one-char options */ switch (opt = *text++) { + case 0: /* to end the goto next_option loop */ + break; + default: fatal("illegal option: %c", opt); break; + case '-': - options[*text] = 1; /* flags, debug options etc. */ - break; + options[*text++] = 1; /* flags, debug options etc. */ + goto next_option; #ifdef DATAFLOW case 'd': @@ -58,12 +63,11 @@ do_option(text) case 'R': /* strict version */ #endif options[opt] = 1; - break; - + goto next_option; #ifdef NOROPTION case 'R': warning("-R option not implemented"); - break; + goto next_option; #endif #ifdef ___XXX___ @@ -293,7 +297,7 @@ deleted, is now a debug-flag } } -int +static int txt2int(tp) register char **tp; { diff --git a/lang/cem/cemcom/program.g b/lang/cem/cemcom/program.g index aebe839ae..ebeeada63 100644 --- a/lang/cem/cemcom/program.g +++ b/lang/cem/cemcom/program.g @@ -56,7 +56,6 @@ #include "code.h" #include "expr.h" #include "def.h" - #ifndef NOPP extern arith ifval; #endif NOPP diff --git a/lang/cem/cemcom/replace.c b/lang/cem/cemcom/replace.c index 82af873b9..e1ed2fa84 100644 --- a/lang/cem/cemcom/replace.c +++ b/lang/cem/cemcom/replace.c @@ -137,6 +137,7 @@ macro_func(idef) break; default : crash("(macro_func)"); + /*NOTREACHED*/ } } diff --git a/lang/cem/cemcom/scan.c b/lang/cem/cemcom/scan.c index 3f1be6d91..60aa3cc71 100644 --- a/lang/cem/cemcom/scan.c +++ b/lang/cem/cemcom/scan.c @@ -181,7 +181,7 @@ copyact(ch1, ch2, lvl) copy(EOS); if (++nr_of_params >= NPARAMS) { - fatal("(getact) too many actuals"); + fatal("too many actual parameters"); } actparams[nr_of_params] = aptr; diff --git a/lang/cem/cemcom/stack.c b/lang/cem/cemcom/stack.c index f1e1c0e8b..aee78b94b 100644 --- a/lang/cem/cemcom/stack.c +++ b/lang/cem/cemcom/stack.c @@ -95,6 +95,7 @@ unstack_level() if (options['t']) dumpidftab("before unstackidfs", 0); #endif DEBUG + /* The implementation below is more careful than strictly necessary. Optimists may optimize it afterwards. */ diff --git a/lang/cem/cemcom/statement.g b/lang/cem/cemcom/statement.g index 27be51309..05e4eb204 100644 --- a/lang/cem/cemcom/statement.g +++ b/lang/cem/cemcom/statement.g @@ -20,7 +20,6 @@ #include "code.h" #include "stack.h" #include "def.h" - extern int level; } @@ -76,6 +75,7 @@ statement asm_statement ; + expression_statement { struct expr *expr; } @@ -84,7 +84,7 @@ expression_statement ';' { #ifdef DEBUG - print_expr("Full expression", expr); + print_expr("expression_statement", expr); #endif DEBUG code_expr(expr, RVAL, FALSE, NO_LABEL, NO_LABEL); free_expression(expr); @@ -267,8 +267,8 @@ for_statement ';' expression(&e_incr)? ')' - { - } + { + } statement { C_df_ilb(l_continue); diff --git a/lang/cem/cemcom/struct.c b/lang/cem/cemcom/struct.c index 8e2c34de8..7d834e8fe 100644 --- a/lang/cem/cemcom/struct.c +++ b/lang/cem/cemcom/struct.c @@ -404,7 +404,7 @@ add_field(szp, fd, fdtpp, idf, stp) default: /* wrong type altogether */ - error("illegal field type (%s)", + error("field type cannot be %s", symbol2str((*fdtpp)->tp_fund)); *fdtpp = error_type; return field_offset; diff --git a/lang/cem/cemcom/switch.c b/lang/cem/cemcom/switch.c index 3f4f63ad8..311f8356e 100644 --- a/lang/cem/cemcom/switch.c +++ b/lang/cem/cemcom/switch.c @@ -213,11 +213,14 @@ code_default() { register struct switch_hdr *sh = switch_stack; - if (sh == 0) - error("default not in switch"); - else - if (sh->sh_default != 0) + if (sh == 0) { + error("default statement not in switch"); + return; + } + if (sh->sh_default != 0) { error("multiple entry for default in switch"); - else - C_df_ilb(sh->sh_default = text_label()); + return; + } + + C_df_ilb(sh->sh_default = text_label()); } -- 2.34.1