if (oper == '.' && exp->ex_flags & EX_READONLY) {
exp->ex_type = qualifier_type(exp->ex_type, TQ_CONST);
}
+ if (exp->ex_flags & EX_VOLATILE) {
+ exp->ex_type = qualifier_type(exp->ex_type, TQ_VOLATILE);
+ }
*expp = exp;
}
return !(pl || opl);
}
-/* check if a type has a const declared member */
-recurconst(tp)
+/* check if a type has a consqualified member */
+recurqual(tp, qual)
struct type *tp;
+int qual;
{
register struct sdef *sdf;
ASSERT(tp);
- if (tp->tp_typequal & TQ_CONST) return 1;
+ if (tp->tp_typequal & qual) return 1;
sdf = tp->tp_sdef;
while (sdf) {
- if (recurconst(sdf->sd_type))
+ if (recurqual(sdf->sd_type, qual))
return 1;
sdf = sdf->sd_sdef;
}
*/
register struct expr *exp = *expp;
int fund = exp->ex_type->tp_fund;
- int vol = 0;
struct type *tp;
char *oper_string = symbol2str(oper);
} else if (exp->ex_flags & EX_READONLY) {
expr_error(exp, "operand of %s is read-only", oper_string);
} else if (fund == STRUCT || fund == UNION) {
- if (recurconst(exp->ex_type))
+ if (recurqual(exp->ex_type, TQ_CONST))
expr_error(expr,"operand of %s contains a const-qualified member",
oper_string);
}
- /* Preserve volatile markers across the tree.
- This is questionable, depending on the way the optimizer
- wants this information.
- */
- vol = (exp->ex_flags & EX_VOLATILE) || (expr->ex_flags & EX_VOLATILE);
-
if (oper == '=') {
ch3cast(&expr, oper, exp->ex_type);
tp = expr->ex_type;
exp = new_oper(exp->ex_type, exp, oper, expr);
#endif NOBITFIELD
exp->OP_TYPE = tp; /* for EVAL() */
- exp->ex_flags |= vol ? (EX_SIDEEFFECTS|EX_VOLATILE) : EX_SIDEEFFECTS;
+ exp->ex_flags |= EX_SIDEEFFECTS;
*expp = exp;
}
if (! options['L']) /* profiling */
C_lin((arith)(expr->ex_line));
- /* HERE WE SHOULD GENERATE A MESSAGE:
- if (expr->ex_flags & EX_VOLATILE)
- HANDS_OFF
- */
EVAL(expr, val, code, tlbl, flbl);
#else LINT
lint_expr(expr, code ? USED : IGNORED);
int val, code;
label true_label, false_label;
{
- register int gencode = (code == TRUE
- && (expr->ex_type->tp_size > 0
- || expr->ex_type->tp_fund == FUNCTION));
+ int vol = (code != TRUE && recurqual(expr->ex_type, TQ_VOLATILE));
+ register int gencode = ((code == TRUE
+ && (expr->ex_type->tp_size > 0
+ || expr->ex_type->tp_fund == FUNCTION))
+ || vol);
switch (expr->ex_class) {
case Value: /* just a simple value */
default:
crash("(EVAL) bad expression class");
}
- if (expr->ex_flags & EX_VOLATILE) C_nop();
+ if (expr->ex_flags & EX_VOLATILE || vol) C_nop();
+ if (vol) C_asp(expr->ex_type->tp_size);
+
}
/* compare() serves as an auxiliary function of EVAL */