Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030706210146

Diff

Diff from 1.44 to:

Annotations

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

Annotated File View

ragge
1.1
1 # include "pass1.h"
ragge
1.9
2 # include "pass2.h"     /* for NOPREF */
ragge
1.1
3
4 # include <setjmp.h>
ragge
1.16
5 # include <stdarg.h>
6 # include <string.h>
ragge
1.1
7
ragge
1.30
8 int adebug = 0/* XXX 4.4 */
9 extern int ddebug;      /* XXX 4.4 */
ragge
1.1
10
ragge
1.2
11 void chkpun(NODE *p);
12 int opact(NODE *p);
13 int moditype(TWORD);
14
15 /* corrections when in violation of lint */
ragge
1.1
16
17 /*      some special actions, used in finding the type of nodes */
18 # define NCVT 01
19 # define PUN 02
20 # define TYPL 04
21 # define TYPR 010
22 # define TYMATCH 040
23 # define LVAL 0100
24 # define CVTO 0200
25 # define CVTL 0400
26 # define CVTR 01000
27 # define PTMATCH 02000
28 # define OTHER 04000
29 # define NCVTR 010000
30
ragge
1.34
31 #ifdef PCC_DEBUG
ragge
1.2
32 static void
ragge
1.30
33 printact(NODE *tint acts)     /* XXX 4.4  hela printact */
ragge
1.1
34 {
35         static struct actions {
36                 int     a_bit;
37                 char    *a_name;
38         } actions[] = {
39                 { PUN,          "PUN" },
40                 { CVTL,         "CVTL" },
41                 { CVTR,         "CVTR" },
42                 { TYPL,         "TYPL" },
43                 { TYPR,         "TYPR" },
44                 { TYMATCH,      "TYMATCH" },
45                 { PTMATCH,      "PTMATCH" },
46                 { LVAL,         "LVAL" },
47                 { CVTO,         "CVTO" },
48                 { NCVT,         "NCVT" },
49                 { OTHER,        "OTHER" },
50                 { NCVTR,        "NCVTR" },
51                 { 0 }
52         };
53         register struct actions *p;
54         char *sep = " ";
55
56         printf("actions");
57         for (p = actionsp->a_namep++)
58                 if (p->a_bit & acts) {
59                         printf("%s%s"sepp->a_name);
60                         sep = "|";
61                 }
62         if (!bdebug) {
63                 printf(" for:\n");
64                 fwalk(teprint0);
65         } else
66                 putchar('\n');
67 }
68 #endif
69
70 /* node conventions:
71
72         NAME:   rval>0 is stab index for external
73                 rval<0 is -inlabel number
74                 lval is offset in bits
75         ICON:   lval has the value
76                 rval has the STAB index, or - label number,
77                         if a name whose address is in the constant
78                 rval = NONAME means no name
79         REG:    rval is reg. identification cookie
80
81         */
82
ragge
1.30
83 int bdebug = 0;
84
ragge
1.1
85 NODE *
ragge
1.2
86 buildtree(int oNODE *lNODE *r)
87 {
88         NODE *p, *q;
89         int actions;
90         int opty;
91         struct symtab *sp;
92         NODE *lr, *ll;
ragge
1.23
93         char *name;
ragge
1.26
94         struct symtab **elem;
ragge
1.1
95
96 # ifndef BUG1
ragge
1.2
97         if (bdebug)
98                 printf("buildtree(%s, %p, %p)\n"opst[o], lr);
ragge
1.1
99 # endif
100         opty = optype(o);
101
102         /* check for constants */
103
ragge
1.22
104         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
105
106                 switcho ){
107
108                 case NOT:
109                 case UNARY MINUS:
110                 case COMPL:
111                         ifconvallol ) ) return(l);
112                         break;
113
114                 }
ragge
1.44
115         } else ifo == UNARY MINUS && l->n_op == FCON ){
116                         ifl->n_type == FLOAT )
ragge
1.22
117                                 l->n_fcon = -l->n_fcon;
ragge
1.1
118                         else
ragge
1.22
119                                 l->n_dcon = -l->n_dcon;
ragge
1.1
120                         return(l);
121
ragge
1.44
122         } else ifo==QUEST && l->n_op==ICON ) {
ragge
1.41
123                 CONSZ c = l->n_lval;
124                 nfree(l);
125                 if (c) {
126                         tfree(r->n_right);
127                         l = r->n_left;
128                         nfree(r);
129                         return(l);
130                 } else {
131                         tfree(r->n_left);
132                         l = r->n_right;
133                         nfree(r);
134                         return(l);
ragge
1.1
135                 }
ragge
1.44
136         } else if( (o==ANDAND || o==OROR) && (l->n_op==ICON||r->n_op==ICON) )
137                 goto ccwarn;
ragge
1.1
138
ragge
1.22
139         else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
140
141                 switcho ){
142
143                 case ULT:
144                 case UGT:
145                 case ULE:
146                 case UGE:
147                 case LT:
148                 case GT:
149                 case LE:
150                 case GE:
151                 case EQ:
ragge
1.30
152                 case NE:        /* XXX 4.4 nedanstanende sats */
ragge
1.22
153                         ifl->n_type == ENUMTY && r->n_type == ENUMTY ){
ragge
1.26
154                                 p = block(olrINT0MKSUE(INT));
ragge
1.1
155                                 chkpunp );
ragge
1.41
156                                 nfree(p);
157                         }
ragge
1.1
158
159                 case ANDAND:
160                 case OROR:
161                 case CBRANCH:
162
163                 ccwarn:
164
165                 case PLUS:
166                 case MINUS:
167                 case MUL:
168                 case DIV:
169                 case MOD:
170                 case AND:
171                 case OR:
172                 case ER:
173                 case LS:
174                 case RS:
175                         ifconvallor ) ) {
ragge
1.41
176                                 nfree(r);
ragge
1.1
177                                 return(l);
ragge
1.44
178                         }
ragge
1.1
179                         break;
180                 }
ragge
1.44
181         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
182             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
183             o == MUL || o == DIV)) {
184                 switch(o){
185                 case PLUS:
186                 case MINUS:
187                 case MUL:
188                 case DIV:
189                         if (l->n_op == ICON)
190                                 l->n_dcon = l->n_lval;
191                         else if (l->n_type == FLOAT)
192                                 l->n_dcon = l->n_fcon;
193                         if (r->n_op == ICON)
194                                 r->n_dcon = r->n_lval;
195                         else if (r->n_type == FLOAT)
196                                 r->n_dcon = r->n_fcon;
197                         switch (o) {
198                         case PLUS:
199                                 l->n_dcon += r->n_dconbreak;
200                         case MINUS:
201                                 l->n_dcon -= r->n_dconbreak;
202                         case MUL:
203                                 l->n_dcon *= r->n_dconbreak;
204                         case DIV:
205                                 if (r->n_dcon == 0)
206                                         uerror("division by 0.");
207                                 else
208                                         l->n_dcon /= r->n_dcon;
209                         }
210                         l->n_op = FCON;
211                         l->n_type = DOUBLE;
212                         l->n_sue = MKSUE(DOUBLE);
213                         nfree(r);
214                         return(l);
ragge
1.1
215                 }
ragge
1.44
216         }
ragge
1.1
217
ragge
1.30
218         /* its real; we must make a new node */
ragge
1.1
219
ragge
1.26
220         p = block(olrINT0MKSUE(INT));
ragge
1.1
221
222         actions = opact(p);
ragge
1.35
223 #ifdef PCC_DEBUG
ragge
1.30
224         if (adebug)     /* XXX 4.4 */
ragge
1.1
225                 printact(pactions);
226 #endif
227
228         ifactions&LVAL ){ /* check left descendent */
ragge
1.22
229                 ifnotlval(p->n_left) ) {
ragge
1.30
230                         uerror"lvalue required" );
ragge
1.1
231                         }
232                 }
233
234         ifactions & NCVTR ){
ragge
1.22
235                 p->n_left = pconvertp->n_left );
ragge
1.1
236                 }
237         else if( !(actions & NCVT ) ){
238                 switchopty ){
239
240                 case BITYPE:
ragge
1.22
241                         p->n_right = pconvertp->n_right );
ragge
1.1
242                 case UTYPE:
ragge
1.22
243                         p->n_left = pconvertp->n_left );
ragge
1.1
244
245                         }
246                 }
247
ragge
1.7
248         if ((actions&PUN) && (o!=CAST||cflag))
ragge
1.1
249                 chkpun(p);
250
251         ifactions & (TYPL|TYPR) ){
252
ragge
1.22
253                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
254
ragge
1.22
255                 p->n_type = q->n_type;
ragge
1.29
256                 p->n_df = q->n_df;
ragge
1.26
257                 p->n_sue = q->n_sue;
ragge
1.1
258                 }
259
260         ifactions & CVTL ) p = convertpCVTL );
261         ifactions & CVTR ) p = convertpCVTR );
262         ifactions & TYMATCH ) p = tymatch(p);
263         ifactions & PTMATCH ) p = ptmatch(p);
264
265         ifactions & OTHER ){
ragge
1.22
266                 l = p->n_left;
267                 r = p->n_right;
ragge
1.1
268
269                 switch(o){
270
271                 case NAME:
ragge
1.23
272                         sp = spname;
273                         if (sp->stype == UNDEF) {
274                                 uerror("%s undefined"sp->sname);
ragge
1.1
275                                 /* make p look reasonable */
ragge
1.26
276                                 p->n_type = INT;
277                                 p->n_sue = MKSUE(INT);
ragge
1.29
278                                 p->n_df = NULL;
ragge
1.23
279                                 p->n_sp = sp;
ragge
1.22
280                                 p->n_lval = 0;
ragge
1.23
281                                 defid(pSNULL);
ragge
1.1
282                                 break;
ragge
1.23
283                         }
ragge
1.22
284                         p->n_type = sp->stype;
ragge
1.29
285                         p->n_df = sp->sdf;
ragge
1.26
286                         p->n_sue = sp->ssue;
ragge
1.22
287                         p->n_lval = 0;
ragge
1.23
288                         p->n_sp = sp;
ragge
1.1
289                         /* special case: MOETY is really an ICON... */
ragge
1.23
290                         if (p->n_type == MOETY) {
291                                 p->n_sp = NULL;
292                                 p->n_lval = sp->soffset;
ragge
1.29
293                                 p->n_df = NULL;
ragge
1.22
294                                 p->n_type = ENUMTY;
295                                 p->n_op = ICON;
ragge
1.23
296                         }
ragge
1.1
297                         break;
298
299                 case STRING:
ragge
1.22
300                         p->n_op = NAME;
ragge
1.17
301 #ifdef CHAR_UNSIGNED
ragge
1.22
302                         p->n_type = UCHAR+ARY;
ragge
1.26
303                         p->n_sue = MKSUE(UCHAR);
ragge
1.17
304 #else
ragge
1.22
305                         p->n_type = CHAR+ARY;
ragge
1.26
306                         p->n_sue = MKSUE(CHAR);
ragge
1.17
307 #endif
ragge
1.22
308                         p->n_lval = 0;
ragge
1.23
309                         p->n_sp = NULL;
ragge
1.1
310                         break;
311
312                 case STREF:
313                         /* p->x turned into *(p+offset) */
314                         /* rhs must be a name; check correctness */
315
ragge
1.23
316                         /* Find member symbol struct */
317                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
318                                 uerror("struct or union required");
319                                 break;
320                         }
321
ragge
1.26
322                         if ((elem = l->n_sue->suelem) == NULL)
ragge
1.23
323                                 uerror("undefined struct or union");
324
325                         name = r->n_name;
ragge
1.26
326                         for (; *elem != NULLelem++) {
327                                 sp = *elem;
ragge
1.23
328                                 if (sp->sname == name)
329                                         break;
330                         }
ragge
1.26
331                         if (*elem == NULL)
ragge
1.23
332                                 uerror("member '%s' not declared"name);
333
334                         r->n_sp = sp;
335                         p = stref(p);
336                         break;
337
ragge
1.1
338                 case UNARY MUL:
ragge
1.41
339                         if (l->n_op == UNARY AND) {
340                                 nfree(p);
ragge
1.22
341                                 p = l->n_left;
ragge
1.41
342                                 nfree(l);
343                         }
ragge
1.22
344                         if( !ISPTR(l->n_type))uerror("illegal indirection");
345                         p->n_type = DECREF(l->n_type);
ragge
1.29
346                         p->n_df = l->n_df;
ragge
1.26
347                         p->n_sue = l->n_sue;
ragge
1.1
348                         break;
349
350                 case UNARY AND:
ragge
1.22
351                         switchl->n_op ){
ragge
1.1
352
353                         case UNARY MUL:
ragge
1.41
354                                 nfree(p);
ragge
1.22
355                                 p = l->n_left;
ragge
1.41
356                                 nfree(l);
ragge
1.1
357                         case NAME:
ragge
1.22
358                                 p->n_type = INCREFl->n_type );
ragge
1.29
359                                 p->n_df = l->n_df;
ragge
1.26
360                                 p->n_sue = l->n_sue;
ragge
1.1
361                                 break;
362
363                         case COMOP:
ragge
1.41
364                                 nfree(p);
ragge
1.22
365                                 lr = buildtreeUNARY ANDl->n_rightNIL );
366                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.41
367                                 nfree(l);
ragge
1.1
368                                 break;
369
370                         case QUEST:
ragge
1.22
371                                 lr = buildtreeUNARY ANDl->n_right->n_rightNIL );
372                                 ll = buildtreeUNARY ANDl->n_right->n_leftNIL );
ragge
1.41
373                                 nfree(p); nfree(l->n_right);
ragge
1.22
374                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.41
375                                 nfree(l);
ragge
1.1
376                                 break;
377
ragge
1.30
378 # ifdef ADDROREG        /* XXX 4.4  addroreg */
ragge
1.1
379                         case OREG:
380                                 /* OREG was built in clocal()
381                                  * for an auto or formal parameter
382                                  * now its address is being taken
383                                  * local code must unwind it
384                                  * back to PLUS/MINUS REG ICON
385                                  * according to local conventions
386                                  */
ragge
1.41
387                                 nfree(p);
ragge
1.1
388                                 p = addroregl );
389                                 break;
390
391 # endif
392                         default:
ragge
1.22
393                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
394                                 break;
395                                 }
396                         break;
397
398                 case LS:
ragge
1.30
399                 case RS:        /* XXX 4.4 satsen */
ragge
1.22
400                         ifl->n_type == CHAR || l->n_type == SHORT )
401                                 p->n_type = INT;
402                         else ifl->n_type == UCHAR || l->n_type == USHORT )
403                                 p->n_type = UNSIGNED;
ragge
1.1
404                         else
ragge
1.22
405                                 p->n_type = l->n_type;
ragge
1.1
406                 case ASG LS:
407                 case ASG RS:
ragge
1.22
408                         ifr->n_type != INT )
ragge
1.26
409                                 p->n_right = r = makety(rINT0MKSUE(INT));
ragge
1.1
410                         break;
411
412                 case RETURN:
413                 case ASSIGN:
414                 case CAST:
415                         /* structure assignment */
416                         /* take the addresses of the two sides; then make an
ragge
1.2
417                          * operator using STASG and
418                          * the addresses of left and right */
ragge
1.1
419
420                         {
ragge
1.26
421                                 struct suedef *sue;
ragge
1.2
422                                 TWORD t;
ragge
1.29
423                                 union dimfun *d;
ragge
1.1
424
ragge
1.26
425                                 if (l->n_sue != r->n_sue)
426                                         uerror("assignment of different structures");
ragge
1.1
427
ragge
1.26
428                                 r = buildtree(UNARY ANDrNIL);
ragge
1.22
429                                 t = r->n_type;
ragge
1.29
430                                 d = r->n_df;
ragge
1.26
431                                 sue = r->n_sue;
ragge
1.1
432
ragge
1.28
433                                 l = block(STASGlrtdsue);
ragge
1.1
434
435                                 ifo == RETURN ){
ragge
1.41
436                                         nfree(p);
ragge
1.1
437                                         p = l;
438                                         break;
ragge
1.28
439                                 }
ragge
1.1
440
ragge
1.22
441                                 p->n_op = UNARY MUL;
442                                 p->n_left = l;
443                                 p->n_right = NIL;
ragge
1.1
444                                 break;
445                                 }
446                 case COLON:
447                         /* structure colon */
448
ragge
1.26
449                         if (l->n_sue != r->n_sue)
450                                 uerror"type clash in conditional" );
ragge
1.1
451                         break;
452
453                 case CALL:
ragge
1.23
454                         p->n_right = r = fixargs(p->n_right);
ragge
1.1
455                 case UNARY CALL:
ragge
1.23
456                         if (!ISPTR(l->n_type))
457                                 uerror("illegal function");
ragge
1.22
458                         p->n_type = DECREF(l->n_type);
ragge
1.23
459                         if (!ISFTN(p->n_type))
460                                 uerror("illegal function");
461                         p->n_type = DECREF(p->n_type);
ragge
1.29
462                         p->n_df = l->n_df;
ragge
1.26
463                         p->n_sue = l->n_sue;
ragge
1.23
464                         if (l->n_op == UNARY AND && l->n_left->n_op == NAME &&
465                             l->n_left->n_sp != NULL && l->n_left->n_sp != NULL &&
466                             (l->n_left->n_sp->sclass == FORTRAN ||
467                             l->n_left->n_sp->sclass == UFORTRAN)) {
ragge
1.22
468                                 p->n_op += (FORTCALL-CALL);
ragge
1.23
469                         }
470                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
471                                 /* function returning structure */
472                                 /*  make function really return ptr to str., with * */
473
ragge
1.22
474                                 p->n_op += STCALL-CALL;
ragge
1.23
475                                 p->n_type = INCREF(p->n_type);
476                                 p = buildtree(UNARY MULpNIL);
ragge
1.1
477
478                                 }
479                         break;
480
481                 default:
482                         cerror"other code %d"o );
483                         }
484
485                 }
486
ragge
1.11
487         /*
488          * Allow (void)0 casts.
489          * XXX - anything on the right side must be possible to cast.
490          * XXX - remove void types further on.
491          */
ragge
1.22
492         if (p->n_op == CAST && p->n_type == UNDEF &&
493             p->n_right->n_op == ICON)
494                 p->n_right->n_type = UNDEF;
ragge
1.11
495
ragge
1.1
496         ifactions & CVTO ) p = oconvert(p);
497         p = clocal(p);
498
ragge
1.30
499 #ifdef PCC_DEBUG
ragge
1.1
500         ifbdebug ) fwalkpeprint0 );
ragge
1.30
501 #endif
ragge
1.1
502
503         return(p);
504
505         }
506
ragge
1.30
507 /*      * XXX 4.4 comments *
ragge
1.1
508  * Rewrite arguments in a function call.
509  * Structure arguments are massaged, single
510  * precision floating point constants are
511  * cast to double (to eliminate convert code).
512  */
513 NODE *
514 fixargsp ) register NODE *p;  {
ragge
1.22
515         int o = p->n_op;
ragge
1.1
516
517         ifo == CM ){
ragge
1.22
518                 p->n_left = fixargsp->n_left );
519                 p->n_right = fixargsp->n_right );
ragge
1.1
520                 returnp );
521                 }
522
ragge
1.22
523         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.29
524                 p = block(STARGpNILp->n_typep->n_dfp->n_sue);
ragge
1.22
525                 p->n_left = buildtreeUNARY ANDp->n_leftNIL );
ragge
1.1
526                 p = clocal(p);
527                 }
ragge
1.30
528         else ifo == FCON )    /* XXX 4.4 */
ragge
1.1
529                 p = makety(pDOUBLE00);
530         returnp );
ragge
1.2
531 }
ragge
1.1
532
ragge
1.2
533 /*
534  * apply the op o to the lval part of p; if binary, rhs is val
535  */
536 int
537 conval(NODE *pint oNODE *q)
538 {
ragge
1.1
539         int iu;
540         CONSZ val;
ragge
1.30
541         TWORD utype;    /* XXX 4.4 */
ragge
1.1
542
ragge
1.22
543         val = q->n_lval;
544         u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
ragge
1.1
545         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
546
ragge
1.23
547         if (p->n_sp != NULL && q->n_sp != NULL)
548                 return(0);
549         if (q->n_sp != NULL && o != PLUS)
550                 return(0);
551         if (p->n_sp != NULL && o != PLUS && o != MINUS)
552                 return(0);
ragge
1.1
553
ragge
1.30
554                 /* XXX 4.4 följande stycke */
ragge
1.1
555         /* usual type conversions -- handle casts of constants */
556 #define ISLONG(t)       ((t) == LONG || (t) == ULONG)
ragge
1.6
557 #define ISLONGLONG(t)   ((t) == LONGLONG || (t) == ULONGLONG)
ragge
1.22
558         if (ISLONG(p->n_type) || ISLONG(q->n_type))
ragge
1.1
559                 utype = u ? ULONG : LONG;
ragge
1.22
560         else if (ISLONGLONG(p->n_type) || ISLONGLONG(q->n_type))
ragge
1.6
561                 utype = u ? ULONGLONG : LONGLONG;
ragge
1.1
562         else
563                 utype = u ? UNSIGNED : INT;
ragge
1.22
564         if( !ISPTR(p->n_type) && p->n_type != utype )
ragge
1.26
565                 p = makety(putype0MKSUE(utype));
ragge
1.22
566         ifq->n_type != utype )
ragge
1.26
567                 q = makety(qutype0MKSUE(utype));
ragge
1.1
568
569         switcho ){
570
571         case PLUS:
ragge
1.22
572                 p->n_lval += val;
ragge
1.23
573                 if (p->n_sp == NULL) {
ragge
1.22
574                         p->n_rval = q->n_rval;
575                         p->n_type = q->n_type;
ragge
1.23
576                 }
ragge
1.1
577                 break;
578         case MINUS:
ragge
1.22
579                 p->n_lval -= val;
ragge
1.1
580                 break;
581         case MUL:
ragge
1.22
582                 p->n_lval *= val;
ragge
1.1
583                 break;
584         case DIV:
585                 ifval == 0 ) uerror"division by 0" );
ragge
1.30
586                 else if ( u ) p->n_lval = (unsignedp->n_lval / val;   /* XXX 4.4 */
ragge
1.22
587                 else p->n_lval /= val;
ragge
1.1
588                 break;
589         case MOD:
590                 ifval == 0 ) uerror"division by 0" );
ragge
1.30
591                 else if ( u ) p->n_lval = (unsignedp->n_lval % val;   /* XXX 4.4 */
ragge
1.22
592                 else p->n_lval %= val;
ragge
1.1
593                 break;
594         case AND:
ragge
1.22
595                 p->n_lval &= val;
ragge
1.1
596                 break;
597         case OR:
ragge
1.22
598                 p->n_lval |= val;
ragge
1.1
599                 break;
600         case ER:
ragge
1.22
601                 p->n_lval ^= val;
ragge
1.1
602                 break;
603         case LS:
604                 i = val;
ragge
1.22
605                 p->n_lval = p->n_lval << i;
ragge
1.1
606                 break;
607         case RS:
608                 i = val;
ragge
1.30
609                 if ( u ) p->n_lval = (unsignedp->n_lval >> i/* XXX 4.4 */
ragge
1.22
610                 else p->n_lval = p->n_lval >> i;
ragge
1.1
611                 break;
612
613         case UNARY MINUS:
ragge
1.22
614                 p->n_lval = - p->n_lval;
ragge
1.1
615                 break;
616         case COMPL:
ragge
1.22
617                 p->n_lval = ~p->n_lval;
ragge
1.1
618                 break;
619         case NOT:
ragge
1.22
620                 p->n_lval = !p->n_lval;
ragge
1.1
621                 break;
622         case LT:
ragge
1.22
623                 p->n_lval = p->n_lval < val;
ragge
1.1
624                 break;
625         case LE:
ragge
1.22
626                 p->n_lval = p->n_lval <= val;
ragge
1.1
627                 break;
628         case GT:
ragge
1.22
629                 p->n_lval = p->n_lval > val;
ragge
1.1
630                 break;
631         case GE:
ragge
1.22
632                 p->n_lval = p->n_lval >= val;
ragge
1.1
633                 break;
634         case ULT:
ragge
1.22
635                 p->n_lval = p->n_lval < (unsignedval;
ragge
1.1
636                 break;
637         case ULE:
ragge
1.22
638                 p->n_lval = p->n_lval <= (unsignedval;
ragge
1.1
639                 break;
640         case UGT:
ragge
1.22
641                 p->n_lval = p->n_lval > (unsignedval;
ragge
1.1
642                 break;
643         case UGE:
ragge
1.22
644                 p->n_lval = p->n_lval >= (unsignedval;
ragge
1.1
645                 break;
646         case EQ:
ragge
1.22
647                 p->n_lval = p->n_lval == val;
ragge
1.1
648                 break;
649         case NE:
ragge
1.22
650                 p->n_lval = p->n_lval != val;
ragge
1.1
651                 break;
652         default:
653                 return(0);
654                 }
655         return(1);
656         }
657
ragge
1.7
658 /*
659  * Checks p for the existance of a pun.  This is called when the op of p
660  * is ASSIGN, RETURN, CAST, COLON, or relational.
661  * One case is when enumerations are used: this applies only to lint.
662  * In the other case, one operand is a pointer, the other integer type
663  * we check that this integer is in fact a constant zero...
664  * in the case of ASSIGN, any assignment of pointer to integer is illegal
665  * this falls out, because the LHS is never 0.
666  */
ragge
1.2
667 void
ragge
1.7
668 chkpun(NODE *p)
669 {
ragge
1.29
670         union dimfun *d1, *d2;
ragge
1.2
671         NODE *q;
ragge
1.29
672         int t1t2ref1ref2;
ragge
1.1
673
ragge
1.22
674         t1 = p->n_left->n_type;
675         t2 = p->n_right->n_type;
ragge
1.1
676
ragge
1.7
677         /* check for enumerations */
678         if (t1==ENUMTY || t2==ENUMTY) {
ragge
1.1
679                 /* rob pike says this is obnoxious...
ragge
1.22
680                 if( logop( p->n_op ) && p->n_op != EQ && p->n_op != NE )
ragge
1.30
681                         werror( "comparison of enums" ); */     /* XXX 4.4 */
ragge
1.7
682                 if (t1==ENUMTY && t2==ENUMTY) {
ragge
1.26
683                         if (p->n_left->n_sue!=p->n_right->n_sue)
ragge
1.7
684                                 werror("enumeration type clash, "
ragge
1.30
685                                     "operator %s"opst[p->n_op]);      /* XXX 4.4 */
ragge
1.1
686                         return;
687                 }
ragge
1.7
688                 if (t1 == ENUMTY)
689                         t1 = INT;
690                 if (t2 == ENUMTY)
691                         t2 = INT;
692         }
ragge
1.1
693
694         ref1 = ISPTR(t1) || ISARY(t1);
695         ref2 = ISPTR(t2) || ISARY(t2);
696
ragge
1.30
697         if (ref1 ^ ref2) {      /* XXX 4.4 */
ragge
1.7
698                 if (ref1)
ragge
1.22
699                         q = p->n_right;
ragge
1.7
700                 else
ragge
1.22
701                         q = p->n_left;
702                 if (q->n_op != ICON || q->n_lval != 0)
ragge
1.7
703                         werror("illegal combination of pointer "
ragge
1.22
704                             "and integer, op %s"opst[p->n_op]);
ragge
1.30
705         } else if (ref1) {      /* XXX 4.4 */
ragge
1.7
706                 if (t1 == t2) {
ragge
1.26
707                         if (p->n_left->n_sue != p->n_right->n_sue) {
ragge
1.5
708                                 werror("illegal structure pointer combination");
ragge
1.1
709                                 return;
ragge
1.5
710                         }
ragge
1.29
711                         d1 = p->n_left->n_df;
712                         d2 = p->n_right->n_df;
ragge
1.7
713                         for (;;) {
714                                 if (ISARY(t1)) {
ragge
1.29
715                                         if (d1->ddim != d2->ddim) {
ragge
1.7
716                                                 werror("illegal array "
717                                                     "size combination");
ragge
1.1
718                                                 return;
ragge
1.5
719                                         }
ragge
1.1
720                                         ++d1;
721                                         ++d2;
ragge
1.29
722                                 } else if (ISFTN(t1)) {
ragge
1.32
723                                         if (chkftn(d1->dfund2->dfun)) {
724                                                 werror("illegal function "
725                                                     "pointer combination");
ragge
1.29
726                                                 return;
727                                         }
728                                         ++d1;
729                                         ++d2;
ragge
1.5
730                                 } else
ragge
1.7
731                                         if (!ISPTR(t1))
ragge
1.5
732                                                 break;
ragge
1.1
733                                 t1 = DECREF(t1);
734                         }
ragge
1.30
735                 } else if (t1 != INCREF(UNDEF) && t2 != INCREF(UNDEF))  /* XXX 4.4 */
ragge
1.7
736                         werror("illegal pointer combination");
ragge
1.1
737         }
ragge
1.5
738 }
ragge
1.1
739
740 NODE *
ragge
1.10
741 stref(NODE *p)
742 {
ragge
1.41
743         NODE *r;
ragge
1.26
744         struct suedef *sue;
ragge
1.29
745         union dimfun *d;
ragge
1.1
746         TWORD t;
ragge
1.30
747         int dscalign/* XXX 4.4 */
ragge
1.1
748         OFFSZ off;
749         register struct symtab *q;
750
751         /* make p->x */
752         /* this is also used to reference automatic variables */
753
ragge
1.23
754         q = p->n_right->n_sp;
ragge
1.41
755         nfree(p->n_right);
756         r = p->n_left;
757         nfree(p);
758         p = pconvert(r);
ragge
1.1
759
760         /* make p look like ptr to x */
761
ragge
1.22
762         if (!ISPTR(p->n_type))
763                 p->n_type = PTR+UNIONTY;
ragge
1.1
764
ragge
1.10
765         t = INCREF(q->stype);
ragge
1.29
766         d = q->sdf;
ragge
1.26
767         sue = q->ssue;
ragge
1.1
768
ragge
1.26
769         p = makety(ptdsue);
ragge
1.1
770
771         /* compute the offset to be added */
772
ragge
1.23
773         off = q->soffset;
ragge
1.1
774         dsc = q->sclass;
775
ragge
1.10
776         if (dsc & FIELD) {  /* normalize offset */
ragge
1.30
777                 align = ALINT;  /* XXX 4.4 */
ragge
1.26
778                 sue = MKSUE(INT);
ragge
1.30
779                 off = (off/align)*align;        /* XXX 4.4 */
ragge
1.10
780         }
781         if (off != 0)
ragge
1.26
782                 p = clocal(block(PLUSpoffcon(offtdsue), tdsue));
ragge
1.1
783
ragge
1.10
784         p = buildtree(UNARY MULpNIL);
ragge
1.1
785
786         /* if field, build field info */
787
ragge
1.10
788         if (dsc & FIELD) {
ragge
1.26
789                 p = block(FLDpNILq->stype0q->ssue);
ragge
1.23
790                 p->n_rval = PKFIELD(dsc&FLDSIZq->soffset%align);
ragge
1.10
791         }
ragge
1.1
792
ragge
1.19
793         p = clocal(p);
794         return p;
ragge
1.10
795 }
ragge
1.1
796
ragge
1.2
797 int
ragge
1.1
798 notlval(pregister NODE *p; {
799
800         /* return 0 if p an lvalue, 1 otherwise */
801
802         again:
803
ragge
1.22
804         switchp->n_op ){
ragge
1.1
805
806         case FLD:
ragge
1.22
807                 p = p->n_left;
ragge
1.1
808                 goto again;
809
ragge
1.30
810         case UNARY MUL/* XXX 4.4 */
ragge
1.1
811                 /* fix the &(a=b) bug, given that a and b are structures */
ragge
1.22
812                 ifp->n_left->n_op == STASG ) return1 );
ragge
1.1
813                 /* and the f().a bug, given that f returns a structure */
ragge
1.22
814                 ifp->n_left->n_op == UNARY STCALL ||
815                     p->n_left->n_op == STCALL ) return1 );
ragge
1.1
816         case NAME:
817         case OREG:
ragge
1.22
818                 ifISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
ragge
1.1
819         case REG:
820                 return(0);
821
822         default:
823                 return(1);
824
825                 }
826
827         }
ragge
1.23
828 /* make a constant node with value i */
ragge
1.1
829 NODE *
ragge
1.23
830 bcon(int i)
831 {
ragge
1.1
832         register NODE *p;
833
ragge
1.26
834