From ad40a77afdec7c29a1358aa02856ed0219033506 Mon Sep 17 00:00:00 2001 From: ceriel Date: Mon, 1 Dec 1986 10:00:23 +0000 Subject: [PATCH] handle void properly, avoid 0-alignments, handle #if defined(..) --- lang/cem/cemcom/LLlex.c | 2 +- lang/cem/cemcom/arith.c | 4 +- lang/cem/cemcom/ch7.c | 2 +- lang/cem/cemcom/ch7bin.c | 76 ++++++++------------ lang/cem/cemcom/ch7mon.c | 2 +- lang/cem/cemcom/code.c | 9 ++- lang/cem/cemcom/cstoper.c | 28 ++++---- lang/cem/cemcom/declarator.c | 1 - lang/cem/cemcom/decspecs.c | 2 +- lang/cem/cemcom/eval.c | 136 +++++++++++++++++++---------------- lang/cem/cemcom/idf.c | 38 ++++++---- lang/cem/cemcom/init.c | 3 + lang/cem/cemcom/main.c | 4 +- lang/cem/cemcom/replace.c | 21 +++++- lang/cem/cemcom/stack.c | 1 + lang/cem/cemcom/type.c | 2 + 16 files changed, 185 insertions(+), 146 deletions(-) diff --git a/lang/cem/cemcom/LLlex.c b/lang/cem/cemcom/LLlex.c index a9a8db8fa..84d5b29d5 100644 --- a/lang/cem/cemcom/LLlex.c +++ b/lang/cem/cemcom/LLlex.c @@ -267,7 +267,7 @@ go_on: /* rescan, the following character has been read */ if (idef->id_macro && ReplaceMacros && replace(idef)) /* macro replacement should be performed */ goto again; - if (UnknownIdIsZero) { + if (UnknownIdIsZero && idef->id_reserved != SIZEOF) { ptok->tk_ival = (arith)0; ptok->tk_fund = INT; return ptok->tk_symb = INTEGER; diff --git a/lang/cem/cemcom/arith.c b/lang/cem/cemcom/arith.c index c11ad70c9..d628ad495 100644 --- a/lang/cem/cemcom/arith.c +++ b/lang/cem/cemcom/arith.c @@ -464,7 +464,7 @@ any2opnd(expp, oper) #ifndef NOBITFIELD field2arith(expp) - struct expr **expp; + register struct expr **expp; { /* The expression to extract the bitfield value from the memory word is put in the tree. @@ -500,7 +500,7 @@ field2arith(expp) take care of the first byte the fl_value pointer points to. */ switch_sign_fp(expr) - struct expr *expr; + register struct expr *expr; { if (*(expr->FL_VALUE) == '-') ++(expr->FL_VALUE); diff --git a/lang/cem/cemcom/ch7.c b/lang/cem/cemcom/ch7.c index 356497d2b..a4da640b6 100644 --- a/lang/cem/cemcom/ch7.c +++ b/lang/cem/cemcom/ch7.c @@ -128,7 +128,7 @@ ch7sel(expp, oper, idf) } ch7incr(expp, oper) - register struct expr **expp; + struct expr **expp; { /* The monadic prefix/postfix incr/decr operator oper is applied to *expp. diff --git a/lang/cem/cemcom/ch7bin.c b/lang/cem/cemcom/ch7bin.c index 484b1caf8..90211bb6c 100644 --- a/lang/cem/cemcom/ch7bin.c +++ b/lang/cem/cemcom/ch7bin.c @@ -20,6 +20,9 @@ extern char *symbol2str(); depending on the constancy of the operands. */ +#define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1) +#define non_commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 0) + ch7bin(expp, oper, expr) register struct expr **expp; struct expr *expr; @@ -82,24 +85,28 @@ ch7bin(expp, oper, expr) break; case '%': case MODAB: + case ANDAB: + case XORAB: + case ORAB: opnd2integral(expp, oper); opnd2integral(&expr, oper); - fund = arithbalance(expp, oper, &expr); - non_commutative_binop(expp, oper, expr); - break; + /* Fall through */ case '/': case DIVAB: + case TIMESAB: fund = arithbalance(expp, oper, &expr); non_commutative_binop(expp, oper, expr); break; + case '&': + case '^': + case '|': + opnd2integral(expp, oper); + opnd2integral(&expr, oper); + /* Fall through */ case '*': fund = arithbalance(expp, oper, &expr); commutative_binop(expp, oper, expr); break; - case TIMESAB: - fund = arithbalance(expp, oper, &expr); - non_commutative_binop(expp, oper, expr); - break; case '+': if (expr->ex_type->tp_fund == POINTER) { /* swap operands */ struct expr *etmp = expr; @@ -161,41 +168,27 @@ ch7bin(expp, oper, expr) non_commutative_binop(expp, oper, expr); (*expp)->ex_type = int_type; break; - case '&': - case '^': - case '|': - opnd2integral(expp, oper); - opnd2integral(&expr, oper); - fund = arithbalance(expp, oper, &expr); - commutative_binop(expp, oper, expr); - break; - case ANDAB: - case XORAB: - case ORAB: - opnd2integral(expp, oper); - opnd2integral(&expr, oper); - fund = arithbalance(expp, oper, &expr); - non_commutative_binop(expp, oper, expr); - break; case AND: case OR: opnd2test(expp, oper); opnd2test(&expr, oper); if (is_cp_cst(*expp)) { - struct expr *ex = *expp; + register struct expr *ex = *expp; /* the following condition is a short-hand for ((oper == AND) && o1) || ((oper == OR) && !o1) where o1 == (*expp)->VL_VALUE; and ((oper == AND) || (oper == OR)) */ - if ((oper == AND) == ((*expp)->VL_VALUE != (arith)0)) + if ((oper == AND) == (ex->VL_VALUE != (arith)0)) *expp = expr; else { + ex->ex_flags |= expr->ex_flags; free_expression(expr); *expp = intexpr((arith)((oper == AND) ? 0 : 1), INT); } + (*expp)->ex_flags |= ex->ex_flags; free_expression(ex); } else @@ -205,8 +198,10 @@ ch7bin(expp, oper, expr) where o2 == expr->VL_VALUE and ((oper == AND) || (oper == OR)) */ - if ((oper == AND) == (expr->VL_VALUE != (arith)0)) + if ((oper == AND) == (expr->VL_VALUE != (arith)0)) { + (*expp)->ex_flags |= expr->ex_flags; free_expression(expr); + } else { if (oper == OR) expr->VL_VALUE = (arith)1; @@ -270,31 +265,22 @@ pntminuspnt(expp, oper, expr) ch7cast(expp, CAST, int_type); /* result will be an integer expr */ } -non_commutative_binop(expp, oper, expr) +mk_binop(expp, oper, expr, commutative) register struct expr **expp, *expr; { /* Constructs in *expp the operation indicated by the operands. - "oper" is a non-commutative operator + "commutative" indicates wether "oper" is a commutative + operator. */ - if (is_cp_cst(expr) && is_cp_cst(*expp)) - cstbin(expp, oper, expr); - else - *expp = new_oper((*expp)->ex_type, *expp, oper, expr); -} + register struct expr *ex = *expp; -commutative_binop(expp, oper, expr) - register struct expr **expp, *expr; -{ - /* Constructs in *expp the operation indicated by the operands. - "oper" is a commutative operator - */ - if (is_cp_cst(expr) && is_cp_cst(*expp)) + if (is_cp_cst(expr) && is_cp_cst(ex)) cstbin(expp, oper, expr); - else - if ((*expp)->ex_depth > expr->ex_depth) - *expp = new_oper((*expp)->ex_type, *expp, oper, expr); - else - *expp = new_oper((*expp)->ex_type, expr, oper, *expp); + else { + *expp = (commutative && expr->ex_depth >= ex->ex_depth) ? + new_oper(ex->ex_type, expr, oper, ex) : + new_oper(ex->ex_type, ex, oper, expr); + } } pointer_arithmetic(expp1, oper, expp2) diff --git a/lang/cem/cemcom/ch7mon.c b/lang/cem/cemcom/ch7mon.c index 23c3f5c39..e42ef4fe9 100644 --- a/lang/cem/cemcom/ch7mon.c +++ b/lang/cem/cemcom/ch7mon.c @@ -151,9 +151,9 @@ ch7mon(oper, expp) warning("sizeof formal array %s is sizeof pointer!", (*expp)->VL_IDF->id_text); expr = intexpr(size_of_type((*expp)->ex_type, "object"), INT); + expr->ex_flags |= EX_SIZEOF; free_expression(*expp); *expp = expr; - (*expp)->ex_flags |= EX_SIZEOF; break; } } diff --git a/lang/cem/cemcom/code.c b/lang/cem/cemcom/code.c index 696c99b55..ca5013c6a 100644 --- a/lang/cem/cemcom/code.c +++ b/lang/cem/cemcom/code.c @@ -437,8 +437,13 @@ bss(idf) /* Since bss() is only called if df_alloc is non-zero, and since df_alloc is only non-zero if size >= 0, we have: */ + /* but we already gave a warning at the declaration of the + array. Besides, the message given here does not apply to + voids + if (options['R'] && size == 0) warning("actual array of size 0"); + */ C_df_dnam(idf->id_text); C_bss_cst(align(size, word_align), (arith)0, 1); } @@ -455,7 +460,9 @@ formal_cvt(df) (tp->tp_fund == CHAR || tp->tp_fund == SHORT) ) { C_lol(df->df_address); - /* conversion(int_type, df->df_type); ??? */ + /* conversion(int_type, df->df_type); ??? + No, you can't do this on the stack! (CJ) + */ C_lal(df->df_address); C_sti(tp->tp_size); df->df_register = REG_NONE; diff --git a/lang/cem/cemcom/cstoper.c b/lang/cem/cemcom/cstoper.c index 8c5154104..82f1e3f61 100644 --- a/lang/cem/cemcom/cstoper.c +++ b/lang/cem/cemcom/cstoper.c @@ -120,15 +120,13 @@ cstbin(expp, oper, expr) o1 >>= o2; break; case '<': - if (uns) { - o1 = (o1 & mach_long_sign ? - (o2 & mach_long_sign ? o1 < o2 : 0) : - (o2 & mach_long_sign ? 1 : o1 < o2) - ); + { + arith tmp = o1; + + o1 = o2; + o2 = tmp; } - else - o1 = o1 < o2; - break; + /* Fall through */ case '>': if (uns) { o1 = (o1 & mach_long_sign ? @@ -140,15 +138,13 @@ cstbin(expp, oper, expr) o1 = o1 > o2; break; case LESSEQ: - if (uns) { - o1 = (o1 & mach_long_sign ? - (o2 & mach_long_sign ? o1 <= o2 : 0) : - (o2 & mach_long_sign ? 1 : o1 <= o2) - ); + { + arith tmp = o1; + + o1 = o2; + o2 = tmp; } - else - o1 = o1 <= o2; - break; + /* Fall through */ case GREATEREQ: if (uns) { o1 = (o1 & mach_long_sign ? diff --git a/lang/cem/cemcom/declarator.c b/lang/cem/cemcom/declarator.c index 33bb4e8fa..f1a1eb2e3 100644 --- a/lang/cem/cemcom/declarator.c +++ b/lang/cem/cemcom/declarator.c @@ -101,7 +101,6 @@ check_array_subscript(expr) else if (size == 0) { warning("empty array declaration"); - expr->VL_VALUE = (arith)-1; } else if (size & ~max_unsigned) { /* absolutely ridiculous */ diff --git a/lang/cem/cemcom/decspecs.c b/lang/cem/cemcom/decspecs.c index ead1cbe6e..235fb1ae5 100644 --- a/lang/cem/cemcom/decspecs.c +++ b/lang/cem/cemcom/decspecs.c @@ -39,8 +39,8 @@ do_decspecs(ds) ds->ds_sc != REGISTER){ extern char *symbol2str(); error("%s formal illegal", symbol2str(ds->ds_sc)); + ds->ds_sc = FORMAL; } - ds->ds_sc = FORMAL; } /* The tests concerning types require a full knowledge of the type and will have to be postponed to declare_idf. diff --git a/lang/cem/cemcom/eval.c b/lang/cem/cemcom/eval.c index 6c1d260f7..12f924373 100644 --- a/lang/cem/cemcom/eval.c +++ b/lang/cem/cemcom/eval.c @@ -96,14 +96,16 @@ EVAL(expr, val, code, true_label, false_label) if (tp->tp_fund == ERRONEOUS) /* stop immediately */ break; + if (tp->tp_fund == VOID) + gencode = 0; switch (oper) { case '+': /* We have the following possibilities : int + int, pointer + int, pointer + long, long + long, double + double */ - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) { switch (tp->tp_fund) { case INT: @@ -128,7 +130,7 @@ EVAL(expr, val, code, true_label, false_label) break; case '-': if (left == 0) { /* unary */ - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) { switch (tp->tp_fund) { case INT: @@ -151,8 +153,8 @@ EVAL(expr, val, code, true_label, false_label) int - int, pointer - int, pointer - long, pointer - pointer, long - long, double - double */ - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (!gencode) break; switch (tp->tp_fund) { @@ -182,10 +184,10 @@ EVAL(expr, val, code, true_label, false_label) break; case '*': if (left == 0) /* unary */ - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); else { /* binary */ - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) switch (tp->tp_fund) { case INT: @@ -207,8 +209,8 @@ EVAL(expr, val, code, true_label, false_label) } break; case '/': - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) switch (tp->tp_fund) { case INT: @@ -229,8 +231,8 @@ EVAL(expr, val, code, true_label, false_label) } break; case '%': - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); ASSERT(tp->tp_fund==INT || tp->tp_fund==LONG); if (gencode) if (tp->tp_unsigned) @@ -239,8 +241,8 @@ EVAL(expr, val, code, true_label, false_label) C_rmi(tp->tp_size); break; case LEFT: - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) if (tp->tp_unsigned) C_slu(tp->tp_size); @@ -248,8 +250,8 @@ EVAL(expr, val, code, true_label, false_label) C_sli(tp->tp_size); break; case RIGHT: - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) if (tp->tp_unsigned) C_sru(tp->tp_size); @@ -262,8 +264,8 @@ EVAL(expr, val, code, true_label, false_label) case GREATEREQ: case EQUAL: case NOTEQUAL: - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) { /* The operands have the same type */ arith size = left->ex_type->tp_size; @@ -312,8 +314,8 @@ EVAL(expr, val, code, true_label, false_label) case '|': case '^': /* both operands should have type int */ - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) { arith size = tp->tp_size; @@ -332,23 +334,26 @@ EVAL(expr, val, code, true_label, false_label) } } break; - case '=': + case '=': { + int newcode = tp->tp_size > 0; /* CJ */ #ifndef NOBITFIELD if (left->ex_type->tp_fund == FIELD) { - eval_field(expr, code); + eval_field(expr, gencode); break; } #endif NOBITFIELD - EVAL(right, RVAL, TRUE, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, newcode, NO_LABEL, NO_LABEL); if (gencode) C_dup(ATW(tp->tp_size)); if (left->ex_class != Value) { - EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL); - store_block(tp->tp_size, tp->tp_align); + EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL); + if (newcode) + store_block(tp->tp_size, tp->tp_align); } - else + else if (newcode) store_val(&(left->ex_object.ex_value), left->ex_type); + } break; case PLUSAB: case MINAB: @@ -367,13 +372,14 @@ EVAL(expr, val, code, true_label, false_label) { arith old_offset, tmp; int compl; /* Complexity of left operand */ + int newcode = left->ex_type->tp_size > 0; /* CJ */ #ifndef NOBITFIELD if (left->ex_type->tp_fund == FIELD) { - eval_field(expr, code); + eval_field(expr, gencode); break; } #endif NOBITFIELD - if (left->ex_class == Value) { + if (newcode && left->ex_class == Value) { compl = 0; /* Value */ load_val(left, RVAL); } @@ -381,34 +387,42 @@ EVAL(expr, val, code, true_label, false_label) if (left->ex_depth == 1 && left->OP_OPER == ARROW) { compl = 1; /* Value->sel */ ASSERT(left->OP_LEFT->ex_class == Value); - EVAL(left, RVAL, TRUE, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, newcode, NO_LABEL, NO_LABEL); } else { compl = 2; /* otherwise */ - tmp = tmp_pointer_var(&old_offset); - EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL); - C_dup(pointer_size); - C_lal(tmp); - C_sti(pointer_size); - C_loi(left->ex_type->tp_size); - } - conversion(left->ex_type, tp); - if (gencode && (oper == POSTINCR || oper == POSTDECR)) - C_dup(tp->tp_size); - EVAL(right, RVAL, TRUE, NO_LABEL, NO_LABEL); - assop(tp, oper); - if (gencode && oper != POSTINCR && oper != POSTDECR) - C_dup(tp->tp_size); - conversion(tp, left->ex_type); - if (compl == 0) + EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL); + if (newcode) { + tmp = tmp_pointer_var(&old_offset); + C_dup(pointer_size); + C_lal(tmp); + C_sti(pointer_size); + C_loi(left->ex_type->tp_size); + } + } + if (newcode) { + conversion(left->ex_type, tp); + if (gencode && (oper == POSTINCR || + oper == POSTDECR)) + C_dup(tp->tp_size); + } + EVAL(right, RVAL, newcode, NO_LABEL, NO_LABEL); + if (newcode) { + assop(tp, oper); + if (gencode && oper != POSTINCR && + oper != POSTDECR) + C_dup(tp->tp_size); + conversion(tp, left->ex_type); + } + if (newcode && compl == 0) store_val(&(left->ex_object.ex_value), left->ex_type); else if (compl == 1) { - EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL); - C_sti(left->ex_type->tp_size); + EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL); + if (newcode) C_sti(left->ex_type->tp_size); } - else { + else if (newcode) { C_lal(tmp); /* always init'd */ C_loi(pointer_size); C_sti(left->ex_type->tp_size); @@ -426,12 +440,14 @@ EVAL(expr, val, code, true_label, false_label) while ( ex->ex_class == Oper && ex->OP_OPER == PARCOMMA ) { - EVAL(ex->OP_RIGHT, RVAL, TRUE, + EVAL(ex->OP_RIGHT, RVAL, + ex->ex_type->tp_size > 0, NO_LABEL, NO_LABEL); ParSize += ATW(ex->ex_type->tp_size); ex = ex->OP_LEFT; } - EVAL(ex, RVAL, TRUE, NO_LABEL, NO_LABEL); + EVAL(ex, RVAL, ex->ex_type->tp_size > 0, + NO_LABEL, NO_LABEL); ParSize += ATW(ex->ex_type->tp_size); } if (left->ex_class == Value && left->VL_CLASS == Name) { @@ -463,23 +479,23 @@ EVAL(expr, val, code, true_label, false_label) break; } case '.': - EVAL(left, LVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, LVAL, gencode, NO_LABEL, NO_LABEL); ASSERT(is_cp_cst(right)); if (gencode) C_adp(right->VL_VALUE); break; case ARROW: - EVAL(left, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL); ASSERT(is_cp_cst(right)); if (gencode) C_adp(right->VL_VALUE); break; case ',': EVAL(left, RVAL, FALSE, NO_LABEL, NO_LABEL); - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); break; case '~': - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) C_com(tp->tp_size); break; @@ -491,10 +507,10 @@ EVAL(expr, val, code, true_label, false_label) EVAL(left, RVAL, TRUE, l_true, l_false); C_df_ilb(l_true); - EVAL(right->OP_LEFT, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(right->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL); C_bra(l_end); C_df_ilb(l_false); - EVAL(right->OP_RIGHT, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(right->OP_RIGHT, RVAL, gencode, NO_LABEL, NO_LABEL); C_df_ilb(l_end); break; } @@ -528,7 +544,7 @@ EVAL(expr, val, code, true_label, false_label) EVAL(left, RVAL, TRUE, l_maybe, false_label); C_df_ilb(l_maybe); - EVAL(right, RVAL, code, true_label, + EVAL(right, RVAL, gencode, true_label, false_label); } break; @@ -562,7 +578,7 @@ EVAL(expr, val, code, true_label, false_label) EVAL(left, RVAL, TRUE, true_label, l_maybe); C_df_ilb(l_maybe); - EVAL(right, RVAL, code, true_label, + EVAL(right, RVAL, gencode, true_label, false_label); } break; @@ -587,7 +603,7 @@ EVAL(expr, val, code, true_label, false_label) NO_LABEL); } else - EVAL(right, RVAL, code, false_label, + EVAL(right, RVAL, gencode, false_label, true_label); break; case INT2INT: @@ -596,7 +612,7 @@ EVAL(expr, val, code, true_label, false_label) case FLOAT2INT: case FLOAT2FLOAT: #endif NOFLOAT - EVAL(right, RVAL, code, NO_LABEL, NO_LABEL); + EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); if (gencode) conversion(right->ex_type, left->ex_type); break; diff --git a/lang/cem/cemcom/idf.c b/lang/cem/cemcom/idf.c index 200a05ab7..23473af65 100644 --- a/lang/cem/cemcom/idf.c +++ b/lang/cem/cemcom/idf.c @@ -187,17 +187,23 @@ declare_idf(ds, dc, lvl) else { /* combine the decspecs and the declarator into one type */ type = declare_type(ds->ds_type, dc); - if (type->tp_size == (arith)-1) { - /* the type is not yet known */ - if (actual_declaration(sc, type)) { - /* but it has to be: */ + if (type->tp_size <= (arith)0 && + actual_declaration(sc, type)) { + if (type->tp_size == (arith) -1) { + /* the type is not yet known, + but it has to be: + */ extern char *symbol2str(); error("unknown %s-type", symbol2str(type->tp_fund)); } + else { + /* CJ */ + warning("%s has size 0", idf->id_text); + } } } - + /* some additional work for formal definitions */ if (lvl == L_FORMAL2) { switch (type->tp_fund) { @@ -276,9 +282,8 @@ declare_idf(ds, dc, lvl) def->df_type = type; def->df_formal_array = formal_array; def->df_sc = sc; - if (def->df_sc != FORMAL) - crash("non-formal formal"); - def->df_register = (sc == REGISTER) ? REG_BONUS : REG_DEFAULT; + def->df_level = L_FORMAL2; /* CJ */ + if (sc == REGISTER) def->df_register = REG_BONUS; } else if ( lvl >= L_LOCAL && @@ -303,6 +308,8 @@ declare_idf(ds, dc, lvl) newdef->df_level = lvl; newdef->df_type = type; newdef->df_sc = sc; + if (lvl == L_FORMAL1) /* CJ */ + newdef->df_register = REG_DEFAULT; /* link it into the name list in the proper place */ idf->id_def = newdef; update_ahead(idf); @@ -323,17 +330,17 @@ declare_idf(ds, dc, lvl) idf->id_text); /** type = idf->id_def->df_type = int_type; **/ } - idf->id_def->df_register = + newdef->df_register = (sc == REGISTER) ? REG_BONUS : REG_DEFAULT; - idf->id_def->df_address = + newdef->df_address = stl->sl_max_block = stl->sl_local_offset = -align(-stl->sl_local_offset + type->tp_size, type->tp_align); break; case STATIC: - idf->id_def->df_address = (arith) data_label(); + newdef->df_address = (arith) data_label(); break; } } @@ -504,7 +511,7 @@ global_redecl(idf, new_sc, tp) int good_formal(def, idf) register struct def *def; - struct idf *idf; + register struct idf *idf; { /* Succeeds if def is a proper L_FORMAL1 definition and gives an error message otherwise. @@ -514,6 +521,7 @@ good_formal(def, idf) error("%s not in parameter list", idf->id_text); return 0; } + ASSERT(def->df_sc == FORMAL); /* CJ */ return 1; } @@ -533,7 +541,7 @@ declare_params(dc) } init_idf(idf) - struct idf *idf; + register struct idf *idf; { /* The topmost definition of idf is set to initialized. */ @@ -593,6 +601,7 @@ declare_formals(fp) f_offset = align(f_offset + def->df_type->tp_size, word_align); formal_cvt(def); /* cvt int to char or short, if necessary */ se = se->next; + def->df_level = L_FORMAL2; /* CJ */ } *fp = f_offset; } @@ -637,7 +646,8 @@ free_formals(fm) register struct formal *fm; { while (fm) { - register struct formal *tmp = fm->next; + struct formal *tmp = fm->next; + free_formal(fm); fm = tmp; } diff --git a/lang/cem/cemcom/init.c b/lang/cem/cemcom/init.c index dcdf1bfc8..2c0b6a6cb 100644 --- a/lang/cem/cemcom/init.c +++ b/lang/cem/cemcom/init.c @@ -75,6 +75,9 @@ init_pp() /* __FILE__ */ macro_def(str2idf("__FILE__"), "", -1, 1, FUNC); + /* defined(??) */ + macro_def(str2idf("defined"), "", 1, 1, FUNC); + #ifdef PREDEFINE { /* PREDEFINE is a compile-time defined string diff --git a/lang/cem/cemcom/main.c b/lang/cem/cemcom/main.c index e6235214f..b9fa69171 100644 --- a/lang/cem/cemcom/main.c +++ b/lang/cem/cemcom/main.c @@ -170,7 +170,7 @@ compile(argc, argv) tmpfile = mktemp(tmpf); #endif USE_TMP - if (strcmp(destination, "-") == 0) + if (destination && strcmp(destination, "-") == 0) destination = 0; if (!InsertFile(source, (char **) 0)) /* read the source file */ fatal("%s: no source file %s\n", prog_name, @@ -246,7 +246,7 @@ init() float_type = standard_type(FLOAT, 0, float_align, float_size); double_type = standard_type(DOUBLE, 0, double_align, double_size); #endif NOFLOAT - void_type = standard_type(VOID, 0, 0, (arith)0); + void_type = standard_type(VOID, 0, 1, (arith)0); label_type = standard_type(LABEL, 0, 0, (arith)0); error_type = standard_type(ERRONEOUS, 0, 1, (arith)1); diff --git a/lang/cem/cemcom/replace.c b/lang/cem/cemcom/replace.c index b64e4fedf..21c98c060 100644 --- a/lang/cem/cemcom/replace.c +++ b/lang/cem/cemcom/replace.c @@ -41,6 +41,15 @@ replace(idef) int size; if (idef->id_macro->mc_nps != -1) { /* with parameter list */ + if (flags & FUNC) { + /* must be "defined". + Unfortunately, the next assertion + will not compile ... + ASSERT( ! strcmp("defined", idef->id_text)); + */ + if (! AccDefined) + return 0; + } LoadChar(c); c = skipspaces(c); if (c != '(') { /* no replacement if no () */ @@ -50,10 +59,20 @@ replace(idef) return 0; } actpars = getactuals(idef); /* get act.param. list */ + if (flags & FUNC) { + struct idf *param = str2idf(*actpars); + + if (param->id_macro) + reptext = "\0001"; + else + reptext = "\0000"; + InsertText(reptext, 2); + return 1; + } } if ((flags & PREDEF) && (UnknownIdIsZero == 0)) /* don't replace */ return 0; - if (flags & FUNC) /* this macro leads to special action */ + if (flags & FUNC) /* this macro leads to special action */ macro_func(idef); reptext = macro2buffer(idef, actpars, &size); /* create input buffer */ InsertText(reptext, size); diff --git a/lang/cem/cemcom/stack.c b/lang/cem/cemcom/stack.c index 24b95ea1c..7b0119d78 100644 --- a/lang/cem/cemcom/stack.c +++ b/lang/cem/cemcom/stack.c @@ -118,6 +118,7 @@ unstack_level() if (level == L_LOCAL || level == L_FORMAL1) { if ( def->df_register != REG_NONE && def->df_sc != STATIC && + def->df_type->tp_size > 0 && options['n'] == 0 ) { int reg; diff --git a/lang/cem/cemcom/type.c b/lang/cem/cemcom/type.c index 73f805d93..ec2c96bb9 100644 --- a/lang/cem/cemcom/type.c +++ b/lang/cem/cemcom/type.c @@ -88,6 +88,8 @@ construct_type(fund, tp, count) error("cannot construct array of unknown type"); count = (arith)-1; } + else if (tp->tp_size == 0) /* CJ */ + warning("array elements have size 0"); if (count >= (arith)0) count *= tp->tp_size; dtp = array_of(tp, count); -- 2.34.1