コード例 #1
0
ファイル: mem1.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * 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;
}
コード例 #2
0
/*
 * 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);
}
コード例 #3
0
/*
 * 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;
}
コード例 #4
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;
}
コード例 #5
0
ファイル: init.c プロジェクト: edgar-pek/PerspicuOS
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();
}