Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030401202622

Diff

Diff from 1.19 to:

Annotations

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

Annotated File View

ragge
1.2
1 #if 0
ragge
1.1
2 static char *sccsid ="@(#)trees.c       4.37 (Berkeley) 6/18/90";
3 #endif
4
5 # include "pass1.h"
ragge
1.9
6 # include "pass2.h"     /* for NOPREF */
ragge
1.1
7
8 # include <setjmp.h>
ragge
1.16
9 # include <stdarg.h>
10 # include <string.h>
ragge
1.1
11
12 int bdebug = 0;
13 int adebug = 0;
ragge
1.2
14 extern int ddebug;
ragge
1.1
15
ragge
1.2
16 void chkpun(NODE *p);
17 int opact(NODE *p);
18 int chkstr(intintTWORD);
19 int moditype(TWORD);
ragge
1.16
20 static void to_pass2(NODE *p);
ragge
1.2
21
22 /* corrections when in violation of lint */
ragge
1.1
23
24 /*      some special actions, used in finding the type of nodes */
25 # define NCVT 01
26 # define PUN 02
27 # define TYPL 04
28 # define TYPR 010
29 # define TYMATCH 040
30 # define LVAL 0100
31 # define CVTO 0200
32 # define CVTL 0400
33 # define CVTR 01000
34 # define PTMATCH 02000
35 # define OTHER 04000
36 # define NCVTR 010000
37
38 #ifndef BUG1
ragge
1.2
39 static void
40 printact(NODE *tint acts)
ragge
1.1
41 {
42         static struct actions {
43                 int     a_bit;
44                 char    *a_name;
45         } actions[] = {
46                 { PUN,          "PUN" },
47                 { CVTL,         "CVTL" },
48                 { CVTR,         "CVTR" },
49                 { TYPL,         "TYPL" },
50                 { TYPR,         "TYPR" },
51                 { TYMATCH,      "TYMATCH" },
52                 { PTMATCH,      "PTMATCH" },
53                 { LVAL,         "LVAL" },
54                 { CVTO,         "CVTO" },
55                 { NCVT,         "NCVT" },
56                 { OTHER,        "OTHER" },
57                 { NCVTR,        "NCVTR" },
58                 { 0 }
59         };
60         register struct actions *p;
61         char *sep = " ";
62
63         printf("actions");
64         for (p = actionsp->a_namep++)
65                 if (p->a_bit & acts) {
66                         printf("%s%s"sepp->a_name);
67                         sep = "|";
68                 }
69         if (!bdebug) {
70                 printf(" for:\n");
71                 fwalk(teprint0);
72         } else
73                 putchar('\n');
74 }
75 #endif
76
77 /* node conventions:
78
79         NAME:   rval>0 is stab index for external
80                 rval<0 is -inlabel number
81                 lval is offset in bits
82         ICON:   lval has the value
83                 rval has the STAB index, or - label number,
84                         if a name whose address is in the constant
85                 rval = NONAME means no name
86         REG:    rval is reg. identification cookie
87
88         */
89
90 NODE *
ragge
1.2
91 buildtree(int oNODE *lNODE *r)
92 {
93         NODE *p, *q;
94         int actions;
95         int opty;
96         struct symtab *sp;
97         NODE *lr, *ll;
ragge
1.1
98         int i;
99
100 # ifndef BUG1
ragge
1.2
101         if (bdebug)
102                 printf("buildtree(%s, %p, %p)\n"opst[o], lr);
ragge
1.1
103 # endif
104         opty = optype(o);
105
106         /* check for constants */
107
108         ifopty == UTYPE && l->in.op == ICON ){
109
110                 switcho ){
111
112                 case NOT:
113                 case UNARY MINUS:
114                 case COMPL:
115                         ifconvallol ) ) return(l);
116                         break;
117
118                         }
119                 }
120
121         else ifopty == UTYPE && (l->in.op == FCON || l->in.op == DCON) ){
122
123                 switcho ){
124
125                 case NOT:
126                         ifl->in.op == FCON )
127                                 l->tn.lval = l->fpn.fval == 0.0;
128                         else
129                                 l->tn.lval = l->dpn.dval == 0.0;
130                         l->tn.rval = NONAME;
131                         l->in.op = ICON;
132                         l->fn.csiz = l->in.type = INT;
133                         l->fn.cdim = 0;
134                         return(l);
135                 case UNARY MINUS:
136                         ifl->in.op == FCON )
137                                 l->fpn.fval = -l->fpn.fval;
138                         else
139                                 l->dpn.dval = -l->dpn.dval;
140                         return(l);
141                         }
142                 }
143
144         else ifo==QUEST && l->in.op==ICON ) {
145                 l->in.op = FREE;
146                 r->in.op = FREE;
147                 ifl->tn.lval ){
148                         tfreer->in.right );
149                         returnr->in.left );
150                         }
151                 else {
152                         tfreer->in.left );
153                         returnr->in.right );
154                         }
155                 }
156
157         else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) goto ccwarn;
158
159         else ifopty == BITYPE && l->in.op == ICON && r->in.op == ICON ){
160
161                 switcho ){
162
163                 case ULT:
164                 case UGT:
165                 case ULE:
166                 case UGE:
167                 case LT:
168                 case GT:
169                 case LE:
170                 case GE:
171                 case EQ:
172                 case NE:
173                         ifl->in.type == ENUMTY && r->in.type == ENUMTY ){
174                                 p = blockolrINT0INT );
175                                 chkpunp );
176                                 p->in.op = FREE;
177                                 }
178
179                 case ANDAND:
180                 case OROR:
181                 case CBRANCH:
182
183                 ccwarn:
184
185                 case PLUS:
186                 case MINUS:
187                 case MUL:
188                 case DIV:
189                 case MOD:
190                 case AND:
191                 case OR:
192                 case ER:
193                 case LS:
194                 case RS:
195                         ifconvallor ) ) {
196                                 r->in.op = FREE;
197                                 return(l);
198                                 }
199                         break;
200                         }
201                 }
202         else if (opty == BITYPE &&
203                 (l->in.op == FCON || l->in.op == DCON || l->in.op == ICON) &&
204                 (r->in.op == FCON || r->in.op == DCON || r->in.op == ICON)) {
205                         if (o == PLUS || o == MINUS || o == MUL || o == DIV) {
206                                 extern int fpe_count;
207                                 extern jmp_buf gotfpe;
208
209                                 fpe_count = 0;
210                                 if (setjmp(gotfpe))
211                                         goto treatfpe;
212                                 if (l->in.op == ICON)
213                                         l->dpn.dval = l->tn.lval;
214                                 else if (l->in.op == FCON)
215                                         l->dpn.dval = l->fpn.fval;
216                                 if (r->in.op == ICON)
217                                         r->dpn.dval = r->tn.lval;
218                                 else if (r->in.op == FCON)
219                                         r->dpn.dval = r->fpn.fval;
220                                 switch (o) {
221
222                                 case PLUS:
223                                         l->dpn.dval += r->dpn.dval;
224                                         break;
225
226                                 case MINUS:
227                                         l->dpn.dval -= r->dpn.dval;
228                                         break;
229
230                                 case MUL:
231                                         l->dpn.dval *= r->dpn.dval;
232                                         break;
233
234                                 case DIV:
235                                         if (r->dpn.dval == 0)
236                                                 uerror("division by 0.");
237                                         else
238                                                 l->dpn.dval /= r->dpn.dval;
239                                         break;
240                                         }
241                         treatfpe:
242                                 if (fpe_count > 0) {
243                                         uerror("floating point exception in constant expression");
244                                         l->dpn.dval = 1.0/* Fairly harmless */
245                                         }
246                                 fpe_count = -1;
247                                 l->in.op = DCON;
248                                 l->in.type = l->fn.csiz = DOUBLE;
249                                 r->in.op = FREE;
250                                 return (l);
251                         }
252                 }
253
254         /* it's real; we must make a new node */
255
256         p = blockolrINT0INT );
257
258         actions = opact(p);
259 #ifndef BUG1
260         if (adebug)
261                 printact(pactions);
262 #endif
263
264         ifactions&LVAL ){ /* check left descendent */
265                 ifnotlval(p->in.left) ) {
266                         uerror"illegal lvalue operand of assignment operator" );
267                         }
268                 }
269
270         ifactions & NCVTR ){
271                 p->in.left = pconvertp->in.left );
272                 }
273         else if( !(actions & NCVT ) ){
274                 switchopty ){
275
276                 case BITYPE:
277                         p->in.right = pconvertp->in.right );
278                 case UTYPE:
279                         p->in.left = pconvertp->in.left );
280
281                         }
282                 }
283
ragge
1.7
284         if ((actions&PUN) && (o!=CAST||cflag))
ragge
1.1
285                 chkpun(p);
286
287         ifactions & (TYPL|TYPR) ){
288
289                 q = (actions&TYPL) ? p->in.left : p->in.right;
290
291                 p->in.type = q->in.type;
292                 p->fn.cdim = q->fn.cdim;
293                 p->fn.csiz = q->fn.csiz;
294                 }
295
296         ifactions & CVTL ) p = convertpCVTL );
297         ifactions & CVTR ) p = convertpCVTR );
298         ifactions & TYMATCH ) p = tymatch(p);
299         ifactions & PTMATCH ) p = ptmatch(p);
300
301         ifactions & OTHER ){
302                 l = p->in.left;
303                 r = p->in.right;
304
305                 switch(o){
306
307                 case NAME:
308                         sp = &stab[idname];
309                         ifsp->stype == UNDEF ){
310                                 uerror"%s undefined"sp->sname );
311                                 /* make p look reasonable */
312                                 p->in.type = p->fn.csiz = INT;
313                                 p->fn.cdim = 0;
314                                 p->tn.rval = idname;
315                                 p->tn.lval = 0;
316                                 defidpSNULL );
317                                 break;
318                                 }
319                         p->in.type = sp->stype;
320                         p->fn.cdim = sp->dimoff;
321                         p->fn.csiz = sp->sizoff;
322                         p->tn.lval = 0;
323                         p->tn.rval = idname;
324                         /* special case: MOETY is really an ICON... */
325                         ifp->in.type == MOETY ){
326                                 p->tn.rval = NONAME;
327                                 p->tn.lval = sp->offset;
328                                 p->fn.cdim = 0;
329                                 p->in.type = ENUMTY;
330                                 p->in.op = ICON;
331                                 }
332                         break;
333
334                 case ICON:
335                         p->in.type = INT;
336                         p->fn.cdim = 0;
337                         p->fn.csiz = INT;
338                         break;
339
340                 case STRING:
341                         p->in.op = NAME;
ragge
1.17
342 #ifdef CHAR_UNSIGNED
343                         p->in.type = UCHAR+ARY;
344                         p->fn.csiz = UCHAR;
345 #else
ragge
1.1
346                         p->in.type = CHAR+ARY;
ragge
1.17
347                         p->fn.csiz = CHAR;
348 #endif
ragge
1.1
349                         p->tn.lval = 0;
350                         p->tn.rval = NOLAB;
351                         p->fn.cdim = curdim;
352                         break;
353
354                 case FCON:
355                         p->tn.lval = 0;
356                         p->tn.rval = 0;
357                         p->in.type = FLOAT;
358                         p->fn.cdim = 0;
359                         p->fn.csiz = FLOAT;
360                         break;
361
362                 case DCON:
363                         p->tn.lval = 0;
364                         p->tn.rval = 0;
365                         p->in.type = DOUBLE;
366                         p->fn.cdim = 0;
367                         p->fn.csiz = DOUBLE;
368                         break;
369
370                 case STREF:
371                         /* p->x turned into *(p+offset) */
372                         /* rhs must be a name; check correctness */
373
374                         i = r->tn.rval;
375                         ifi<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){
376                                 uerror"member of structure or union required" );
377                                 }else
378                         /* if this name is non-unique, find right one */
379                         ifstab[i].sflags & SNONUNIQ &&
380                                 (l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) &&
381                                 (l->fn.csiz +1) >= 0 ){
382                                 /* nonunique name && structure defined */
383                                 char * memnam, * tabnam;
384                                 int j;
385                                 int memi;
386                                 j=dimtab[l->fn.csiz+1];
387                                 for( ; (memi=dimtab[j]) >= 0; ++j ){
388                                         tabnam = stab[memi].sname;
389                                         memnam = stab[i].sname;
390 # ifndef BUG1
391                                         ifddebug>1 ){
392                                                 printf("member %s==%s?\n",
393                                                         memnamtabnam);
394                                                 }
395 # endif
396                                         ifstab[memi].sflags & SNONUNIQ ){
397                                                 if (memnam != tabnam)
398                                                         goto next;
399                                                 r->tn.rval = i = memi;
400                                                 break;
401                                                 }
402                                         nextcontinue;
403                                         }
404                                 ifmemi < 0 )
405                                         uerror("illegal member use: %s",
406                                                 stab[i].sname);
407                                 }
408                         else {
ragge
1.2
409                                 int j;
ragge
1.1
410                                 ifl->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){
411                                         ifstab[i].sflags & SNONUNIQ ){
412                                                 uerror"nonunique name demands struct/union or struct/union pointer" );
413                                                 }
414                                         else werror"struct/union or struct/union pointer required" );
415                                         }
416                                 else if( (j=l->fn.csiz+1)<0 ) cerror"undefined structure or union" );
417                                 else if( !chkstridimtab[j], DECREF(l->in.type) ) ){
418                                         werror"illegal member use: %s"stab[i].sname );
419                                         }
420                                 }
421
422                         p = strefp );
423                         break;
424
425                 case UNARY MUL:
426                         ifl->in.op == UNARY AND ){
427                                 p->in.op = l->in.op = FREE;
428                                 p = l->in.left;
429                                 }
430                         if( !ISPTR(l->in.type))uerror("illegal indirection");
431                         p->in.type = DECREF(l->in.type);
432                         p->fn.cdim = l->fn.cdim;
433                         p->fn.csiz = l->fn.csiz;
434                         break;
435
436                 case UNARY AND:
437                         switchl->in.op ){
438
439                         case UNARY MUL:
440                                 p->in.op = l->in.op = FREE;
441                                 p = l->in.left;
442                         case NAME:
443                                 p->in.type = INCREFl->in.type );
444                                 p->fn.cdim = l->fn.cdim;
445                                 p->fn.csiz = l->fn.csiz;
446                                 break;
447
448                         case COMOP:
449                                 lr = buildtreeUNARY ANDl->in.rightNIL );
450                                 p->in.op = l->in.op = FREE;
451                                 p = buildtreeCOMOPl->in.leftlr );
452                                 break;
453
454                         case QUEST:
455                                 lr = buildtreeUNARY ANDl->in.right->in.rightNIL );
456                                 ll = buildtreeUNARY ANDl->in.right->in.leftNIL );
457                                 p->in.op = l->in.op = l->in.right->in.op = FREE;
458                                 p = buildtreeQUESTl->in.leftbuildtreeCOLONlllr ) );
459                                 break;
460
461 # ifdef ADDROREG
462                         case OREG:
463                                 /* OREG was built in clocal()
464                                  * for an auto or formal parameter
465                                  * now its address is being taken
466                                  * local code must unwind it
467                                  * back to PLUS/MINUS REG ICON
468                                  * according to local conventions
469                                  */
470                                 p->in.op = FREE;
471                                 p = addroregl );
472                                 break;
473
474 # endif
475                         default:
ragge
1.18
476                                 uerror("unacceptable operand of &: %d"l->in.op );
ragge
1.1
477                                 break;
478                                 }
479                         break;
480
481                 case LS:
482                 case RS:
483                         ifl->in.type == CHAR || l->in.type == SHORT )
484                                 p->in.type = INT;
485                         else ifl->in.type == UCHAR || l->in.type == USHORT )
486                                 p->in.type = UNSIGNED;
487                         else
488                                 p->in.type = l->in.type;
489                 case ASG LS:
490                 case ASG RS:
491                         ifr->in.type != INT )
492                                 p->in.right = r = makety(rINT0INT );
493                         break;
494
495                 case RETURN:
496                 case ASSIGN:
497                 case CAST:
498                         /* structure assignment */
499                         /* take the addresses of the two sides; then make an
ragge
1.2
500                          * operator using STASG and
501                          * the addresses of left and right */
ragge
1.1
502
503                         {
ragge
1.2
504                                 TWORD t;
505                                 int ds;
ragge
1.1
506
507                                 ifl->fn.csiz != r->fn.csiz ) uerror"assignment of different structures" );
508
509                                 r = buildtreeUNARY ANDrNIL );
510                                 t = r->in.type;
511                                 d = r->fn.cdim;
512                                 s = r->fn.csiz;
513
514                                 l = blockSTASGlrtds );
515
516                                 ifo == RETURN ){
517                                         p->in.op = FREE;
518                                         p = l;
519                                         break;
520                                         }
521
522                                 p->in.op = UNARY MUL;
523                                 p->in.left = l;
524                                 p->in.right = NIL;
525                                 break;
526                                 }
527                 case COLON:
528                         /* structure colon */
529
530                         ifl->fn.csiz != r->fn.csiz ) uerror"type clash in conditional" );
531                         break;
532
533                 case CALL:
534                         p->in.right = r = fixargsp->in.right );
535                 case UNARY CALL:
536                         if( !ISPTR(l->in.type)) uerror("illegal function");
537                         p->in.type = DECREF(l->in.type);
538                         if( !ISFTN(p->in.type)) uerror("illegal function");
539                         p->in.type = DECREFp->in.type );
540                         p->fn.cdim = l->fn.cdim;
541                         p->fn.csiz = l->fn.csiz;
542                         ifl->in.op == UNARY AND && l->in.left->in.op == NAME &&
543                                 l->in.left->tn.rval >= 0 && l->in.left->tn.rval != NONAME &&
544                                 ( (i=stab[l->in.left->tn.rval].sclass) == FORTRAN || i==UFORTRAN ) ){
545                                 p->in.op += (FORTCALL-CALL);
546                                 }
547                         ifp->in.type == STRTY || p->in.type == UNIONTY ){
548                                 /* function returning structure */
549                                 /*  make function really return ptr to str., with * */
550
551                                 p->in.op += STCALL-CALL;
552                                 p->in.type = INCREFp->in.type );
553                                 p = buildtreeUNARY MULpNIL );
554
555                                 }
556                         break;
557
558                 default:
559                         cerror"other code %d"o );
560                         }
561
562                 }
563
ragge
1.11
564         /*
565          * Allow (void)0 casts.
566          * XXX - anything on the right side must be possible to cast.
567          * XXX - remove void types further on.
568          */
569         if (p->in.op == CAST && p->in.type == UNDEF &&
570             p->in.right->in.op == ICON)
571                 p->in.right->in.type = UNDEF;
572
ragge
1.1
573         ifactions & CVTO ) p = oconvert(p);
574         p = clocal(p);
575
576 # ifndef BUG1
577         ifbdebug ) fwalkpeprint0 );
578 # endif
579
580         return(p);
581
582         }
583
584 int fpe_count = -1;
585 jmp_buf gotfpe;
586
ragge
1.2
587 void fpe(int);
ragge
1.1
588 void
ragge
1.2
589 fpe(int a)
590 {
ragge
1.1
591         if (fpe_count < 0)
592                 cerror("floating point exception");
593         ++fpe_count;
594         longjmp(gotfpe1);
ragge
1.2
595 }
ragge
1.1
596
597 /*
598  * Rewrite arguments in a function call.
599  * Structure arguments are massaged, single
600  * precision floating point constants are
601  * cast to double (to eliminate convert code).
602  */
603 NODE *
604 fixargsp ) register NODE *p;  {
605         int o = p->in.op;
606
607         ifo == CM ){
608                 p->in.left = fixargsp->in.left );
609                 p->in.right = fixargsp->in.right );
610                 returnp );
611                 }
612
613         ifp->in.type == STRTY || p->in.type == UNIONTY ){
614                 p = blockSTARGpNILp->in.typep->fn.cdimp->fn.csiz );
615                 p->in.left = buildtreeUNARY ANDp->in.leftNIL );
616                 p = clocal(p);
617                 }
618         else ifo == FCON )
619                 p = makety(pDOUBLE00);
620         returnp );
ragge
1.2
621 }
ragge
1.1
622
ragge
1.2
623 /*
624  * is the MOS or MOU at stab[i] OK for strict reference by a ptr
625  * i has been checked to contain a MOS or MOU
626  * j is the index in dimtab of the members...
627  */
628 int
629 chkstr(int iint jTWORD type)
630 {
ragge
1.1
631         int kkk;
632
633         extern int ddebug;
634
635 # ifndef BUG1
ragge
1.15
636         if (ddebug > 1)
637                 printf("chkstr( %s(%d), %d )\n"stab[i].snameij);
ragge
1.1
638 # endif
ragge
1.15
639         if ((k = j) < 0)
640                 uerror("undefined structure or union");
ragge
1.1
641         else {
ragge
1.15
642                 for (; (kk = dimtab[k] ) >= 0; ++k) {
643                         if (kk >= SYMTSZ) {
ragge
1.1
644                                 cerror"gummy structure" );
645                                 return(1);
ragge
1.15
646                         }
647                         if (kk == i)
648                                 return(1);
649                         switch(stab[kk].stype) {
ragge
1.1
650
651                         case STRTY:
652                         case UNIONTY:
ragge
1.15
653                                 if (type == STRTY)
654                                         continue;  /* no recursive looking for strs */
ragge
1.1
655                         }
656                 }
ragge
1.15
657         }
658         return(0);
ragge
1.2
659 }
ragge
1.1
660
ragge
1.2
661 /*
662  * apply the op o to the lval part of p; if binary, rhs is val
663  * works only on integer constants
664  */
665 int
666 conval(NODE *pint oNODE *q)
667 {
ragge
1.1
668         int iu;
669         CONSZ val;
670         TWORD utype;
671
672         val = q->tn.lval;
673         u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type);
674         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
675
676         ifp->tn.rval != NONAME && q->tn.rval != NONAME ) return(0);
677         ifq->tn.rval != NONAME && o!=PLUS ) return(0);
678         ifp->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0);
679
680         /* usual type conversions -- handle casts of constants */
681 #define ISLONG(t)       ((t) == LONG || (t) == ULONG)
ragge
1.6
682 #define ISLONGLONG(t)   ((t) == LONGLONG || (t) == ULONGLONG)
ragge
1.1
683         if (ISLONG(p->in.type) || ISLONG(q->in.type))
684                 utype = u ? ULONG : LONG;
ragge
1.6
685         else if (ISLONGLONG(p->in.type) || ISLONGLONG(q->in.type))
686                 utype = u ? ULONGLONG : LONGLONG;
ragge
1.1
687         else
688                 utype = u ? UNSIGNED : INT;
689         if( !ISPTR(p->in.type) && p->in.type != utype )
690                 p = makety(putype0, (int)utype);
691         ifq->in.type != utype )
692                 q = makety(qutype0, (int)utype);
693
694         switcho ){
695
696         case PLUS:
697                 p->tn.lval += val;
698                 ifp->tn.rval == NONAME ){
699                         p->tn.rval = q->tn.rval;
700                         p->in.type = q->in.type;
701                         }
702                 break;
703         case MINUS:
704                 p->tn.lval -= val;
705                 break;
706         case MUL:
707                 p->tn.lval *= val;
708                 break;
709         case DIV:
710                 ifval == 0 ) uerror"division by 0" );
711                 else if ( u ) p->tn.lval = (unsignedp->tn.lval / val;
712                 else p->tn.lval /= val;
713                 break;
714         case MOD:
715                 ifval == 0 ) uerror"division by 0" );
716                 else if ( u ) p->tn.lval = (unsignedp->tn.lval % val;
717                 else p->tn.lval %= val;
718                 break;
719         case AND:
720                 p->tn.lval &= val;
721                 break;
722         case OR:
723                 p->tn.lval |= val;
724                 break;
725         case ER:
726                 p->tn.lval ^= val;
727                 break;
728         case LS:
729                 i = val;
730                 p->tn.lval = p->tn.lval << i;
731                 break;
732         case RS:
733                 i = val;
734                 if ( u ) p->tn.lval = (unsignedp->tn.lval >> i;
735                 else p->tn.lval = p->tn.lval >> i;
736                 break;
737
738         case UNARY MINUS:
739                 p->tn.lval = - p->tn.lval;
740                 break;
741         case COMPL:
742                 p->tn.lval = ~p->tn.lval;
743                 break;
744         case NOT:
745                 p->tn.lval = !p->tn.lval;
746                 break;
747         case LT:
748                 p->tn.lval = p->tn.lval < val;
749                 break;
750         case LE:
751                 p->tn.lval = p->tn.lval <= val;
752                 break;
753         case GT:
754                 p->tn.lval = p->tn.lval > val;
755                 break;
756         case GE:
757                 p->tn.lval = p->tn.lval >= val;
758                 break;
759         case ULT:
760                 p->tn.lval = p->tn.lval < (unsignedval;
761                 break;
762         case ULE:
763                 p->tn.lval = p->tn.lval <= (unsignedval;
764                 break;
765         case UGT:
766                 p->tn.lval = p->tn.lval > (unsignedval;
767                 break;
768         case UGE:
769                 p->tn.lval = p->tn.lval >= (unsignedval;
770                 break;
771         case EQ:
772                 p->tn.lval = p->tn.lval == val;
773                 break;
774         case NE:
775                 p->tn.lval = p->tn.lval != val;
776                 break;
777         default:
778                 return(0);
779                 }
780         return(1);
781         }
782
ragge
1.7
783 /*
784  * Checks p for the existance of a pun.  This is called when the op of p
785  * is ASSIGN, RETURN, CAST, COLON, or relational.
786  * One case is when enumerations are used: this applies only to lint.
787  * In the other case, one operand is a pointer, the other integer type
788  * we check that this integer is in fact a constant zero...
789  * in the case of ASSIGN, any assignment of pointer to integer is illegal
790  * this falls out, because the LHS is never 0.
791  */
ragge
1.2
792 void
ragge
1.7
793 chkpun(NODE *p)
794 {
ragge
1.2
795         NODE *q;
796         int t1t2d1d2ref1ref2;
ragge
1.1
797
798         t1 = p->in.left->in.type;
799         t2 = p->in.right->in.type;
800
ragge
1.7
801         /* check for enumerations */
802         if (t1==ENUMTY || t2==ENUMTY) {
ragge
1.1
803                 /* rob pike says this is obnoxious...
804                 if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE )
805                         werror( "comparison of enums" ); */
ragge
1.7
806                 if (t1==ENUMTY && t2==ENUMTY) {
807                         if (p->in.left->fn.csiz!=p->in.right->fn.csiz)
808                                 werror("enumeration type clash, "
809                                     "operator %s"opst[p->in.op]);
ragge
1.1
810                         return;
811                 }
ragge
1.7
812                 if (t1 == ENUMTY)
813                         t1 = INT;
814                 if (t2 == ENUMTY)
815                         t2 = INT;
816         }
ragge
1.1
817
818         ref1 = ISPTR(t1) || ISARY(t1);
819         ref2 = ISPTR(t2) || ISARY(t2);
820
ragge
1.7
821         if (ref1 ^ ref2) {
822                 if (ref1)
823                         q = p->in.right;
824                 else
825                         q = p->in.left;
826                 if (q->in.op != ICON || q->tn.lval != 0)
827                         werror("illegal combination of pointer "
828                             "and integer, op %s"opst[p->in.op]);
829         } else if (ref1) {
830                 if (t1 == t2) {
831                         if (p->in.left->fn.csiz != p->in.right->fn.csiz) {
ragge
1.5
832                                 werror("illegal structure pointer combination");
ragge
1.1
833                                 return;
ragge
1.5
834                         }
ragge
1.1
835                         d1 = p->in.left->fn.cdim;
836                         d2 = p->in.right->fn.cdim;
ragge
1.7
837                         for (;;) {
838                                 if (ISARY(t1)) {
839                                         if (dimtab[d1] != dimtab[d2]) {
840                                                 werror("illegal array "
841                                                     "size combination");
ragge
1.1
842                                                 return;
ragge
1.5
843                                         }
ragge
1.1
844                                         ++d1;
845                                         ++d2;
ragge
1.5
846                                 } else
ragge
1.7
847                                         if (!ISPTR(t1))
ragge
1.5
848                                                 break;
ragge
1.1
849                                 t1 = DECREF(t1);
850                         }
ragge
1.7
851                 } else if (t1 != INCREF(UNDEF) && t2 != INCREF(UNDEF))
852                         werror("illegal pointer combination");
ragge
1.1
853         }
ragge
1.5
854 }
ragge
1.1
855
856 NODE *
ragge
1.10
857 stref(NODE *p)
858 {
ragge
1.1
859         TWORD t;
860         int dsdscalign;
861         OFFSZ off;
862         register struct symtab *q;
863
864         /* make p->x */
865         /* this is also used to reference automatic variables */
866
867         q = &stab[p->in.right->tn.rval];
868         p->in.right->in.op = FREE;
869         p->in.op = FREE;
ragge
1.10
870         p = pconvert(p->in.left);
ragge
1.1
871
872         /* make p look like ptr to x */
873
ragge
1.10
874         if (!ISPTR(p->in.type))
ragge
1.1
875                 p->in.type = PTR+UNIONTY;
876
ragge
1.10
877         t = INCREF(q->stype);
ragge
1.1
878         d = q->dimoff;
879         s = q->sizoff;
880
ragge
1.10
881         p = makety(ptds);
ragge
1.1
882
883         /* compute the offset to be added */
884
885         off = q->offset;
886         dsc = q->sclass;
887
ragge
1.10
888         if (dsc & FIELD) {  /* normalize offset */
ragge
1.1
889                 align = ALINT;
890                 s = INT;
891                 off = (off/align)*align;
ragge
1.10
892         }
893         if (off != 0)
894                 p = clocal(block(PLUSpoffcon(offtds), tds));
ragge
1.1
895
ragge
1.10
896         p = buildtree(UNARY MULpNIL);
ragge
1.1
897
898         /* if field, build field info */
899
ragge
1.10
900         if (dsc & FIELD) {
901                 p = block(FLDpNILq->stype0q->sizoff);
902                 p->tn.rval = PKFIELD(dsc&FLDSIZq->offset%align);
903         }
ragge
1.1
904
ragge
1.19
905         p = clocal(p);
906         p->in.su = q->s_argn;   /* Needed if this is a function */
907         return p;
ragge
1.10
908 }
ragge
1.1
909
ragge
1.2
910 int
ragge
1.1
911 notlval(pregister NODE *p; {
912
913         /* return 0 if p an lvalue, 1 otherwise */
914
915         again:
916
917         switchp->in.op ){
918
919         case FLD:
920                 p = p->in.left;
921                 goto again;
922
923         case UNARY MUL:
924                 /* fix the &(a=b) bug, given that a and b are structures */
925                 ifp->in.left->in.op == STASG ) return1 );
926                 /* and the f().a bug, given that f returns a structure */
927                 ifp->in.left->in.op == UNARY STCALL ||
928                     p->in.left->in.op == STCALL ) return1 );
929         case NAME:
930         case OREG:
931                 ifISARY(p->in.type) || ISFTN(p->in.type) ) return(1);
932         case REG:
933                 return(0);
934
935         default:
936                 return(1);
937
938                 }
939
940         }
941
942 NODE *
943 bconi ){ /* make a constant node with value i */
944         register NODE *p;
945
946         p = blockICONNILNILINT0INT );
947         p->tn.lval = i;
948         p->tn.rval = NONAME;
949         returnclocal(p) );
950         }
951
952 NODE *
ragge
1.10
953 bpsize(NODE *p)
954 {
955         return(offcon(psize(p), p->in.typep->fn.cdimp->fn.csiz));
956 }
ragge
1.1
957
ragge
1.10
958 /*
959  * p is a node of type pointer; psize returns the
960  * size of the thing pointed to
961  */
ragge
1.1
962 OFFSZ
ragge
1.10
963 psize(NODE *p)
964 {
965
966         if (!ISPTR(p->in.type)) {
967                 uerror("pointer required");
968                 return(SZINT);
969         }
ragge
1.1
970         /* note: no pointers to fields */
ragge
1.10
971         return(tsize(DECREF(p->in.type), p->fn.cdimp->fn.csiz));
972 }
ragge
1.1
973
ragge
1.10
974 /*
975  * convert an operand of p
976  * f is either CVTL or CVTR
977  * operand has type int, and is converted by the size of the other side
978  */
ragge
1.1
979 NODE *
ragge
1.10
980 convert(NODE *pint f)
981 {
982         NODE *q, *r, *s;
ragge
1.1
983
ragge
1.10
984         q = (f == CVTL) ? p->in.left : p->in.right;
ragge
1.1
985
ragge
1.10
986         s = bpsize(f == CVTL ? p->in.right : p->in.left);
987         r = block(PMCONVqsINT0INT);
ragge
1.1
988         r = clocal(r);
ragge
1.13
989         /*
990          * Indexing is only allowed with integer arguments, so insert
991          * SCONV here if arg is not an integer.
992          * XXX - complain?
993          */
994         if (r->in.type != INT)
995                 r = clocal(block(SCONVrNILINT0INT));
ragge
1.10
996         if (f == CVTL)
ragge
1.1
997                 p->in.left = r;
998         else
999                 p->in.right = r;
1000         return(p);
ragge
1.10
1001 }
ragge
1.1
1002
1003 #ifndef econvert
ragge
1.2
1004 void
ragge
1.1
1005