Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:otto:20071004054541

Diff

Diff from 1.165 to:

Annotations

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

Annotated File View

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