Esempio n. 1
0
/*
 * Get memory for a new tree node.
 */
tnode_t *
getnode(void)
{

	return (tgetblk(sizeof (tnode_t)));
}
Esempio n. 2
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;
}
Esempio n. 3
0
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();
}