/* * Free all memory used for the current expression and the memory used * be a previous expression and saved by tsave(). The next call to * tfreeblk() frees the restored memory. */ void trestor(mbl_t *tmem) { tfreeblk(); if (tmblk != NULL) { free(tmblk->blk); free(tmblk); } tmblk = tmem; }
/* * for_exprs stmnt * for_exprs error */ void for2(void) { pos_t cpos, cspos; tnode_t *tn3; if (cstk->c_cont) reached = 1; STRUCT_ASSIGN(cpos, curr_pos); STRUCT_ASSIGN(cspos, csrc_pos); /* Restore the tree memory for the reinitialisation expression */ trestor(cstk->c_fexprm); tn3 = cstk->c_f3expr; STRUCT_ASSIGN(curr_pos, cstk->c_fpos); STRUCT_ASSIGN(csrc_pos, cstk->c_cfpos); /* simply "statement not reached" would be confusing */ if (!reached && !rchflg) { /* end-of-loop code not reached */ warning(223); reached = 1; } if (tn3 != NULL) { expr(tn3, 0, 0); } else { tfreeblk(); } STRUCT_ASSIGN(curr_pos, cpos); STRUCT_ASSIGN(csrc_pos, cspos); /* An endless loop without break will never terminate */ reached = cstk->c_break || !cstk->c_infinite; rchflg = 0; popctrl(T_FOR); }
/* * T_RETURN T_SEMI * T_RETURN expr T_SEMI */ void doreturn(tnode_t *tn) { tnode_t *ln, *rn; cstk_t *ci; op_t op; for (ci = cstk; ci->c_nxt != NULL; ci = ci->c_nxt) continue; if (tn != NULL) { ci->c_retval = 1; } else { ci->c_noretval = 1; } if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { /* void function %s cannot return value */ error(213, funcsym->s_name); tfreeblk(); tn = NULL; } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) { /* * Assume that the function has a return value only if it * is explicitly declared. */ if (!funcsym->s_rimpl) /* function %s expects to return value */ warning(214, funcsym->s_name); } if (tn != NULL) { /* Create a temporary node for the left side */ ln = tgetblk(sizeof (tnode_t)); ln->tn_op = NAME; ln->tn_type = tduptyp(funcsym->s_type->t_subt); ln->tn_type->t_const = 0; ln->tn_lvalue = 1; ln->tn_sym = funcsym; /* better than nothing */ tn = build(RETURN, ln, tn); if (tn != NULL) { rn = tn->tn_right; while ((op = rn->tn_op) == CVT || op == PLUS) rn = rn->tn_left; if (rn->tn_op == AMPER && rn->tn_left->tn_op == NAME && rn->tn_left->tn_sym->s_scl == AUTO) { /* %s returns pointer to automatic object */ warning(302, funcsym->s_name); } } expr(tn, 1, 0); } else { chkreach(); } reached = rchflg = 0; }
/* * Process a label. * * typ type of the label (T_NAME, T_DEFAULT or T_CASE). * sym symbol table entry of label if typ == T_NAME * tn expression if typ == T_CASE */ void label(int typ, sym_t *sym, tnode_t *tn) { cstk_t *ci; clst_t *cl; val_t *v; val_t nv; tspec_t t; switch (typ) { case T_NAME: if (sym->s_set) { /* label %s redefined */ error(194, sym->s_name); } else { setsflg(sym); } break; case T_CASE: /* find the stack entry for the innermost switch statement */ for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) continue; if (ci == NULL) { /* case not in switch */ error(195); tn = NULL; } else if (tn != NULL && tn->tn_op != CON) { /* non-constant case expression */ error(197); tn = NULL; } else if (tn != NULL && !isityp(tn->tn_type->t_tspec)) { /* non-integral case expression */ error(198); tn = NULL; } if (tn != NULL) { if (ci->c_swtype == NULL) lerror("label() 1"); if (reached && !ftflg) { if (hflag) /* fallthrough on case statement */ warning(220); } t = tn->tn_type->t_tspec; if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) { if (tflag) /* case label must be of type ... */ warning(203); } /* * get the value of the expression and convert it * to the type of the switch expression */ v = constant(tn); (void) memset(&nv, 0, sizeof nv); cvtcon(CASE, 0, ci->c_swtype, &nv, v); free(v); /* look if we had this value already */ for (cl = ci->c_clst; cl != NULL; cl = cl->cl_nxt) { if (cl->cl_val.v_quad == nv.v_quad) break; } if (cl != NULL && isutyp(nv.v_tspec)) { /* duplicate case in switch, %lu */ error(200, (u_long)nv.v_quad); } else if (cl != NULL) { /* duplicate case in switch, %ld */ error(199, (long)nv.v_quad); } else { /* * append the value to the list of * case values */ cl = xcalloc(1, sizeof (clst_t)); STRUCT_ASSIGN(cl->cl_val, nv); cl->cl_nxt = ci->c_clst; ci->c_clst = cl; } } tfreeblk(); break; case T_DEFAULT: /* find the stack entry for the innermost switch statement */ for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) continue; if (ci == NULL) { /* default outside switch */ error(201); } else if (ci->c_default) { /* duplicate default in switch */ error(202); } else { if (reached && !ftflg) { if (hflag) /* fallthrough on default statement */ warning(284); } ci->c_default = 1; } break; }; reached = 1; }
void mkinit(tnode_t *tn) { ptrdiff_t offs; sym_t *sym; tspec_t lt, rt; tnode_t *ln; struct mbl *tmem; scl_t sc; if (initerr || tn == NULL) goto end; sc = initsym->s_scl; /* * Do not test for automatic aggregat initialisation. If the * initializer starts with a brace we have the warning already. * If not, an error will be printed that the initializer must * be enclosed by braces. */ /* * Local initialisation of non-array-types with only one expression * without braces is done by ASSIGN */ if ((sc == AUTO || sc == REG) && initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) { ln = getnnode(initsym, 0); ln->tn_type = tduptyp(ln->tn_type); ln->tn_type->t_const = 0; tn = build(ASSIGN, ln, tn); expr(tn, 0, 0); goto end; } /* * Remove all entries which cannot be used for further initializers * and do not require a closing brace. */ popinit(0); /* Initialisations by strings are done in strginit(). */ if (strginit(tn)) goto end; nextinit(0); if (initerr || tn == NULL) goto end; initstk->i_cnt--; /* Create a temporary node for the left side. */ ln = tgetblk(sizeof (tnode_t)); ln->tn_op = NAME; ln->tn_type = tduptyp(initstk->i_type); ln->tn_type->t_const = 0; ln->tn_lvalue = 1; ln->tn_sym = initsym; /* better than nothing */ tn = cconv(tn); lt = ln->tn_type->t_tspec; rt = tn->tn_type->t_tspec; if (!issclt(lt)) lerror("mkinit() 1"); if (!typeok(INIT, 0, ln, tn)) goto end; /* * Store the tree memory. This is nessesary because otherwise * expr() would free it. */ tmem = tsave(); expr(tn, 1, 0); trestor(tmem); if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) { /* * Bit-fields can be initialized in trad. C only by integer * constants. */ if (tflag) /* bit-field initialisation is illegal in trad. C */ warning(186); } if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON)) tn = convert(INIT, 0, initstk->i_type, tn); if (tn != NULL && tn->tn_op != CON) { sym = NULL; offs = 0; if (conaddr(tn, &sym, &offs) == -1) { if (sc == AUTO || sc == REG) { /* non-constant initializer */ (void)gnuism(177); } else { /* non-constant initializer */ error(177); } } } end: tfreeblk(); }