static void nextinit(int brace) { if (!brace) { if (initstk->i_type == NULL && !issclt(initstk->i_subt->t_tspec)) { /* {}-enclosed initializer required */ error(181); } /* * Make sure an entry with a scalar type is at the top * of the stack. */ if (!initerr) testinit(); while (!initerr && (initstk->i_type == NULL || !issclt(initstk->i_type->t_tspec))) { if (!initerr) pushinit(); } } else { if (initstk->i_type != NULL && issclt(initstk->i_type->t_tspec)) { /* invalid initializer */ error(176); initerr = 1; } if (!initerr) testinit(); if (!initerr) pushinit(); if (!initerr) initstk->i_brace = 1; } }
/* * T_WHILE T_LPARN expr T_RPARN */ void while1(tnode_t *tn) { if (!reached) { /* loop not entered at top */ warning(207); reached = 1; } if (tn != NULL) tn = cconv(tn); if (tn != NULL) tn = promote(NOOP, 0, tn); if (tn != NULL && !issclt(tn->tn_type->t_tspec)) { /* controlling expressions must have scalar type */ error(204); tn = NULL; } pushctrl(T_WHILE); cstk->c_loop = 1; if (tn != NULL && tn->tn_op == CON) { if (isityp(tn->tn_type->t_tspec)) { cstk->c_infinite = tn->tn_val->v_quad != 0; } else { cstk->c_infinite = tn->tn_val->v_ldbl != 0.0; } } expr(tn, 0, 1); }
/* * T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN */ void for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) { /* * If there is no initialisation expression it is possible that * it is intended not to enter the loop at top. */ if (tn1 != NULL && !reached) { /* loop not entered at top */ warning(207); reached = 1; } pushctrl(T_FOR); cstk->c_loop = 1; /* * Store the tree memory for the reinitialisation expression. * Also remember this expression itself. We must check it at * the end of the loop to get "used but not set" warnings correct. */ cstk->c_fexprm = tsave(); cstk->c_f3expr = tn3; STRUCT_ASSIGN(cstk->c_fpos, curr_pos); STRUCT_ASSIGN(cstk->c_cfpos, csrc_pos); if (tn1 != NULL) expr(tn1, 0, 0); if (tn2 != NULL) tn2 = cconv(tn2); if (tn2 != NULL) tn2 = promote(NOOP, 0, tn2); if (tn2 != NULL && !issclt(tn2->tn_type->t_tspec)) { /* controlling expressions must have scalar type */ error(204); tn2 = NULL; } if (tn2 != NULL) expr(tn2, 0, 1); if (tn2 == NULL) { cstk->c_infinite = 1; } else if (tn2->tn_op == CON) { if (isityp(tn2->tn_type->t_tspec)) { cstk->c_infinite = tn2->tn_val->v_quad != 0; } else { cstk->c_infinite = tn2->tn_val->v_ldbl != 0.0; } } /* Checking the reinitialisation expression is done in for2() */ reached = 1; }
/* * do stmnt do_while_expr * do error */ void do2(tnode_t *tn) { /* * If there was a continue statement the expression controlling the * loop is reached. */ if (cstk->c_cont) reached = 1; if (tn != NULL) tn = cconv(tn); if (tn != NULL) tn = promote(NOOP, 0, tn); if (tn != NULL && !issclt(tn->tn_type->t_tspec)) { /* controlling expressions must have scalar type */ error(204); tn = NULL; } if (tn != NULL && tn->tn_op == CON) { if (isityp(tn->tn_type->t_tspec)) { cstk->c_infinite = tn->tn_val->v_quad != 0; } else { cstk->c_infinite = tn->tn_val->v_ldbl != 0.0; } if (!cstk->c_infinite && cstk->c_cont) error(323); } expr(tn, 0, 1, 1); /* * The end of the loop is only reached if it is no endless loop * or there was a break statement which could be reached. */ reached = !cstk->c_infinite || cstk->c_break; rchflg = 0; popctrl(T_DO); }
void initlbr(void) { if (initerr) return; if ((initsym->s_scl == AUTO || initsym->s_scl == REG) && initstk->i_nxt == NULL) { if (tflag && !issclt(initstk->i_subt->t_tspec)) /* no automatic aggregate initialization in trad. C*/ warning(188); } /* * Remove all entries which cannot be used for further initializers * and do not expect a closing brace. */ popinit(0); nextinit(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(); }
static void pushinit(void) { istk_t *istk; int cnt; sym_t *m; istk = initstk; /* Extend an incomplete array type by one element */ if (istk->i_cnt == 0) { /* * Inside of other aggregate types must not be an incomplete * type. */ if (istk->i_nxt->i_nxt != NULL) lerror("pushinit() 1"); istk->i_cnt = 1; if (istk->i_type->t_tspec != ARRAY) lerror("pushinit() 2"); istk->i_type->t_dim++; /* from now its a complete type */ setcompl(istk->i_type, 0); } if (istk->i_cnt <= 0) lerror("pushinit() 3"); if (istk->i_type != NULL && issclt(istk->i_type->t_tspec)) lerror("pushinit() 4"); initstk = xcalloc(1, sizeof (istk_t)); initstk->i_nxt = istk; initstk->i_type = istk->i_subt; if (initstk->i_type->t_tspec == FUNC) lerror("pushinit() 5"); istk = initstk; switch (istk->i_type->t_tspec) { case ARRAY: if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) { /* initialisation of an incomplete type */ error(175); initerr = 1; return; } istk->i_subt = istk->i_type->t_subt; istk->i_nolimit = incompl(istk->i_type); istk->i_cnt = istk->i_type->t_dim; break; case UNION: if (tflag) /* initialisation of union is illegal in trad. C */ warning(238); /* FALLTHROUGH */ case STRUCT: if (incompl(istk->i_type)) { /* initialisation of an incomplete type */ error(175); initerr = 1; return; } cnt = 0; for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) { if (m->s_field && m->s_name == unnamed) continue; if (++cnt == 1) { istk->i_mem = m; istk->i_subt = m->s_type; } } if (cnt == 0) { /* cannot init. struct/union with no named member */ error(179); initerr = 1; return; } istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1; break; default: istk->i_cnt = 1; break; } }