Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom / ch7.c
1 /*
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".
4  */
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        */
7
8 #include        "lint.h"
9 #include        "nofloat.h"
10 #include        "debug.h"
11 #include        "nobitfield.h"
12 #include        "idf.h"
13 #include        "arith.h"
14 #include        "type.h"
15 #include        "struct.h"
16 #include        "label.h"
17 #include        "expr.h"
18 #include        "def.h"
19 #include        "Lpars.h"
20 #include        "assert.h"
21
22 extern char options[];
23 extern char *symbol2str();
24
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.
28 */
29
30 ch7sel(expp, oper, idf)
31         struct expr **expp;
32         struct idf *idf;
33 {
34         /*      The selector idf is applied to *expp; oper may be '.' or
35                 ARROW.
36         */
37         register struct expr *exp;
38         register struct type *tp;
39         register struct sdef *sd;
40
41         any2opnd(expp, oper);
42         exp = *expp;
43         tp = exp->ex_type;
44         if (oper == ARROW)      {
45                 if (tp->tp_fund == POINTER &&
46                     ( tp->tp_up->tp_fund == STRUCT ||
47                       tp->tp_up->tp_fund == UNION))     /* normal case */
48                         tp = tp->tp_up;
49                 else {  /* constructions like "12->selector" and
50                                 "char c; c->selector"
51                         */
52                         switch (tp->tp_fund)    {
53                         case INT:
54                         case LONG:
55                                 /* Allowed by RM 14.1 */
56                                 ch7cast(expp, CAST, pa_type);
57                                 sd = idf2sdef(idf, tp);
58                                 tp = sd->sd_stype;
59                                 break;
60                         case POINTER:
61                                 break;
62                         default:
63                                 expr_error(exp, "-> applied to %s",
64                                         symbol2str(tp->tp_fund));
65                         case ERRONEOUS:
66                                 exp->ex_type = error_type;
67                                 return;
68                         }
69                 }
70         } /* oper == ARROW */
71         else { /* oper == '.' */
72                 /* filter out illegal expressions "non_lvalue.sel" */
73                 if (!exp->ex_lvalue) {
74                         expr_error(exp, "dot requires lvalue");
75                         return;
76                 }
77         }
78         exp = *expp;
79         switch (tp->tp_fund)    {
80         case POINTER:   /* for int *p;  p->next = ...   */
81         case STRUCT:
82         case UNION:
83                 break;
84         case INT:
85         case LONG:
86                 /* warning will be given by idf2sdef() */
87                 break;
88         default:
89                 if (!is_anon_idf(idf))
90                         expr_error(exp, "selector %s applied to %s",
91                                 idf->id_text, symbol2str(tp->tp_fund));
92         case ERRONEOUS:
93                 exp->ex_type = error_type;
94                 return;
95         }
96         sd = idf2sdef(idf, tp);
97         if (oper == '.')        {
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
104                                 extremely obscure.
105                 */
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
109                                 selected member 
110                         */
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;
115                 }
116                 else
117                 if (exp->ex_class == Oper)      {
118                         struct oper *op = &(exp->ex_object.ex_oper);
119                         
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;
126                         }
127                         else
128                                 exp = new_oper(sd->sd_type, exp, '.',
129                                                 intexpr(sd->sd_offset, INT));
130                 }
131         }
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);
136         *expp = exp;
137 }
138
139 ch7incr(expp, oper)
140         struct expr **expp;
141 {
142         /*      The monadic prefix/postfix incr/decr operator oper is
143                 applied to *expp.
144         */
145         ch7asgn(expp, oper, intexpr((arith)1, INT));
146 }
147
148 ch7cast(expp, oper, tp)
149         register struct expr **expp;
150         register struct type *tp;
151 {
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.
156         */
157         register struct type *oldtp;
158
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;
166
167 #ifndef NOBITFIELD
168         if (oldtp->tp_fund == FIELD)    {
169                 field2arith(expp);
170                 ch7cast(expp, oper, tp);
171         }
172         else
173         if (tp->tp_fund == FIELD) {
174                 ch7cast(expp, oper, tp->tp_up);
175         }
176         else
177 #endif /* NOBITFIELD */
178         if (oldtp == tp) {
179                 /* life is easy */
180         }
181         else
182         if (tp->tp_fund == VOID) {
183                 /* Easy again */
184                 (*expp)->ex_type = void_type;
185         }
186         else
187         if (is_arith_type(oldtp) && is_arith_type(tp))  {
188                 int oldi = is_integral_type(oldtp);
189                 int i = is_integral_type(tp);
190
191                 if (oldi && i)  {
192                         if (    oper != CAST
193                         &&      (       tp->tp_fund == ENUM
194                                 ||      oldtp->tp_fund == ENUM
195                                 )
196                         ) {
197                                 expr_warning(*expp,
198                                         "dubious %s on enum",
199                                         symbol2str(oper));
200                         }
201 #ifdef  LINT
202                         if (oper == CAST)
203                                 (*expp)->ex_type = tp;
204                         else
205                                 int2int(expp, tp);
206 #else   /* LINT */
207                         int2int(expp, tp);
208 #endif  /* LINT */
209                 }
210 #ifndef NOFLOAT
211                 else
212                 if (oldi && !i) {
213                         if (oldtp->tp_fund == ENUM && oper != CAST)
214                                 expr_warning(*expp,
215                                         "conversion of enum to %s\n",
216                                         symbol2str(tp->tp_fund));
217 #ifdef  LINT
218                         if (oper == CAST)
219                                 (*expp)->ex_type = tp;
220                         else
221                                 int2float(expp, tp);
222 #else   /* LINT */
223                         int2float(expp, tp);
224 #endif  /* LINT */
225                 }
226                 else
227                 if (!oldi && i) {
228 #ifdef  LINT
229                         if (oper == CAST)
230                                 (*expp)->ex_type = tp;
231                         else
232                                 float2int(expp, tp);
233 #else   /* LINT */
234                         float2int(expp, tp);
235 #endif  /* LINT */
236                 }
237                 else {
238                         /* !oldi && !i */
239 #ifdef  LINT
240                         if (oper == CAST)
241                                 (*expp)->ex_type = tp;
242                         else
243                                 float2float(expp, tp);
244 #else   /* LINT */
245                         float2float(expp, tp);
246 #endif  /* LINT */
247                 }
248 #else /* NOFLOAT */
249                 else {
250                         crash("(ch7cast) floats not implemented\n");
251                         /*NOTREACHED*/
252                 }
253 #endif /* NOFLOAT */
254         }
255         else
256         if (oldtp->tp_fund == POINTER && tp->tp_fund == POINTER)        {
257                 if (oper != CAST)
258                         expr_warning(*expp, "incompatible pointers in %s",
259                                                         symbol2str(oper));
260 #ifdef  LINT
261                 if (oper != CAST)
262                         lint_ptr_conv(oldtp->tp_up->tp_fund, tp->tp_up->tp_fund);
263 #endif  /* LINT */
264                 (*expp)->ex_type = tp;  /* free conversion */
265         }
266         else
267         if (oldtp->tp_fund == POINTER && is_integral_type(tp))  {
268                 /* from pointer to integral */
269                 if (oper != CAST)
270                         expr_warning(*expp,
271                                 "illegal conversion of pointer to %s",
272                                 symbol2str(tp->tp_fund));
273                 if (oldtp->tp_size > tp->tp_size)
274                         expr_warning(*expp,
275                                 "conversion of pointer to %s loses accuracy",
276                                 symbol2str(tp->tp_fund));
277                 if (oldtp->tp_size != tp->tp_size)
278                         int2int(expp, tp);
279                 else
280                         (*expp)->ex_type = tp;
281         }
282         else
283         if (tp->tp_fund == POINTER && is_integral_type(oldtp))  {
284                 /* from integral to pointer */
285                 switch (oper)   {
286                 case CAST:
287                         break;
288                 case EQUAL:
289                 case NOTEQUAL:
290                 case ':':
291                 case '=':
292                 case RETURN:
293                         if (is_cp_cst(*expp) && (*expp)->VL_VALUE == (arith)0)
294                                 break;
295                 default:
296                         expr_warning(*expp,
297                                 "dubious conversion of %s to pointer",
298                                 symbol2str(oldtp->tp_fund));
299                         break;
300                 }
301                 if (oldtp->tp_size > tp->tp_size)
302                         expr_warning(*expp,
303                                 "conversion of %s to pointer loses accuracy",
304                                 symbol2str(oldtp->tp_fund));
305                 if (oldtp->tp_size != tp->tp_size)
306                         int2int(expp, tp);
307                 else
308                         (*expp)->ex_type = tp;
309         }
310         else
311         if (oldtp->tp_fund == ERRONEOUS) {
312                 /* we just won't look */
313                 (*expp)->ex_type = tp;  /* brute force */
314         }
315         else
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 */
319         }
320         else    {
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)
325                         );
326                 (*expp)->ex_type = tp;          /* brute force */
327         }
328 }
329
330 ch7asgn(expp, oper, expr)
331         struct expr **expp;
332         struct expr *expr;
333 {
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
339                 typeof i == int.
340                 The resulting expression tree becomes:
341                                 op=
342                                 / \
343                                /   \
344                               f     (typeof (f op e))e
345                 EVAL should however take care of evaluating (typeof (f op e))f
346         */
347         register struct expr *exp = *expp;
348         int fund = exp->ex_type->tp_fund;
349         struct type *tp;
350
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 */
356         }
357         if (oper == '=') {
358                 ch7cast(&expr, oper, exp->ex_type);
359                 tp = expr->ex_type;
360         }
361         else {  /* turn e into e' where typeof(e') = typeof (f op e) */
362                 struct expr *extmp = intexpr((arith)0, INT);
363
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!
375                 */
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);
381                 }
382                 else
383                         expr = extmp;
384         }
385 #ifndef NOBITFIELD
386         if (fund == FIELD)
387                 exp = new_oper(exp->ex_type->tp_up, exp, oper, expr);
388         else
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;
395         *expp = exp;
396 }
397
398 /*      Some interesting (?) questions answered.
399 */
400 int
401 is_integral_type(tp)
402         register struct type *tp;
403 {
404         switch (tp->tp_fund)    {
405         case CHAR:
406         case SHORT:
407         case INT:
408         case LONG:
409         case ENUM:
410                 return 1;
411 #ifndef NOBITFIELD
412         case FIELD:
413                 return is_integral_type(tp->tp_up);
414 #endif /* NOBITFIELD */
415         default:
416                 return 0;
417         }
418 }
419
420 int
421 is_arith_type(tp)
422         register struct type *tp;
423 {
424         switch (tp->tp_fund)    {
425         case CHAR:
426         case SHORT:
427         case INT:
428         case LONG:
429         case ENUM:
430 #ifndef NOFLOAT
431         case FLOAT:
432         case DOUBLE:
433 #endif /* NOFLOAT */
434                 return 1;
435 #ifndef NOBITFIELD
436         case FIELD:
437                 return is_arith_type(tp->tp_up);
438 #endif /* NOBITFIELD */
439         default:
440                 return 0;
441         }
442 }