Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030610120813

Diff

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