) /* ch 7.7 */
ch7cast(expp, CAST, tp);
else {
- if ((*expp)->ex_type != error_type)
- expr_error(*expp, "%s on %s and pointer",
+ expr_error(*expp, "%s on %s and pointer",
symbol2str(oper),
symbol2str((*expp)->ex_type->tp_fund)
);
- (*expp)->ex_type = error_type;
ch7cast(expp, oper, tp);
}
}
/* the (erroneous) expression *expp is replaced by an
int expression
*/
+ int flags = (*expp)->ex_flags;
+
free_expression(*expp);
*expp = intexpr((arith)0, INT);
+ (*expp)->ex_flags = (flags | EX_ERROR);
}
struct expr *
register int fund = (*expp)->ex_type->tp_fund;
if (fund != INT && fund != LONG) {
- if (fund != ERRONEOUS)
- expr_error(*expp, "%s operand to %s",
+ expr_error(*expp, "%s operand to %s",
symbol2str(fund), symbol2str(oper));
erroneous2int(expp);
/* fund = INT; */
/* filter out illegal expressions "non_lvalue.sel" */
if (!(*expp)->ex_lvalue) {
expr_error(*expp, "dot requires lvalue");
- (*expp)->ex_type = error_type;
return;
}
}
*/
(*expp)->VL_VALUE += sd->sd_offset;
(*expp)->ex_type = sd->sd_type;
+ if ((*expp)->ex_type == error_type)
+ (*expp)->ex_flags |= EX_ERROR;
}
else
if ((*expp)->ex_class == Oper) {
if (op->op_oper == '.' || op->op_oper == ARROW) {
op->op_right->VL_VALUE += sd->sd_offset;
(*expp)->ex_type = sd->sd_type;
+ if ((*expp)->ex_type == error_type)
+ (*expp)->ex_flags |= EX_ERROR;
}
else
*expp = new_oper(sd->sd_type, *expp, '.',
intexpr(sd->sd_offset, INT));
}
}
- else /* oper == ARROW */
+ else {
+ /* oper == ARROW */
*expp = new_oper(sd->sd_type,
*expp, oper, intexpr(sd->sd_offset, INT));
- (*expp)->ex_lvalue = sd->sd_type->tp_fund != ARRAY;
+ }
+ (*expp)->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
}
ch7incr(expp, oper)
addend = (arith)1;
#endif NOBITFIELD
else {
- if ((*expp)->ex_type != error_type)
- expr_error(*expp, "%s on %s",
+ expr_error(*expp, "%s on %s",
symbol2str(oper),
symbol2str((*expp)->ex_type->tp_fund)
);
(*expp)->ex_type = tp;
}
else
+ if (oldtp->tp_fund == ERRONEOUS) {
+ /* we just won't look */
+ (*expp)->ex_type = tp; /* brute force */
+ }
+ else
if (oldtp->tp_size == tp->tp_size && oper == CAST) {
expr_warning(*expp, "dubious conversion based on equal size");
(*expp)->ex_type = tp; /* brute force */
}
- else
- {
+ else {
if (oldtp->tp_fund != ERRONEOUS && tp->tp_fund != ERRONEOUS)
expr_error(*expp, "cannot convert %s to %s",
symbol2str(oldtp->tp_fund),
symbol2str(tp->tp_fund)
);
- (*expp)->ex_type = tp;
+ (*expp)->ex_type = tp; /* brute force */
}
}
ch7mon('*', expp);
}
if ((*expp)->ex_type->tp_fund != FUNCTION) {
- if ((*expp)->ex_type != error_type)
- expr_error(*expp, "call of non-function (%s)",
- symbol2str((*expp)->ex_type->tp_fund));
+ expr_error(*expp, "call of non-function (%s)",
+ symbol2str((*expp)->ex_type->tp_fund));
/* leave the expression; it may still serve */
free_expression(expr); /* there go the parameters */
}
) {
if ((*expp)->ex_type != expr->ex_type) {
expr_error(*expp, "illegal balance");
- (*expp)->ex_type = error_type;
}
}
else {
if ((*expp)->ex_type->tp_fund == ARRAY)
array2pointer(expp);
if ((*expp)->ex_type->tp_fund != POINTER) {
- if ((*expp)->ex_type != error_type)
- expr_error(*expp,
- "* applied to non-pointer (%s)",
- symbol2str((*expp)->ex_type->tp_fund));
- (*expp)->ex_type = error_type;
+ expr_error(*expp,
+ "* applied to non-pointer (%s)",
+ symbol2str((*expp)->ex_type->tp_fund));
}
else {
expr = *expp;
#ifndef NOBITFIELD
if ((*expp)->ex_type->tp_fund == FIELD) {
expr_error(*expp, "& applied to field variable");
- (*expp)->ex_type = error_type;
}
else
#endif NOBITFIELD
if (!(*expp)->ex_lvalue) {
expr_error(*expp, "& applied to non-lvalue");
- (*expp)->ex_type = error_type;
}
else {
/* assume that enums are already filtered out */
if (def->df_sc == REGISTER) {
expr_error(*expp,
"& on register variable not allowed");
- (*expp)->ex_type = error_type;
break; /* break case '&' */
}
def->df_register = REG_NONE;
printf("NILEXPR\n");
return;
}
- printf("expr: L=%u, T=%s, %cV, F=%02o, D=%d, %s: ",
+ printf("expr: L=%u, T=%s, %cV, F=%03o, D=%d, %s: ",
expr->ex_line,
type2str(expr->ex_type),
expr->ex_lvalue ? 'l' : 'r',
- expr->ex_flags,
+ expr->ex_flags & 0xFF,
expr->ex_depth,
expr->ex_class == Value ? "Value" :
expr->ex_class == String ? "String" :
struct expr *expr;
char *fmt;
{
+ if (expr->ex_flags & EX_ERROR)
+ return; /* to prevent proliferation */
_error(ERROR, expr, fmt, &args);
+ expr->ex_flags |= EX_ERROR;
}
/*VARARGS1*/
struct expr *expr;
char *fmt;
{
+ if (expr->ex_flags & EX_ERROR)
+ return; /* to prevent proliferation */
_error(WARNING, expr, fmt, &args);
}
}
/* now def != 0 */
if (def->df_type->tp_fund == LABEL) {
- error("illegal use of label %s", idf->id_text);
- expr->ex_type = error_type;
+ expr_error(expr, "illegal use of label %s", idf->id_text);
}
else {
def->df_used = 1;
expr->ex_type = def->df_type;
+ if (expr->ex_type == error_type)
+ expr->ex_flags |= EX_ERROR;
}
expr->ex_lvalue =
( def->df_type->tp_fund == FUNCTION ||
if (err) {
erroneous2int(expp);
- (*expp)->ex_type = error_type;
}
}
/* some bits for the ex_flag field, to keep track of various
interesting properties of an expression.
*/
-#define EX_SIZEOF 001 /* contains sizeof operator */
-#define EX_CAST 002 /* contains cast */
-#define EX_LOGICAL 004 /* contains logical operator */
-#define EX_COMMA 010 /* contains expression comma */
-#define EX_PARENS 020 /* the top level is parenthesized */
+#define EX_SIZEOF 0001 /* contains sizeof operator */
+#define EX_CAST 0002 /* contains cast */
+#define EX_LOGICAL 0004 /* contains logical operator */
+#define EX_COMMA 0010 /* contains expression comma */
+#define EX_PARENS 0020 /* the top level is parenthesized */
+#define EX_ERROR 0200 /* the expression is wrong */
#define NILEXPR ((struct expr *)0)
illegal_init_cst(expr)
struct expr *expr;
{
- if (expr->ex_type->tp_fund != ERRONEOUS)
- expr_error(expr, "illegal initialisation constant");
+ expr_error(expr, "illegal initialisation constant");
}
too_many_initialisers(expr)
{
#ifndef NOPP
if (expr->ex_flags & EX_SIZEOF)
- error("sizeof not allowed in preprocessor");
+ expr_error(expr,
+ "sizeof not allowed in preprocessor");
ifval = expr->VL_VALUE;
free_expression(expr);
#endif NOPP
return;
}
+ if (expr->ex_flags & EX_ERROR) {
+ /* is probably 0 anyway */
+ return;
+ }
+
expr->ex_type = sh->sh_type;
cut_size(expr);