Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030604200825

Diff

Diff from 1.24 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.23
98         char *name;
ragge
1.1
99         int i;
100
101 # ifndef BUG1
ragge
1.2
102         if (bdebug)
103                 printf("buildtree(%s, %p, %p)\n"opst[o], lr);
ragge
1.1
104 # endif
105         opty = optype(o);
106
107         /* check for constants */
108
ragge
1.22
109         ifopty == UTYPE && l->n_op == ICON ){
ragge
1.1
110
111                 switcho ){
112
113                 case NOT:
114                 case UNARY MINUS:
115                 case COMPL:
116                         ifconvallol ) ) return(l);
117                         break;
118
119                         }
120                 }
121
ragge
1.22
122         else ifopty == UTYPE && (l->n_op == FCON || l->n_op == DCON) ){
ragge
1.1
123
124                 switcho ){
125
126                 case NOT:
ragge
1.22
127                         ifl->n_op == FCON )
128                                 l->n_lval = l->n_fcon == 0.0;
ragge
1.1
129                         else
ragge
1.22
130                                 l->n_lval = l->n_dcon == 0.0;
ragge
1.23
131                         l->n_sp = NULL;
ragge
1.22
132                         l->n_op = ICON;
133                         l->n_csiz = l->n_type = INT;
134                         l->n_cdim = 0;
ragge
1.1
135                         return(l);
136                 case UNARY MINUS:
ragge
1.22
137                         ifl->n_op == FCON )
138                                 l->n_fcon = -l->n_fcon;
ragge
1.1
139                         else
ragge
1.22
140                                 l->n_dcon = -l->n_dcon;
ragge
1.1
141                         return(l);
142                         }
143                 }
144
ragge
1.22
145         else ifo==QUEST && l->n_op==ICON ) {
146                 l->n_op = FREE;
147                 r->n_op = FREE;
148                 ifl->n_lval ){
149                         tfreer->n_right );
150                         returnr->n_left );
ragge
1.1
151                         }
152                 else {
ragge
1.22
153                         tfreer->n_left );
154                         returnr->n_right );
ragge
1.1
155                         }
156                 }
157
ragge
1.22
158         else if( (o==ANDAND || o==OROR) && (l->n_op==ICON||r->n_op==ICON) ) goto ccwarn;
ragge
1.1
159
ragge
1.22
160         else ifopty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
ragge
1.1
161
162                 switcho ){
163
164                 case ULT:
165                 case UGT:
166                 case ULE:
167                 case UGE:
168                 case LT:
169                 case GT:
170                 case LE:
171                 case GE:
172                 case EQ:
173                 case NE:
ragge
1.22
174                         ifl->n_type == ENUMTY && r->n_type == ENUMTY ){
ragge
1.1
175                                 p = blockolrINT0INT );
176                                 chkpunp );
ragge
1.22
177                                 p->n_op = FREE;
ragge
1.1
178                                 }
179
180                 case ANDAND:
181                 case OROR:
182                 case CBRANCH:
183
184                 ccwarn:
185
186                 case PLUS:
187                 case MINUS:
188                 case MUL:
189                 case DIV:
190                 case MOD:
191                 case AND:
192                 case OR:
193                 case ER:
194                 case LS:
195                 case RS:
196                         ifconvallor ) ) {
ragge
1.22
197                                 r->n_op = FREE;
ragge
1.1
198                                 return(l);
199                                 }
200                         break;
201                         }
202                 }
203         else if (opty == BITYPE &&
ragge
1.22
204                 (l->n_op == FCON || l->n_op == DCON || l->n_op == ICON) &&
205                 (r->n_op == FCON || r->n_op == DCON || r->n_op == ICON)) {
ragge
1.1
206                         if (o == PLUS || o == MINUS || o == MUL || o == DIV) {
207                                 extern int fpe_count;
208                                 extern jmp_buf gotfpe;
209
210                                 fpe_count = 0;
211                                 if (setjmp(gotfpe))
212                                         goto treatfpe;
ragge
1.22
213                                 if (l->n_op == ICON)
214                                         l->n_dcon = l->n_lval;
215                                 else if (l->n_op == FCON)
216                                         l->n_dcon = l->n_fcon;
217                                 if (r->n_op == ICON)
218                                         r->n_dcon = r->n_lval;
219                                 else if (r->n_op == FCON)
220                                         r->n_dcon = r->n_fcon;
ragge
1.1
221                                 switch (o) {
222
223                                 case PLUS:
ragge
1.22
224                                         l->n_dcon += r->n_dcon;
ragge
1.1
225                                         break;
226
227                                 case MINUS:
ragge
1.22
228                                         l->n_dcon -= r->n_dcon;
ragge
1.1
229                                         break;
230
231                                 case MUL:
ragge
1.22
232                                         l->n_dcon *= r->n_dcon;
ragge
1.1
233                                         break;
234
235                                 case DIV:
ragge
1.22
236                                         if (r->n_dcon == 0)
ragge
1.1
237                                                 uerror("division by 0.");
238                                         else
ragge
1.22
239                                                 l->n_dcon /= r->n_dcon;
ragge
1.1
240                                         break;
241                                         }
242                         treatfpe:
243                                 if (fpe_count > 0) {
244                                         uerror("floating point exception in constant expression");
ragge
1.22
245                                         l->n_dcon = 1.0/* Fairly harmless */
ragge
1.1
246                                         }
247                                 fpe_count = -1;
ragge
1.22
248                                 l->n_op = DCON;
249                                 l->n_type = l->n_csiz = DOUBLE;
250                                 r->n_op = FREE;
ragge
1.1
251                                 return (l);
252                         }
253                 }
254
255         /* it's real; we must make a new node */
256
257         p = blockolrINT0INT );
258
259         actions = opact(p);
260 #ifndef BUG1
261         if (adebug)
262                 printact(pactions);
263 #endif
264
265         ifactions&LVAL ){ /* check left descendent */
ragge
1.22
266                 ifnotlval(p->n_left) ) {
ragge
1.1
267                         uerror"illegal lvalue operand of assignment operator" );
268                         }
269                 }
270
271         ifactions & NCVTR ){
ragge
1.22
272                 p->n_left = pconvertp->n_left );
ragge
1.1
273                 }
274         else if( !(actions & NCVT ) ){
275                 switchopty ){
276
277                 case BITYPE:
ragge
1.22
278                         p->n_right = pconvertp->n_right );
ragge
1.1
279                 case UTYPE:
ragge
1.22
280                         p->n_left = pconvertp->n_left );
ragge
1.1
281
282                         }
283                 }
284
ragge
1.7
285         if ((actions&PUN) && (o!=CAST||cflag))
ragge
1.1
286                 chkpun(p);
287
288         ifactions & (TYPL|TYPR) ){
289
ragge
1.22
290                 q = (actions&TYPL) ? p->n_left : p->n_right;
ragge
1.1
291
ragge
1.22
292                 p->n_type = q->n_type;
293                 p->n_cdim = q->n_cdim;
294                 p->n_csiz = q->n_csiz;
ragge
1.1
295                 }
296
297         ifactions & CVTL ) p = convertpCVTL );
298         ifactions & CVTR ) p = convertpCVTR );
299         ifactions & TYMATCH ) p = tymatch(p);
300         ifactions & PTMATCH ) p = ptmatch(p);
301
302         ifactions & OTHER ){
ragge
1.22
303                 l = p->n_left;
304                 r = p->n_right;
ragge
1.1
305
306                 switch(o){
307
308                 case NAME:
ragge
1.23
309                         sp = spname;
310                         if (sp->stype == UNDEF) {
311                                 uerror("%s undefined"sp->sname);
ragge
1.1
312                                 /* make p look reasonable */
ragge
1.22
313                                 p->n_type = p->n_csiz = INT;
314                                 p->n_cdim = 0;
ragge
1.23
315                                 p->n_sp = sp;
ragge
1.22
316                                 p->n_lval = 0;
ragge
1.23
317                                 defid(pSNULL);
ragge
1.1
318                                 break;
ragge
1.23
319                         }
ragge
1.22
320                         p->n_type = sp->stype;
321                         p->n_cdim = sp->dimoff;
322                         p->n_csiz = sp->sizoff;
323                         p->n_lval = 0;
ragge
1.23
324                         p->n_sp = sp;
ragge
1.1
325                         /* special case: MOETY is really an ICON... */
ragge
1.23
326                         if (p->n_type == MOETY) {
327                                 p->n_sp = NULL;
328                                 p->n_lval = sp->soffset;
ragge
1.22
329                                 p->n_cdim = 0;
330                                 p->n_type = ENUMTY;
331                                 p->n_op = ICON;
ragge
1.23
332                         }
ragge
1.1
333                         break;
334
335                 case ICON:
ragge
1.22
336                         p->n_type = INT;
337                         p->n_cdim = 0;
338                         p->n_csiz = INT;
ragge
1.1
339                         break;
340
341                 case STRING:
ragge
1.22
342                         p->n_op = NAME;
ragge
1.17
343 #ifdef CHAR_UNSIGNED
ragge
1.22
344                         p->n_type = UCHAR+ARY;
345                         p->n_csiz = UCHAR;
ragge
1.17
346 #else
ragge
1.22
347                         p->n_type = CHAR+ARY;
348                         p->n_csiz = CHAR;
ragge
1.17
349 #endif
ragge
1.22
350                         p->n_lval = 0;
ragge
1.23
351                         p->n_sp = NULL;
ragge
1.22
352                         p->n_cdim = curdim;
ragge
1.1
353                         break;
354
355                 case FCON:
ragge
1.22
356                         p->n_lval = 0;
357                         p->n_rval = 0;
358                         p->n_type = FLOAT;
359                         p->n_cdim = 0;
360                         p->n_csiz = FLOAT;
ragge
1.1
361                         break;
362
363                 case DCON:
ragge
1.22
364                         p->n_lval = 0;
365                         p->n_rval = 0;
366                         p->n_type = DOUBLE;
367                         p->n_cdim = 0;
368                         p->n_csiz = DOUBLE;
ragge
1.1
369                         break;
370
371                 case STREF:
372                         /* p->x turned into *(p+offset) */
373                         /* rhs must be a name; check correctness */
374
ragge
1.23
375                         /* Find member symbol struct */
376                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
377                                 uerror("struct or union required");
378                                 break;
379                         }
380
381                         if ((i = dimtab[l->n_csiz + 1]) < 0)
382                                 uerror("undefined struct or union");
383
384                         name = r->n_name;
385                         for (; dimtab[i] >= 0i++) {
386                                 sp = (struct symtab *)dimtab[i];
387                                 if (sp->sname == name)
388                                         break;
389                         }
390                         if (dimtab[i] < 0)
391                                 uerror("member '%s' not declared"name);
392
393                         r->n_sp = sp;
394                         p = stref(p);
395                         break;
396
ragge
1.1
397                 case UNARY MUL:
ragge
1.22
398                         ifl->n_op == UNARY AND ){
399                                 p->n_op = l->n_op = FREE;
400                                 p = l->n_left;
ragge
1.1
401                                 }
ragge
1.22
402                         if( !ISPTR(l->n_type))uerror("illegal indirection");
403                         p->n_type = DECREF(l->n_type);
404                         p->n_cdim = l->n_cdim;
405                         p->n_csiz = l->n_csiz;
ragge
1.1
406                         break;
407
408                 case UNARY AND:
ragge
1.22
409                         switchl->n_op ){
ragge
1.1
410
411                         case UNARY MUL:
ragge
1.22
412                                 p->n_op = l->n_op = FREE;
413                                 p = l->n_left;
ragge
1.1
414                         case NAME:
ragge
1.22
415                                 p->n_type = INCREFl->n_type );
416                                 p->n_cdim = l->n_cdim;
417                                 p->n_csiz = l->n_csiz;
ragge
1.1
418                                 break;
419
420                         case COMOP:
ragge
1.22
421                                 lr = buildtreeUNARY ANDl->n_rightNIL );
422                                 p->n_op = l->n_op = FREE;
423                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.1
424                                 break;
425
426                         case QUEST:
ragge
1.22
427                                 lr = buildtreeUNARY ANDl->n_right->n_rightNIL );
428                                 ll = buildtreeUNARY ANDl->n_right->n_leftNIL );
429                                 p->n_op = l->n_op = l->n_right->n_op = FREE;
430                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.1
431                                 break;
432
433 # ifdef ADDROREG
434                         case OREG:
435                                 /* OREG was built in clocal()
436                                  * for an auto or formal parameter
437                                  * now its address is being taken
438                                  * local code must unwind it
439                                  * back to PLUS/MINUS REG ICON
440                                  * according to local conventions
441                                  */
ragge
1.22
442                                 p->n_op = FREE;
ragge
1.1
443                                 p = addroregl );
444                                 break;
445
446 # endif
447                         default:
ragge
1.22
448                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
449                                 break;
450                                 }
451                         break;
452
453                 case LS:
454                 case RS:
ragge
1.22
455                         ifl->n_type == CHAR || l->n_type == SHORT )
456                                 p->n_type = INT;
457                         else ifl->n_type == UCHAR || l->n_type == USHORT )
458                                 p->n_type = UNSIGNED;
ragge
1.1
459                         else
ragge
1.22
460                                 p->n_type = l->n_type;
ragge
1.1
461                 case ASG LS:
462                 case ASG RS:
ragge
1.22
463                         ifr->n_type != INT )
464                                 p->n_right = r = makety(rINT0INT );
ragge
1.1
465                         break;
466
467                 case RETURN:
468                 case ASSIGN:
469                 case CAST:
470                         /* structure assignment */
471                         /* take the addresses of the two sides; then make an
ragge
1.2
472                          * operator using STASG and
473                          * the addresses of left and right */
ragge
1.1
474
475                         {
ragge
1.2
476                                 TWORD t;
477                                 int ds;
ragge
1.1
478
ragge
1.22
479                                 ifl->n_csiz != r->n_csiz ) uerror"assignment of different structures" );
ragge
1.1
480
481                                 r = buildtreeUNARY ANDrNIL );
ragge
1.22
482                                 t = r->n_type;
483                                 d = r->n_cdim;
484                                 s = r->n_csiz;
ragge
1.1
485
486                                 l = blockSTASGlrtds );
487
488                                 ifo == RETURN ){
ragge
1.22
489                                         p->n_op = FREE;
ragge
1.1
490                                         p = l;
491                                         break;
492                                         }
493
ragge
1.22
494                                 p->n_op = UNARY MUL;
495                                 p->n_left = l;
496                                 p->n_right = NIL;
ragge
1.1
497                                 break;
498                                 }
499                 case COLON:
500                         /* structure colon */
501
ragge
1.22
502                         ifl->n_csiz != r->n_csiz ) uerror"type clash in conditional" );
ragge
1.1
503                         break;
504
505                 case CALL:
ragge
1.23
506                         p->n_right = r = fixargs(p->n_right);
ragge
1.1
507                 case UNARY CALL:
ragge
1.23
508                         if (!ISPTR(l->n_type))
509                                 uerror("illegal function");
ragge
1.22
510                         p->n_type = DECREF(l->n_type);
ragge
1.23
511                         if (!ISFTN(p->n_type))
512                                 uerror("illegal function");
513                         p->n_type = DECREF(p->n_type);
ragge
1.22
514                         p->n_cdim = l->n_cdim;
515                         p->n_csiz = l->n_csiz;
ragge
1.23
516                         if (l->n_op == UNARY AND && l->n_left->n_op == NAME &&
517                             l->n_left->n_sp != NULL && l->n_left->n_sp != NULL &&
518                             (l->n_left->n_sp->sclass == FORTRAN ||
519                             l->n_left->n_sp->sclass == UFORTRAN)) {
ragge
1.22
520                                 p->n_op += (FORTCALL-CALL);
ragge
1.23
521                         }
522                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
523                                 /* function returning structure */
524                                 /*  make function really return ptr to str., with * */
525
ragge
1.22
526                                 p->n_op += STCALL-CALL;
ragge
1.23
527                                 p->n_type = INCREF(p->n_type);
528                                 p = buildtree(UNARY MULpNIL);
ragge
1.1
529
530                                 }
531                         break;
532
533                 default:
534                         cerror"other code %d"o );
535                         }
536
537                 }
538
ragge
1.11
539         /*
540          * Allow (void)0 casts.
541          * XXX - anything on the right side must be possible to cast.
542          * XXX - remove void types further on.
543          */
ragge
1.22
544         if (p->n_op == CAST && p->n_type == UNDEF &&
545             p->n_right->n_op == ICON)
546                 p->n_right->n_type = UNDEF;
ragge
1.11
547
ragge
1.1
548         ifactions & CVTO ) p = oconvert(p);
549         p = clocal(p);
550
551 # ifndef BUG1
552         ifbdebug ) fwalkpeprint0 );
553 # endif
554
555         return(p);
556
557         }
558
559 int fpe_count = -1;
560 jmp_buf gotfpe;
561
ragge
1.2
562 void fpe(int);
ragge
1.1
563 void
ragge
1.2
564 fpe(int a)
565 {
ragge
1.1
566         if (fpe_count < 0)
567                 cerror("floating point exception");
568         ++fpe_count;
569         longjmp(gotfpe1);
ragge
1.2
570 }
ragge
1.1
571
572 /*
573  * Rewrite arguments in a function call.
574  * Structure arguments are massaged, single
575  * precision floating point constants are
576  * cast to double (to eliminate convert code).
577  */
578 NODE *
579 fixargsp ) register NODE *p;  {
ragge
1.22
580         int o = p->n_op;
ragge
1.1
581
582         ifo == CM ){
ragge
1.22
583                 p->n_left = fixargsp->n_left );
584                 p->n_right = fixargsp->n_right );
ragge
1.1
585                 returnp );
586                 }
587
ragge
1.22
588         ifp->n_type == STRTY || p->n_type == UNIONTY ){
589                 p = blockSTARGpNILp->n_typep->n_cdimp->n_csiz );
590                 p->n_left = buildtreeUNARY ANDp->n_leftNIL );
ragge
1.1
591                 p = clocal(p);
592                 }
593         else ifo == FCON )
594                 p = makety(pDOUBLE00);
595         returnp );
ragge
1.2
596 }
ragge
1.1
597
ragge
1.23
598 #if 0
ragge
1.2
599 /*
600  * is the MOS or MOU at stab[i] OK for strict reference by a ptr
601  * i has been checked to contain a MOS or MOU
602  * j is the index in dimtab of the members...
603  */
604 int
605 chkstr(int iint jTWORD type)
606 {
ragge
1.1
607         int kkk;
608
609         extern int ddebug;
610
611 # ifndef BUG1
ragge
1.15
612         if (ddebug > 1)
613                 printf("chkstr( %s(%d), %d )\n"stab[i].snameij);
ragge
1.1
614 # endif
ragge
1.15
615         if ((k = j) < 0)
616                 uerror("undefined structure or union");
ragge
1.1
617         else {
ragge
1.15
618                 for (; (kk = dimtab[k] ) >= 0; ++k) {
619                         if (kk >= SYMTSZ) {
ragge
1.1
620                                 cerror"gummy structure" );
621                                 return(1);
ragge
1.15
622                         }
623                         if (kk == i)
624                                 return(1);
625                         switch(stab[kk].stype) {
ragge
1.1
626
627                         case STRTY:
628                         case UNIONTY:
ragge
1.15
629                                 if (type == STRTY)
630                                         continue;  /* no recursive looking for strs */
ragge
1.1
631                         }
632                 }
ragge
1.15
633         }
634         return(0);
ragge
1.2
635 }
ragge
1.23
636 #endif
ragge
1.1
637
ragge
1.2
638 /*
639  * apply the op o to the lval part of p; if binary, rhs is val
640  * works only on integer constants
641  */
642 int
643 conval(NODE *pint oNODE *q)
644 {
ragge
1.1
645         int iu;
646         CONSZ val;
647         TWORD utype;
648
ragge
1.22
649         val = q->n_lval;
650         u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
ragge
1.1
651         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
652
ragge
1.23
653         if (p->n_sp != NULL && q->n_sp != NULL)
654                 return(0);
655         if (q->n_sp != NULL && o != PLUS)
656                 return(0);
657         if (p->n_sp != NULL && o != PLUS && o != MINUS)
658                 return(0);
ragge
1.1
659
660         /* usual type conversions -- handle casts of constants */
661 #define ISLONG(t)       ((t) == LONG || (t) == ULONG)
ragge
1.6
662 #define ISLONGLONG(t)   ((t) == LONGLONG || (t) == ULONGLONG)
ragge
1.22
663         if (ISLONG(p->n_type) || ISLONG(q->n_type))
ragge
1.1
664                 utype = u ? ULONG : LONG;
ragge
1.22
665         else if (ISLONGLONG(p->n_type) || ISLONGLONG(q->n_type))
ragge
1.6
666                 utype = u ? ULONGLONG : LONGLONG;
ragge
1.1
667         else
668                 utype = u ? UNSIGNED : INT;
ragge
1.22
669         if( !ISPTR(p->n_type) && p->n_type != utype )
ragge
1.1
670                 p = makety(putype0, (int)utype);
ragge
1.22
671         ifq->n_type != utype )
ragge
1.1
672                 q = makety(qutype0, (int)utype);
673
674         switcho ){
675
676         case PLUS:
ragge
1.22
677                 p->n_lval += val;
ragge
1.23
678                 if (p->n_sp == NULL) {
ragge
1.22
679                         p->n_rval = q->n_rval;
680                         p->n_type = q->n_type;
ragge
1.23
681                 }
ragge
1.1
682                 break;
683         case MINUS:
ragge
1.22
684                 p->n_lval -= val;
ragge
1.1
685                 break;
686         case MUL:
ragge
1.22
687                 p->n_lval *= val;
ragge
1.1
688                 break;
689         case DIV:
690                 ifval == 0 ) uerror"division by 0" );
ragge
1.22
691                 else if ( u ) p->n_lval = (unsignedp->n_lval / val;
692                 else p->n_lval /= val;
ragge
1.1
693                 break;
694         case MOD:
695                 ifval == 0 ) uerror"division by 0" );
ragge
1.22
696                 else if ( u ) p->n_lval = (unsignedp->n_lval % val;
697                 else p->n_lval %= val;
ragge
1.1
698                 break;
699         case AND:
ragge
1.22
700                 p->n_lval &= val;
ragge
1.1
701                 break;
702         case OR:
ragge
1.22
703                 p->n_lval |= val;
ragge
1.1
704                 break;
705         case ER:
ragge
1.22
706                 p->n_lval ^= val;
ragge
1.1
707                 break;
708         case LS:
709                 i = val;
ragge
1.22
710                 p->n_lval = p->n_lval << i;
ragge
1.1
711                 break;
712         case RS:
713                 i = val;
ragge
1.22
714                 if ( u ) p->n_lval = (unsignedp->n_lval >> i;
715                 else p->n_lval = p->n_lval >> i;
ragge
1.1
716                 break;
717
718         case UNARY MINUS:
ragge
1.22
719                 p->n_lval = - p->n_lval;
ragge
1.1
720                 break;
721         case COMPL:
ragge
1.22
722                 p->n_lval = ~p->n_lval;
ragge
1.1
723                 break;
724         case NOT:
ragge
1.22
725                 p->n_lval = !p->n_lval;
ragge
1.1
726                 break;
727         case LT:
ragge
1.22
728                 p->n_lval = p->n_lval < val;
ragge
1.1
729                 break;
730         case LE:
ragge
1.22
731                 p->n_lval = p->n_lval <= val;
ragge
1.1
732                 break;
733         case GT:
ragge
1.22
734                 p->n_lval = p->n_lval > val;
ragge
1.1
735                 break;
736         case GE:
ragge
1.22
737                 p->n_lval = p->n_lval >= val;
ragge
1.1
738                 break;
739         case ULT:
ragge
1.22
740                 p->n_lval = p->n_lval < (unsignedval;
ragge
1.1
741                 break;
742         case ULE:
ragge
1.22
743                 p->n_lval = p->n_lval <= (unsignedval;
ragge
1.1
744                 break;
745         case UGT:
ragge
1.22
746                 p->n_lval = p->n_lval > (unsignedval;
ragge
1.1
747                 break;
748         case UGE:
ragge
1.22
749                 p->n_lval = p->n_lval >= (unsignedval;
ragge
1.1
750                 break;
751         case EQ:
ragge
1.22
752                 p->n_lval = p->n_lval == val;
ragge
1.1
753                 break;
754         case NE:
ragge
1.22
755                 p->n_lval = p->n_lval != val;
ragge
1.1
756                 break;
757         default:
758                 return(0);
759                 }
760         return(1);
761         }
762
ragge
1.7
763 /*
764  * Checks p for the existance of a pun.  This is called when the op of p
765  * is ASSIGN, RETURN, CAST, COLON, or relational.
766  * One case is when enumerations are used: this applies only to lint.
767  * In the other case, one operand is a pointer, the other integer type
768  * we check that this integer is in fact a constant zero...
769  * in the case of ASSIGN, any assignment of pointer to integer is illegal
770  * this falls out, because the LHS is never 0.
771  */
ragge
1.2
772 void
ragge
1.7
773 chkpun(NODE *p)
774 {
ragge
1.2
775         NODE *q;
776         int t1t2d1d2ref1ref2;
ragge
1.1
777
ragge
1.22
778         t1 = p->n_left->n_type;
779         t2 = p->n_right->n_type;
ragge
1.1
780
ragge
1.7
781         /* check for enumerations */
782         if (t1==ENUMTY || t2==ENUMTY) {
ragge
1.1
783                 /* rob pike says this is obnoxious...
ragge
1.22
784                 if( logop( p->n_op ) && p->n_op != EQ && p->n_op != NE )
ragge
1.1
785                         werror( "comparison of enums" ); */
ragge
1.7
786                 if (t1==ENUMTY && t2==ENUMTY) {
ragge
1.22
787                         if (p->n_left->n_csiz!=p->n_right->n_csiz)
ragge
1.7
788                                 werror("enumeration type clash, "
ragge
1.22
789                                     "operator %s"opst[p->n_op]);
ragge
1.1
790                         return;
791                 }
ragge
1.7
792                 if (t1 == ENUMTY)
793                         t1 = INT;
794                 if (t2 == ENUMTY)
795                         t2 = INT;
796         }
ragge
1.1
797
798         ref1 = ISPTR(t1) || ISARY(t1);
799         ref2 = ISPTR(t2) || ISARY(t2);
800
ragge
1.7
801         if (ref1 ^ ref2) {
802                 if (ref1)
ragge
1.22
803                         q = p->n_right;
ragge
1.7
804                 else
ragge
1.22
805                         q = p->n_left;
806                 if (q->n_op != ICON || q->n_lval != 0)
ragge
1.7
807                         werror("illegal combination of pointer "
ragge
1.22
808                             "and integer, op %s"opst[p->n_op]);
ragge
1.7
809         } else if (ref1) {
810                 if (t1 == t2) {
ragge
1.22
811                         if (p->n_left->n_csiz != p->n_right->n_csiz) {
ragge
1.5
812                                 werror("illegal structure pointer combination");
ragge
1.1
813                                 return;
ragge
1.5
814                         }
ragge
1.22
815                         d1 = p->n_left->n_cdim;
816                         d2 = p->n_right->n_cdim;
ragge
1.7
817                         for (;;) {
818                                 if (ISARY(t1)) {
819                                         if (dimtab[d1] != dimtab[d2]) {
820                                                 werror("illegal array "
821                                                     "size combination");
ragge
1.1
822                                                 return;
ragge
1.5
823                                         }
ragge
1.1
824                                         ++d1;
825                                         ++d2;
ragge
1.5
826                                 } else
ragge
1.7
827                                         if (!ISPTR(t1))
ragge
1.5
828                                                 break;
ragge
1.1
829                                 t1 = DECREF(t1);
830                         }
ragge
1.7
831                 } else if (t1 != INCREF(UNDEF) && t2 != INCREF(UNDEF))
832                         werror("illegal pointer combination");
ragge
1.1
833         }
ragge
1.5
834 }
ragge
1.1
835
836 NODE *
ragge
1.10
837 stref(NODE *p)
838 {
ragge
1.1
839         TWORD t;
ragge
1.23
840         int dsdscalign;
ragge
1.1
841         OFFSZ off;
842         register struct symtab *q;
843
844         /* make p->x */
845         /* this is also used to reference automatic variables */
846
ragge
1.23
847         q = p->n_right->n_sp;
ragge
1.22
848         p->n_right->n_op = FREE;
849         p->n_op = FREE;
850         p = pconvert(p->n_left);
ragge
1.1
851
852         /* make p look like ptr to x */
853
ragge
1.22
854         if (!ISPTR(p->n_type))
855                 p->n_type = PTR+UNIONTY;
ragge
1.1
856
ragge
1.10
857         t = INCREF(q->stype);
ragge
1.1
858         d = q->dimoff;
859         s = q->sizoff;
860
ragge
1.10
861         p = makety(ptds);
ragge
1.1
862
863         /* compute the offset to be added */
864
ragge
1.23
865         off = q->soffset;
ragge
1.1
866         dsc = q->sclass;
867
ragge
1.10
868         if (dsc & FIELD) {  /* normalize offset */
ragge
1.1
869                 align = ALINT;
870                 s = INT;
871                 off = (off/align)*align;
ragge
1.10
872         }
873         if (off != 0)
874                 p = clocal(block(PLUSpoffcon(offtds), tds));
ragge
1.1
875
ragge
1.10
876         p = buildtree(UNARY MULpNIL);
ragge