Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20071116234901

Diff

Diff from 1.174 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/trees.c

Annotated File View

gmcgarry
1.174
1 /*      $Id: trees.c,v 1.174 2007/11/16 23:49:01 gmcgarry Exp $ */
ragge
1.51
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
62 /*
63  * Some of the changes from 32V include:
64  * - Understand "void" as type.
65  * - Handle enums as ints everywhere.
ragge
1.57
66  * - Convert some C-specific ops into branches.
ragge
1.51
67  */
68
ragge
1.1
69 # include "pass1.h"
ragge
1.51
70 # include "pass2.h"
ragge
1.1
71
ragge
1.16
72 # include <stdarg.h>
ragge
1.1
73
ragge
1.51
74 static void chkpun(NODE *p);
ragge
1.166
75 static int chkenum(intintNODE *p);
ragge
1.51
76 static int opact(NODE *p);
77 static int moditype(TWORD);
ragge
1.45
78 static NODE *strargs(NODE *);
ragge
1.57
79 static void rmcops(NODE *p);
ragge
1.2
80
ragge
1.77
81 int lastloc = -1;
ragge
1.1
82
83 /*      some special actions, used in finding the type of nodes */
84 # define NCVT 01
85 # define PUN 02
86 # define TYPL 04
87 # define TYPR 010
88 # define TYMATCH 040
89 # define LVAL 0100
90 # define CVTO 0200
91 # define CVTL 0400
92 # define CVTR 01000
93 # define PTMATCH 02000
94 # define OTHER 04000
95 # define NCVTR 010000
96
97 /* node conventions:
98
99         NAME:   rval>0 is stab index for external
100                 rval<0 is -inlabel number
101                 lval is offset in bits
102         ICON:   lval has the value
103                 rval has the STAB index, or - label number,
104                         if a name whose address is in the constant
105                 rval = NONAME means no name
106         REG:    rval is reg. identification cookie
107
108         */
109
ragge
1.30
110 int bdebug = 0;
111
ragge
1.1
112 NODE *
ragge
1.2
113 buildtree(int oNODE *lNODE *r)
114 {
115         NODE *p, *q;
116         int actions;
117         int opty;
ragge
1.119
118         struct symtab *sp = NULL/* XXX gcc */
ragge
1.2
119         NODE *lr, *ll;
ragge
1.23
120         char *name;
ragge
1.26
121         struct symtab **elem;
ragge
1.1
122
ragge
1.68
123 #ifdef PCC_DEBUG
ragge
1.128
124         if (bdebug) {
ragge
1.58
125                 printf("buildtree(%s, %p, %p)\n"copst(o), lr);
ragge
1.128
126                 if (lfwalk(leprint0);
127                 if (rfwalk(reprint0);
128         }
ragge
1.68
129 #endif
ragge
1.58
130         opty = coptype(o);
ragge
1.1
131
132         /* check for constants */
133
ragge
1.22
134         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
135
136                 switcho ){
137
138                 case NOT:
ragge
1.94
139                 case UMINUS:
ragge
1.1
140                 case COMPL:
141                         ifconvallol ) ) return(l);
142                         break;
143                 }
ragge
1.71
144         } else if (o == NOT && l->n_op == FCON) {
145                 l = clocal(block(SCONVlNILINT0MKSUE(INT)));
ragge
1.94
146         } else ifo == UMINUS && l->n_op == FCON ){
ragge
1.71
147                         l->n_dcon = -l->n_dcon;
ragge
1.1
148                         return(l);
149
ragge
1.44
150         } else ifo==QUEST && l->n_op==ICON ) {
ragge
1.41
151                 CONSZ c = l->n_lval;
152                 nfree(l);
153                 if (c) {
154                         tfree(r->n_right);
155                         l = r->n_left;
156                         nfree(r);
157                         return(l);
158                 } else {
159                         tfree(r->n_left);
160                         l = r->n_right;
161                         nfree(r);
162                         return(l);
ragge
1.1
163                 }
ragge
1.155
164         } else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
165
166                 switcho ){
167
ragge
1.159
168                 case PLUS:
169                 case MINUS:
170                 case MUL:
171                 case DIV:
172                 case MOD:
173                         /*
174                          * Do type propagation for simple types here.
175                          * The constant value is correct anyway.
176                          * Maybe this op shortcut should be removed?
177                          */
178                         if (l->n_sp == NULL && r->n_sp == NULL &&
179                             l->n_type < BTMASK && r->n_type < BTMASK) {
180                                 if (l->n_type > r->n_type)
181                                         r->n_type = l->n_type;
182                                 else
183                                         l->n_type = r->n_type;
184                         }
185                         /* FALLTHROUGH */
ragge
1.1
186                 case ULT:
187                 case UGT:
188                 case ULE:
189                 case UGE:
190                 case LT:
191                 case GT:
192                 case LE:
193                 case GE:
194                 case EQ:
ragge
1.48
195                 case NE:
ragge
1.1
196                 case ANDAND:
197                 case OROR:
198                 case AND:
199                 case OR:
200                 case ER:
201                 case LS:
202                 case RS:
203                         ifconvallor ) ) {
ragge
1.41
204                                 nfree(r);
ragge
1.1
205                                 return(l);
ragge
1.44
206                         }
ragge
1.1
207                         break;
208                 }
ragge
1.44
209         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
210             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
211             o == MUL || o == DIV)) {
212                 switch(o){
213                 case PLUS:
214                 case MINUS:
215                 case MUL:
216                 case DIV:
217                         if (l->n_op == ICON)
218                                 l->n_dcon = l->n_lval;
219                         if (r->n_op == ICON)
220                                 r->n_dcon = r->n_lval;
221                         switch (o) {
222                         case PLUS:
223                                 l->n_dcon += r->n_dconbreak;
224                         case MINUS:
225                                 l->n_dcon -= r->n_dconbreak;
226                         case MUL:
227                                 l->n_dcon *= r->n_dconbreak;
228                         case DIV:
229                                 if (r->n_dcon == 0)
otto
1.170
230                                         goto runtime;
ragge
1.44
231                                 else
232                                         l->n_dcon /= r->n_dcon;
233                         }
234                         l->n_op = FCON;
235                         l->n_type = DOUBLE;
236                         l->n_sue = MKSUE(DOUBLE);
237                         nfree(r);
238                         return(l);
ragge
1.1
239                 }
ragge
1.44
240         }
otto
1.170
241 runtime:
ragge
1.30
242         /* its real; we must make a new node */
ragge
1.1
243
ragge
1.26
244         p = block(olrINT0MKSUE(INT));
ragge
1.1
245
246         actions = opact(p);
247
ragge
1.66
248         if (actions & LVAL) { /* check left descendent */
249                 if (notlval(p->n_left)) {
250                         uerror("lvalue required");
ragge
1.68
251 #ifdef notyet
ragge
1.67
252                 } else {
253                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
254                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
255                                 if (blevel > 0)
256                                         uerror("lvalue is declared const");
ragge
1.68
257 #endif
ragge
1.67
258                 }
ragge
1.66
259         }
ragge
1.1
260
261         ifactions & NCVTR ){
ragge
1.22
262                 p->n_left = pconvertp->n_left );
ragge
1.1
263                 }
264         else if( !(actions & NCVT ) ){
265                 switchopty ){
266
267                 case BITYPE:
ragge
1.22
268                         p->n_right = pconvertp->n_right );
ragge
1.1
269                 case UTYPE:
ragge
1.22
270                         p->n_left = pconvertp->n_left );
ragge
1.1
271
272                         }
273                 }
274
ragge
1.64
275         if ((actions&PUN) && (o!=CAST))
ragge
1.1
276                 chkpun(p);
277
278         ifactions & (TYPL|TYPR) ){
279
ragge
1.22
280                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
281
ragge
1.22
282                 p->n_type = q->n_type;
ragge
1.66
283                 p->n_qual = q->n_qual;
ragge
1.29
284                 p->n_df = q->n_df;
ragge
1.26
285                 p->n_sue = q->n_sue;
ragge
1.1
286                 }
287
288         ifactions & CVTL ) p = convertpCVTL );
289         ifactions & CVTR ) p = convertpCVTR );
290         ifactions & TYMATCH ) p = tymatch(p);
291         ifactions & PTMATCH ) p = ptmatch(p);
292
293         ifactions & OTHER ){
ragge
1.22
294                 l = p->n_left;
295                 r = p->n_right;
ragge
1.1
296
297                 switch(o){
298
299                 case NAME:
ragge
1.23
300                         sp = spname;
ragge
1.129
301                         if (sp->sflags & STNODE) {
302                                 /* Generated for optimizer */
303                                 p->n_op = TEMP;
304                                 p->n_type = sp->stype;
305                                 p->n_sue = sp->ssue;
306                                 p->n_df = sp->sdf;
307                                 p->n_lval = sp->soffset;
308                                 break;
309                         }
310                                 
ragge
1.115
311 #ifdef GCC_COMPAT
312                         /* Get a label name */
313                         if (sp->sflags == SLBLNAME) {
314                                 p->n_type = VOID;
315                                 p->n_sue = MKSUE(VOID);
316                                 p->n_lval = 0;
317                                 p->n_sp = sp;
318                                 break;
319                         } else
320 #endif
ragge
1.23
321                         if (sp->stype == UNDEF) {
322                                 uerror("%s undefined"sp->sname);
ragge
1.1
323                                 /* make p look reasonable */
ragge
1.26
324                                 p->n_type = INT;
325                                 p->n_sue = MKSUE(INT);
ragge
1.29
326                                 p->n_df = NULL;
ragge
1.23
327                                 p->n_sp = sp;
ragge
1.22
328                                 p->n_lval = 0;
ragge
1.23
329                                 defid(pSNULL);
ragge
1.1
330                                 break;
ragge
1.23
331                         }
ragge
1.22
332                         p->n_type = sp->stype;
ragge
1.66
333                         p->n_qual = sp->squal;
ragge
1.29
334                         p->n_df = sp->sdf;
ragge
1.26
335                         p->n_sue = sp->ssue;
ragge
1.22
336                         p->n_lval = 0;
ragge
1.23
337                         p->n_sp = sp;
ragge
1.1
338                         /* special case: MOETY is really an ICON... */
ragge
1.23
339                         if (p->n_type == MOETY) {
340                                 p->n_sp = NULL;
341                                 p->n_lval = sp->soffset;
ragge
1.29
342                                 p->n_df = NULL;
ragge
1.22
343                                 p->n_type = ENUMTY;
344                                 p->n_op = ICON;
ragge
1.23
345                         }
ragge
1.1
346                         break;
347
348                 case STREF:
349                         /* p->x turned into *(p+offset) */
350                         /* rhs must be a name; check correctness */
351
ragge
1.23
352                         /* Find member symbol struct */
353                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
354                                 uerror("struct or union required");
355                                 break;
356                         }
357
ragge
1.26
358                         if ((elem = l->n_sue->suelem) == NULL)
ragge
1.23
359                                 uerror("undefined struct or union");
360
361                         name = r->n_name;
ragge
1.26
362                         for (; *elem != NULLelem++) {
363                                 sp = *elem;
ragge
1.23
364                                 if (sp->sname == name)
365                                         break;
366                         }
ragge
1.26
367                         if (*elem == NULL)
ragge
1.23
368                                 uerror("member '%s' not declared"name);
369
370                         r->n_sp = sp;
371                         p = stref(p);
372                         break;
373
ragge
1.94
374                 case UMUL:
ragge
1.93
375                         if (l->n_op == ADDROF) {
ragge
1.41
376                                 nfree(p);
ragge
1.22
377                                 p = l->n_left;
ragge
1.41
378                                 nfree(l);
379                         }
ragge
1.22
380                         if( !ISPTR(l->n_type))uerror("illegal indirection");
381                         p->n_type = DECREF(l->n_type);
ragge
1.67
382                         p->n_qual = DECREF(l->n_qual);
ragge
1.29
383                         p->n_df = l->n_df;
ragge
1.26
384                         p->n_sue = l->n_sue;
ragge
1.1
385                         break;
386
ragge
1.93
387                 case ADDROF:
ragge
1.22
388                         switchl->n_op ){
ragge
1.1
389
ragge
1.94
390                         case UMUL:
ragge
1.41
391                                 nfree(p);
ragge
1.22
392                                 p = l->n_left;
ragge
1.41
393                                 nfree(l);
ragge
1.130
394                         case TEMP:
ragge
1.1
395                         case NAME:
ragge
1.68
396                                 p->n_type = INCREF(l->n_type);
397                                 p->n_qual = INCQAL(l->n_qual);
ragge
1.29
398                                 p->n_df = l->n_df;
ragge
1.26
399                                 p->n_sue = l->n_sue;
ragge
1.1
400                                 break;
401
402                         case COMOP:
ragge
1.41
403                                 nfree(p);
ragge
1.93
404                                 lr = buildtree(ADDROFl->n_rightNIL);
ragge
1.22
405                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
406                                 nfree(l);
ragge
1.1
407                                 break;
408
409                         case QUEST:
ragge
1.93
410                                 lr = buildtreeADDROFl->n_right->n_rightNIL );
411                                 ll = buildtreeADDROFl->n_right->n_leftNIL );
ragge
1.41
412                                 nfree(p); nfree(l->n_right);
ragge
1.22
413                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
414                                 nfree(l);
ragge
1.1
415                                 break;
416
417                         default:
ragge
1.22
418                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
419                                 break;
420                                 }
421                         break;
422
423                 case LS:
ragge
1.150
424                 case RS/* must make type size at least int... */
425                         if (p->n_type == CHAR || p->n_type == SHORT) {
426                                 p->n_left = makety(lINT00MKSUE(INT));
427                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
428                                 p->n_left = makety(lUNSIGNED00,
429                                     MKSUE(UNSIGNED));
430                         }
431                         l = p->n_left;
432                         p->n_type = l->n_type;
433                         p->n_qual = l->n_qual;
434                         p->n_df = l->n_df;
435                         p->n_sue = l->n_sue;
436
437                         /* FALLTHROUGH */
ragge
1.95
438                 case LSEQ:
ragge
1.150
439                 case RSEQ/* ...but not for assigned types */
440                         if(tsize(r->n_typer->n_dfr->n_sue) > SZINT)
441                                 p->n_right = makety(rINT00MKSUE(INT));
ragge
1.1
442                         break;
443
444                 case RETURN:
445                 case ASSIGN:
446                 case CAST:
447                         /* structure assignment */
448                         /* take the addresses of the two sides; then make an
ragge
1.2
449                          * operator using STASG and
450                          * the addresses of left and right */
ragge
1.1
451
452                         {
ragge
1.26
453                                 struct suedef *sue;
ragge
1.2
454                                 TWORD t;
ragge
1.29
455                                 union dimfun *d;
ragge
1.1
456
ragge
1.26
457                                 if (l->n_sue != r->n_sue)
458                                         uerror("assignment of different structures");
ragge
1.1
459
ragge
1.93
460                                 r = buildtree(ADDROFrNIL);
ragge
1.22
461                                 t = r->n_type;
ragge
1.29
462                                 d = r->n_df;
ragge
1.26
463                                 sue = r->n_sue;
ragge
1.1
464
ragge
1.28
465                                 l = block(STASGlrtdsue);
ragge
1.1
466
467                                 ifo == RETURN ){
ragge
1.41
468                                         nfree(p);
ragge
1.1
469                                         p = l;
470                                         break;
ragge
1.28
471                                 }
ragge
1.1
472
ragge
1.94
473                                 p->n_op = UMUL;
ragge
1.22
474                                 p->n_left = l;
475                                 p->n_right = NIL;
ragge
1.1
476                                 break;
477                                 }
478                 case COLON:
479                         /* structure colon */
480
ragge
1.26
481                         if (l->n_sue != r->n_sue)
482                                 uerror"type clash in conditional" );
ragge
1.1
483                         break;
484
485                 case CALL:
ragge
1.45
486                         p->n_right = r = strargs(p->n_right);
ragge
1.171
487                         p = funcode(p);
488                         /* FALLTHROUGH */
ragge
1.95
489                 case UCALL:
ragge
1.23
490                         if (!ISPTR(l->n_type))
491                                 uerror("illegal function");
ragge
1.22
492                         p->n_type = DECREF(l->n_type);
ragge
1.23
493                         if (!ISFTN(p->n_type))
494                                 uerror("illegal function");
495                         p->n_type = DECREF(p->n_type);
ragge
1.29
496                         p->n_df = l->n_df;
ragge
1.26
497                         p->n_sue = l->n_sue;
ragge
1.93
498                         if (l->n_op == ADDROF && l->n_left->n_op == NAME &&
ragge
1.23
499                             l->n_left->n_sp != NULL && l->n_left->n_sp != NULL &&
500                             (l->n_left->n_sp->sclass == FORTRAN ||
501                             l->n_left->n_sp->sclass == UFORTRAN)) {
ragge
1.22
502                                 p->n_op += (FORTCALL-CALL);
ragge
1.23
503                         }
504                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
505                                 /* function returning structure */
506                                 /*  make function really return ptr to str., with * */
507
ragge
1.22
508                                 p->n_op += STCALL-CALL;
ragge
1.23
509                                 p->n_type = INCREF(p->n_type);
ragge
1.149
510                                 p = clocal(p); /* before recursing */
ragge
1.94
511                                 p = buildtree(UMULpNIL);
ragge
1.1
512
513                                 }
514                         break;
515
516                 default:
517                         cerror"other code %d"o );
518                         }
519
520                 }
521
ragge
1.11
522         /*
523          * Allow (void)0 casts.
524          * XXX - anything on the right side must be possible to cast.
525          * XXX - remove void types further on.
526          */
ragge
1.50
527         if (p->n_op == CAST && p->n_type == VOID &&
ragge
1.22
528             p->n_right->n_op == ICON)
ragge
1.50
529                 p->n_right->n_type = VOID;
ragge
1.11
530
ragge
1.68
531         if (actions & CVTO)
532                 p = oconvert(p);
ragge
1.1
533         p = clocal(p);
534
ragge
1.30
535 #ifdef PCC_DEBUG
ragge
1.74
536         if (bdebug) {
537                 printf("End of buildtree:\n");
ragge
1.68
538                 fwalk(peprint0);
ragge
1.74
539         }
ragge
1.30
540 #endif
ragge
1.1
541
542         return(p);
543
544         }
545
ragge
1.107
546 /*
547  * Do a conditional branch.
548  */
549 void
550 cbranch(NODE *pNODE *q)
551 {
552         p = buildtree(CBRANCHpq);
553         if (p->n_left->n_op == ICON) {
554                 if (p->n_left->n_lval != 0)
555                         branch(q->n_lval); /* branch always */
556                 tfree(p);
557                 tfree(q);
558                 return;
559         }
560         ecomp(p);
561 }
562
ragge
1.1
563 NODE *
ragge
1.45
564 strargsp ) register NODE *p;  { /* rewrite structure flavored arguments */
ragge
1.1
565
ragge
1.45
566         ifp->n_op == CM ){
567                 p->n_left = strargsp->n_left );
568                 p->n_right = strargsp->n_right );
ragge
1.1
569                 returnp );
570                 }
571
ragge
1.22
572         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.29
573                 p = block(STARGpNILp->n_typep->n_dfp->n_sue);
ragge
1.93
574                 p->n_left = buildtreeADDROFp->n_leftNIL );
ragge
1.1
575                 p = clocal(p);
576                 }
577         returnp );
ragge
1.2
578 }
ragge
1.1
579
ragge
1.2
580 /*
581  * apply the op o to the lval part of p; if binary, rhs is val
582  */
583 int
584 conval(NODE *pint oNODE *q)
585 {
ragge
1.1
586         int iu;
587         CONSZ val;
ragge
1.159
588         U_CONSZ v1v2;
ragge
1.1
589
ragge
1.22
590         val = q->n_lval;
591         u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
ragge
1.1
592         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
593
ragge
1.23
594         if (p->n_sp != NULL && q->n_sp != NULL)
595                 return(0);
596         if (q->n_sp != NULL && o != PLUS)
597                 return(0);
598         if (p->n_sp != NULL && o != PLUS && o != MINUS)
599                 return(0);
ragge
1.161
600         v1 = p->n_lval;
601         v2 = q->n_lval;
ragge
1.1
602         switcho ){
603
604         case PLUS:
ragge
1.22
605                 p->n_lval += val;
ragge
1.23
606                 if (p->n_sp == NULL) {
ragge
1.22
607                         p->n_rval = q->n_rval;
608                         p->n_type = q->n_type;
ragge
1.23
609                 }
ragge
1.1
610                 break;
611         case MINUS:
ragge
1.22
612                 p->n_lval -= val;
ragge
1.1
613                 break;
614         case MUL:
ragge
1.22
615                 p->n_lval *= val;
ragge
1.1
616                 break;
617         case DIV:
ragge
1.46
618                 if (val == 0)
619                         uerror("division by 0");
ragge
1.159
620                 else  {
621                         if (u) {
622                                 v1 /= v2;
623                                 p->n_lval = v1;
624                         } else
625                                 p->n_lval /= val;
626                 }
ragge
1.1
627                 break;
628         case MOD:
ragge
1.46
629                 if (val == 0)
630                         uerror("division by 0");
ragge
1.159
631                 else  {
632                         if (u) {
633                                 v1 %= v2;
634                                 p->n_lval = v1;
635                         } else
636                                 p->n_lval %= val;
637                 }
ragge
1.1
638                 break;
639         case AND:
ragge
1.22
640                 p->n_lval &= val;
ragge
1.1
641                 break;
642         case OR:
ragge
1.22
643                 p->n_lval |= val;
ragge
1.1
644                 break;
645         case ER:
ragge
1.22
646                 p->n_lval ^= val;
ragge
1.1
647                 break;
648         case LS:
649                 i = val;
ragge
1.22
650                 p->n_lval = p->n_lval << i;
ragge
1.1
651                 break;
652         case RS:
653                 i = val;
ragge
1.159
654                 if (u) {
655                         v1 = v1 >> i;
656                         p->n_lval = v1;
657                 } else
658                         p->n_lval = p->n_lval >> i;
ragge
1.1
659                 break;
660
ragge
1.94
661         case UMINUS:
ragge
1.22
662                 p->n_lval = - p->n_lval;
ragge
1.1
663                 break;
664         case COMPL:
ragge
1.22
665                 p->n_lval = ~p->n_lval;
ragge
1.1
666                 break;
667         case NOT:
ragge
1.22
668                 p->n_lval = !p->n_lval;
ragge
1.1
669                 break;
670         case LT:
ragge
1.22
671                 p->n_lval = p->n_lval < val;
ragge
1.1
672                 break;
673         case LE:
ragge
1.22
674                 p->n_lval = p->n_lval <= val;
ragge
1.1
675                 break;
676         case GT:
ragge
1.22
677                 p->n_lval = p->n_lval > val;
ragge
1.1
678                 break;
679         case GE:
ragge
1.22
680                 p->n_lval = p->n_lval >= val;
ragge
1.1
681                 break;
682         case ULT:
ragge
1.159
683                 p->n_lval = v1 < v2;
ragge
1.1
684                 break;
685         case ULE:
ragge
1.159
686                 p->n_lval = v1 <= v2;
ragge
1.1
687                 break;
688         case UGT:
ragge
1.159
689                 p->n_lval = v1 > v2;
ragge
1.1
690                 break;
691         case UGE:
ragge
1.159
692                 p->n_lval = v1 >= v2;
ragge
1.1
693                 break;
694         case EQ:
ragge
1.22
695                 p->n_lval = p->n_lval == val;
ragge
1.1
696                 break;
697         case NE:
ragge
1.22
698                 p->n_lval = p->n_lval != val;
ragge
1.1
699                 break;
ragge
1.155
700         case ANDAND:
701                 p->n_lval = p->n_lval && val;
702                 break;
ragge
1.154
703         case OROR:
704                 p->n_lval = p->n_lval || val;
705                 break;
ragge
1.1
706         default:
707                 return(0);
708                 }
709         return(1);
710         }
711
ragge
1.7
712 /*
713  * Checks p for the existance of a pun.  This is called when the op of p
714  * is ASSIGN, RETURN, CAST, COLON, or relational.
715  * One case is when enumerations are used: this applies only to lint.
716  * In the other case, one operand is a pointer, the other integer type
717  * we check that this integer is in fact a constant zero...
718  * in the case of ASSIGN, any assignment of pointer to integer is illegal
719  * this falls out, because the LHS is never 0.
720  */
ragge
1.2
721 void
ragge
1.7
722 chkpun(NODE *p)
723 {
ragge
1.29
724         union dimfun *d1, *d2;
ragge
1.2
725         NODE *q;
ragge
1.47
726         int t1t2;
ragge
1.1
727
ragge
1.22
728         t1 = p->n_left->n_type;
729         t2 = p->n_right->n_type;
ragge
1.1
730
ragge
1.56
731         switch (p->n_op) {
732         case RETURN:
733                 /* return of void allowed but nothing else */
ragge
1.52
734                 if (t1 == VOID && t2 == VOID)
735                         return;
ragge
1.163
736                 if (t1 == VOID) {
737                         werror("returning value from void function");
738                         return;
739                 }
740                 if (t2 == VOID) {
741                         uerror("using void value");
742                         return;
743                 }
ragge
1.56
744         case COLON:
745                 if (t1 == VOID && t2 == VOID)
746                         return;
747                 break;
748         default:
otto
1.165
749                 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
750                         uerror("value of void expression used");
751                         return;
752                 }
ragge
1.56
753                 break;
ragge
1.52
754         }
755
756         /* allow void pointer assignments in any direction */
757         if (BTYPE(t1) == VOID && (t2 & TMASK))
758                 return;
759         if (BTYPE(t2) == VOID && (t1 & TMASK))
760                 return;
761
ragge
1.7
762         /* check for enumerations */
ragge
1.166
763         if (t1 == ENUMTY || t2 == ENUMTY) {
764                 if (clogop(p->n_op) && p->n_op != EQ && p->n_op != NE) {
765                         werror("comparison of enums");
ragge
1.1
766                         return;
767                 }
ragge
1.166
768                 if (chkenum(t1t2p))
ragge
1.87
769                         return;
ragge
1.7
770         }
ragge
1.1
771
ragge
1.52
772         if (ISPTR(t1) || ISARY(t1))
773                 q = p->n_right;
774         else
775                 q = p->n_left;
ragge
1.1
776
ragge
1.52
777         if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
ragge
1.22
778                 if (q->n_op != ICON || q->n_lval != 0)
ragge
1.47
779                         werror("illegal combination of pointer and integer");
780         } else {
781                 d1 = p->n_left->n_df;
782                 d2 = p->n_right->n_df;
ragge
1.52
783                 if (t1 == t2) {
784                         if (p->n_left->n_sue != p->n_right->n_sue)
785                                 werror("illegal structure pointer combination");
786                         return;
787                 }
ragge
1.47
788                 for (;;) {
ragge
1.52
789                         if (ISARY(t1) || ISPTR(t1)) {
790                                 if (!ISARY(t2) && !ISPTR(t2))
791                                         break;
ragge
1.47
792                                 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
793                                         werror("illegal array size combination");
794                                         return;
795                                 }
ragge
1.52
796                                 if (ISARY(t1))
797                                         ++d1;
798                                 if (ISARY(t2))
799                                         ++d2;
ragge
1.47
800                         } else if (ISFTN(t1)) {
801                                 if (chkftn(d1->dfund2->dfun)) {
802                                         werror("illegal function "
803                                             "pointer combination");
804                                         return;
805                                 }
806                                 ++d1;
807                                 ++d2;
ragge
1.166
808                         } else if (t1 == ENUMTY || t2 == ENUMTY) {
809                                 chkenum(t1t2p);
810                                 return;
ragge
1.52
811                         } else
812                                 break;
ragge
1.47
813                         t1 = DECREF(t1);
814                         t2 = DECREF(t2);
815                 }
816                 werror("illegal pointer combination");
ragge
1.1
817         }
ragge
1.5
818 }
ragge
1.1
819
ragge
1.166
820 static int
821 chkenum(int t1int t2NODE *p)
822 {
823         if (t1 == ENUMTY && t2 == ENUMTY) {
824                 if (p->n_left->n_sue != p->n_right->n_sue)
825                 werror("enumeration type clash, operator %s"copst(p->n_op));
826                         return 1;
827         }
828         if ((t1 == ENUMTY && !(t2 >= CHAR && t2 <= UNSIGNED)) ||
829             (t2 == ENUMTY && !(t1 >= CHAR && t1 <= UNSIGNED))) {
830                 werror("illegal combination of enum and non-integer type");
831                 return 1;
832         }
833         return 0;
834 }
835
ragge
1.1
836 NODE *
ragge
1.10
837 stref(NODE *p)
838 {
ragge
1.41
839         NODE *r;
ragge
1.26
840         struct suedef *sue;
ragge
1.29
841         union dimfun *d;
ragge
1.68
842         TWORD tq;
ragge
1.49
843         int dsc;
ragge
1.1
844         OFFSZ off;
ragge
1.68
845         struct symtab *s;
ragge
1.1
846
847         /* make p->x */
848         /* this is also used to reference automatic variables */
849
ragge
1.68
850         s = p->n_right->n_sp;
ragge
1.41
851         nfree(p->n_right);
852         r = p->n_left;
853         nfree(p);
854         p = pconvert(r);
ragge
1.1
855
856         /* make p look like ptr to x */
857
ragge
1.22
858         if (!ISPTR(p->n_type))
859                 p->n_type = PTR+UNIONTY;
ragge
1.1
860
ragge
1.68
861         t = INCREF(s->stype);
862         q = INCQAL(s->squal);
863         d = s->sdf;
864         sue = s->ssue;
ragge
1.1
865
ragge
1.68
866         p = makety(ptqdsue);
ragge
1.1
867
868         /* compute the offset to be added */
869
ragge
1.68
870         off = s->soffset;
871         dsc = s