2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: ch7.c,v 3.26 1994/06/24 12:02:24 ceriel Exp $ */
6 /* S E M A N T I C A N A L Y S I S -- C H A P T E R 7 RM */
11 #include "nobitfield.h"
22 extern char options[];
23 extern char *symbol2str();
25 /* Most expression-handling routines have a pointer to a
26 (struct type *) as first parameter. The object under the pointer
27 gets updated in the process.
30 ch7sel(expp, oper, idf)
34 /* The selector idf is applied to *expp; oper may be '.' or
37 register struct expr *exp;
38 register struct type *tp;
39 register struct sdef *sd;
45 if (tp->tp_fund == POINTER &&
46 ( tp->tp_up->tp_fund == STRUCT ||
47 tp->tp_up->tp_fund == UNION)) /* normal case */
49 else { /* constructions like "12->selector" and
52 switch (tp->tp_fund) {
55 /* Allowed by RM 14.1 */
56 ch7cast(expp, CAST, pa_type);
57 sd = idf2sdef(idf, tp);
63 expr_error(exp, "-> applied to %s",
64 symbol2str(tp->tp_fund));
66 exp->ex_type = error_type;
71 else { /* oper == '.' */
72 /* filter out illegal expressions "non_lvalue.sel" */
73 if (!exp->ex_lvalue) {
74 expr_error(exp, "dot requires lvalue");
79 switch (tp->tp_fund) {
80 case POINTER: /* for int *p; p->next = ... */
86 /* warning will be given by idf2sdef() */
89 if (!is_anon_idf(idf))
90 expr_error(exp, "selector %s applied to %s",
91 idf->id_text, symbol2str(tp->tp_fund));
93 exp->ex_type = error_type;
96 sd = idf2sdef(idf, tp);
98 /* there are 3 cases in which the selection can be
99 performed compile-time:
100 I: n.sel (n either an identifier or a constant)
101 II: (e.s1).s2 (transformed into (e.(s1+s2)))
102 III: (e->s1).s2 (transformed into (e->(s1+s2)))
103 The code performing these conversions is
106 if (exp->ex_class == Value) {
107 /* It is an object we know the address of; so
108 we can calculate the address of the
111 exp->VL_VALUE += sd->sd_offset;
112 exp->ex_type = sd->sd_type;
113 if (exp->ex_type == error_type)
114 exp->ex_flags |= EX_ERROR;
117 if (exp->ex_class == Oper) {
118 struct oper *op = &(exp->ex_object.ex_oper);
120 if (op->op_oper == '.' || op->op_oper == ARROW) {
121 ASSERT(is_cp_cst(op->op_right));
122 op->op_right->VL_VALUE += sd->sd_offset;
123 exp->ex_type = sd->sd_type;
124 if (exp->ex_type == error_type)
125 exp->ex_flags |= EX_ERROR;
128 exp = new_oper(sd->sd_type, exp, '.',
129 intexpr(sd->sd_offset, INT));
132 else /* oper == ARROW */
133 exp = new_oper(sd->sd_type,
134 exp, oper, intexpr(sd->sd_offset, INT));
135 exp->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
142 /* The monadic prefix/postfix incr/decr operator oper is
145 ch7asgn(expp, oper, intexpr((arith)1, INT));
148 ch7cast(expp, oper, tp)
149 register struct expr **expp;
150 register struct type *tp;
152 /* The expression *expp is cast to type tp; the cast is
153 caused by the operator oper. If the cast has
154 to be passed on to run time, its left operand will be an
155 expression of class Type.
157 register struct type *oldtp;
159 if ((*expp)->ex_type->tp_fund == FUNCTION)
160 function2pointer(*expp);
161 if ((*expp)->ex_type->tp_fund == ARRAY)
162 array2pointer(*expp);
163 if ((*expp)->ex_class == String)
164 string2pointer(*expp);
165 oldtp = (*expp)->ex_type;
168 if (oldtp->tp_fund == FIELD) {
170 ch7cast(expp, oper, tp);
173 if (tp->tp_fund == FIELD) {
174 ch7cast(expp, oper, tp->tp_up);
177 #endif /* NOBITFIELD */
182 if (tp->tp_fund == VOID) {
184 (*expp)->ex_type = void_type;
187 if (is_arith_type(oldtp) && is_arith_type(tp)) {
188 int oldi = is_integral_type(oldtp);
189 int i = is_integral_type(tp);
193 && ( tp->tp_fund == ENUM
194 || oldtp->tp_fund == ENUM
198 "dubious %s on enum",
203 (*expp)->ex_type = tp;
213 if (oldtp->tp_fund == ENUM && oper != CAST)
215 "conversion of enum to %s\n",
216 symbol2str(tp->tp_fund));
219 (*expp)->ex_type = tp;
230 (*expp)->ex_type = tp;
241 (*expp)->ex_type = tp;
243 float2float(expp, tp);
245 float2float(expp, tp);
250 crash("(ch7cast) floats not implemented\n");
256 if (oldtp->tp_fund == POINTER && tp->tp_fund == POINTER) {
258 expr_warning(*expp, "incompatible pointers in %s",
262 lint_ptr_conv(oldtp->tp_up->tp_fund, tp->tp_up->tp_fund);
264 (*expp)->ex_type = tp; /* free conversion */
267 if (oldtp->tp_fund == POINTER && is_integral_type(tp)) {
268 /* from pointer to integral */
271 "illegal conversion of pointer to %s",
272 symbol2str(tp->tp_fund));
273 if (oldtp->tp_size > tp->tp_size)
275 "conversion of pointer to %s loses accuracy",
276 symbol2str(tp->tp_fund));
277 if (oldtp->tp_size != tp->tp_size)
280 (*expp)->ex_type = tp;
283 if (tp->tp_fund == POINTER && is_integral_type(oldtp)) {
284 /* from integral to pointer */
293 if (is_cp_cst(*expp) && (*expp)->VL_VALUE == (arith)0)
297 "dubious conversion of %s to pointer",
298 symbol2str(oldtp->tp_fund));
301 if (oldtp->tp_size > tp->tp_size)
303 "conversion of %s to pointer loses accuracy",
304 symbol2str(oldtp->tp_fund));
305 if (oldtp->tp_size != tp->tp_size)
308 (*expp)->ex_type = tp;
311 if (oldtp->tp_fund == ERRONEOUS) {
312 /* we just won't look */
313 (*expp)->ex_type = tp; /* brute force */
316 if (oldtp->tp_size == tp->tp_size && oper == CAST) {
317 expr_warning(*expp, "dubious conversion based on equal size");
318 (*expp)->ex_type = tp; /* brute force */
321 if (oldtp->tp_fund != ERRONEOUS && tp->tp_fund != ERRONEOUS)
322 expr_error(*expp, "cannot convert %s to %s",
323 symbol2str(oldtp->tp_fund),
324 symbol2str(tp->tp_fund)
326 (*expp)->ex_type = tp; /* brute force */
330 ch7asgn(expp, oper, expr)
334 /* The assignment operators.
335 "f op= e" should be interpreted as
336 "f = (typeof f)((typeof (f op e))f op (typeof (f op e))e)"
337 and not as "f = f op (typeof f)e".
338 Consider, for example, (i == 10) i *= 0.9; (i == 9), where
340 The resulting expression tree becomes:
345 EVAL should however take care of evaluating (typeof (f op e))f
347 register struct expr *exp = *expp;
348 int fund = exp->ex_type->tp_fund;
351 /* We expect an lvalue */
352 if (!exp->ex_lvalue) {
353 expr_error(exp, "no lvalue in lhs of %s", symbol2str(oper));
354 exp->ex_depth = 99; /* no direct store/load at EVAL() */
355 /* what is 99 ??? DG */
358 ch7cast(&expr, oper, exp->ex_type);
361 else { /* turn e into e' where typeof(e') = typeof (f op e) */
362 struct expr *extmp = intexpr((arith)0, INT);
364 /* this is really $#@&*%$# ! */
365 /* if you correct this, please correct lint_new_oper() too */
366 extmp->ex_lvalue = 1;
367 extmp->ex_type = exp->ex_type;
368 ch7bin(&extmp, oper, expr);
369 /* Note that ch7bin creates a tree of the expression
370 ((typeof (f op e))f op (typeof (f op e))e),
371 where f ~ extmp and e ~ expr.
372 We want to use (typeof (f op e))e.
373 Ch7bin does not create a tree if both operands
374 were illegal or constants!
376 tp = extmp->ex_type; /* perform the arithmetic in type tp */
377 if (extmp->ex_class == Oper) {
378 expr = extmp->OP_RIGHT;
379 extmp->OP_RIGHT = NILEXPR;
380 free_expression(extmp);
387 exp = new_oper(exp->ex_type->tp_up, exp, oper, expr);
389 exp = new_oper(exp->ex_type, exp, oper, expr);
390 #else /* NOBITFIELD */
391 exp = new_oper(exp->ex_type, exp, oper, expr);
392 #endif /* NOBITFIELD */
393 exp->OP_TYPE = tp; /* for EVAL() */
394 exp->ex_flags |= EX_SIDEEFFECTS;
398 /* Some interesting (?) questions answered.
402 register struct type *tp;
404 switch (tp->tp_fund) {
413 return is_integral_type(tp->tp_up);
414 #endif /* NOBITFIELD */
422 register struct type *tp;
424 switch (tp->tp_fund) {
437 return is_arith_type(tp->tp_up);
438 #endif /* NOBITFIELD */