Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030610135719

Diff

Diff from 1.28 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.28
135                         l->n_dim = NULL;
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;
ragge
1.28
295                 p->n_dim = q->n_dim;
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.28
317                                 p->n_dim = NULL;
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;
ragge
1.28
324                         p->n_dim = sp->sdim;
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.28
332                                 p->n_dim = NULL;
ragge
1.22
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;
ragge
1.28
340                         p->n_dim = NULL;
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.1
355                         break;
356
357                 case FCON:
ragge
1.22
358                         p->n_lval = 0;
359                         p->n_rval = 0;
360                         p->n_type = FLOAT;
ragge
1.28
361                         p->n_dim = NULL;
ragge
1.26
362                         p->n_sue = MKSUE(FLOAT);
ragge
1.1
363                         break;
364
365                 case DCON:
ragge
1.22
366                         p->n_lval = 0;
367                         p->n_rval = 0;
368                         p->n_type = DOUBLE;
ragge
1.28
369                         p->n_dim = NULL;
ragge
1.26
370                         p->n_sue = MKSUE(DOUBLE);
ragge
1.1
371                         break;
372
373                 case STREF:
374                         /* p->x turned into *(p+offset) */
375                         /* rhs must be a name; check correctness */
376
ragge
1.23
377                         /* Find member symbol struct */
378                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
379                                 uerror("struct or union required");
380                                 break;
381                         }
382
ragge
1.26
383                         if ((elem = l->n_sue->suelem) == NULL)
ragge
1.23
384                                 uerror("undefined struct or union");
385
386                         name = r->n_name;
ragge
1.26
387                         for (; *elem != NULLelem++) {
388                                 sp = *elem;
ragge
1.23
389                                 if (sp->sname == name)
390                                         break;
391                         }
ragge
1.26
392                         if (*elem == NULL)
ragge
1.23
393                                 uerror("member '%s' not declared"name);
394
395                         r->n_sp = sp;
396                         p = stref(p);
397                         break;
398
ragge
1.1
399                 case UNARY MUL:
ragge
1.22
400                         ifl->n_op == UNARY AND ){
401                                 p->n_op = l->n_op = FREE;
402                                 p = l->n_left;
ragge
1.1
403                                 }
ragge
1.22
404                         if( !ISPTR(l->n_type))uerror("illegal indirection");
405                         p->n_type = DECREF(l->n_type);
ragge
1.28
406                         p->n_dim = l->n_dim;
ragge
1.26
407                         p->n_sue = l->n_sue;
ragge
1.1
408                         break;
409
410                 case UNARY AND:
ragge
1.22
411                         switchl->n_op ){
ragge
1.1
412
413                         case UNARY MUL:
ragge
1.22
414                                 p->n_op = l->n_op = FREE;
415                                 p = l->n_left;
ragge
1.1
416                         case NAME:
ragge
1.22
417                                 p->n_type = INCREFl->n_type );
ragge
1.28
418                                 p->n_dim = l->n_dim;
ragge
1.26
419                                 p->n_sue = l->n_sue;
ragge
1.1
420                                 break;
421
422                         case COMOP:
ragge
1.22
423                                 lr = buildtreeUNARY ANDl->n_rightNIL );
424                                 p->n_op = l->n_op = FREE;
425                                 p = buildtreeCOMOPl->n_leftlr );
ragge
1.1
426                                 break;
427
428                         case QUEST:
ragge
1.22
429                                 lr = buildtreeUNARY ANDl->n_right->n_rightNIL );
430                                 ll = buildtreeUNARY ANDl->n_right->n_leftNIL );
431                                 p->n_op = l->n_op = l->n_right->n_op = FREE;
432                                 p = buildtreeQUESTl->n_leftbuildtreeCOLONlllr ) );
ragge
1.1
433                                 break;
434
435 # ifdef ADDROREG
436                         case OREG:
437                                 /* OREG was built in clocal()
438                                  * for an auto or formal parameter
439                                  * now its address is being taken
440                                  * local code must unwind it
441                                  * back to PLUS/MINUS REG ICON
442                                  * according to local conventions
443                                  */
ragge
1.22
444                                 p->n_op = FREE;
ragge
1.1
445                                 p = addroregl );
446                                 break;
447
448 # endif
449                         default:
ragge
1.22
450                                 uerror("unacceptable operand of &: %d"l->n_op );
ragge
1.1
451                                 break;
452                                 }
453                         break;
454
455                 case LS:
456                 case RS:
ragge
1.22
457                         ifl->n_type == CHAR || l->n_type == SHORT )
458                                 p->n_type = INT;
459                         else ifl->n_type == UCHAR || l->n_type == USHORT )
460                                 p->n_type = UNSIGNED;
ragge
1.1
461                         else
ragge
1.22
462                                 p->n_type = l->n_type;
ragge
1.1
463                 case ASG LS:
464                 case ASG RS:
ragge
1.22
465                         ifr->n_type != INT )
ragge
1.26
466                                 p->n_right = r = makety(rINT0MKSUE(INT));
ragge
1.1
467                         break;
468
469                 case RETURN:
470                 case ASSIGN:
471                 case CAST:
472                         /* structure assignment */
473                         /* take the addresses of the two sides; then make an
ragge
1.2
474                          * operator using STASG and
475                          * the addresses of left and right */
ragge
1.1
476
477                         {
ragge
1.26
478                                 struct suedef *sue;
ragge
1.2
479                                 TWORD t;
ragge
1.28
480                                 int *d;
ragge
1.1
481
ragge
1.26
482                                 if (l->n_sue != r->n_sue)
483                                         uerror("assignment of different structures");
ragge
1.1
484
ragge
1.26
485                                 r = buildtree(UNARY ANDrNIL);
ragge
1.22
486                                 t = r->n_type;
ragge
1.28
487                                 d = r->n_dim;
ragge
1.26
488                                 sue = r->n_sue;
ragge
1.1
489
ragge
1.28
490                                 l = block(STASGlrtdsue);
ragge
1.1
491
492                                 ifo == RETURN ){
ragge
1.22
493                                         p->n_op = FREE;
ragge
1.1
494                                         p = l;
495                                         break;
ragge
1.28
496                                 }
ragge
1.1
497
ragge
1.22
498                                 p->n_op = UNARY MUL;
499                                 p->n_left = l;
500                                 p->n_right = NIL;
ragge
1.1
501                                 break;
502                                 }
503                 case COLON:
504                         /* structure colon */
505
ragge
1.26
506                         if (l->n_sue != r->n_sue)
507                                 uerror"type clash in conditional" );
ragge
1.1
508                         break;
509
510                 case CALL:
ragge
1.23
511                         p->n_right = r = fixargs(p->n_right);
ragge
1.1
512                 case UNARY CALL:
ragge
1.23
513                         if (!ISPTR(l->n_type))
514                                 uerror("illegal function");
ragge
1.22
515                         p->n_type = DECREF(l->n_type);
ragge
1.23
516                         if (!ISFTN(p->n_type))
517                                 uerror("illegal function");
518                         p->n_type = DECREF(p->n_type);
ragge
1.28
519                         p->n_dim = l->n_dim;
ragge
1.26
520                         p->n_sue = l->n_sue;
ragge
1.23
521                         if (l->n_op == UNARY AND && l->n_left->n_op == NAME &&
522                             l->n_left->n_sp != NULL && l->n_left->n_sp != NULL &&
523                             (l->n_left->n_sp->sclass == FORTRAN ||
524                             l->n_left->n_sp->sclass == UFORTRAN)) {
ragge
1.22
525                                 p->n_op += (FORTCALL-CALL);
ragge
1.23
526                         }
527                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
ragge
1.1
528                                 /* function returning structure */
529                                 /*  make function really return ptr to str., with * */
530
ragge
1.22
531                                 p->n_op += STCALL-CALL;
ragge
1.23
532                                 p->n_type = INCREF(p->n_type);
533                                 p = buildtree(UNARY MULpNIL);
ragge
1.1
534
535                                 }
536                         break;
537
538                 default:
539                         cerror"other code %d"o );
540                         }
541
542                 }
543
ragge
1.11
544         /*
545          * Allow (void)0 casts.
546          * XXX - anything on the right side must be possible to cast.
547          * XXX - remove void types further on.
548          */
ragge
1.22
549         if (p->n_op == CAST && p->n_type == UNDEF &&
550             p->n_right->n_op == ICON)
551                 p->n_right->n_type = UNDEF;
ragge
1.11
552
ragge
1.1
553         ifactions & CVTO ) p = oconvert(p);
554         p = clocal(p);
555
556 # ifndef BUG1
557         ifbdebug ) fwalkpeprint0 );
558 # endif
559
560         return(p);
561
562         }
563
564 int fpe_count = -1;
565 jmp_buf gotfpe;
566
ragge
1.2
567 void fpe(int);
ragge
1.1
568 void
ragge
1.2
569 fpe(int a)
570 {
ragge
1.1
571         if (fpe_count < 0)
572                 cerror("floating point exception");
573         ++fpe_count;
574         longjmp(gotfpe1);
ragge
1.2
575 }
ragge
1.1
576
577 /*
578  * Rewrite arguments in a function call.
579  * Structure arguments are massaged, single
580  * precision floating point constants are
581  * cast to double (to eliminate convert code).
582  */
583 NODE *
584 fixargsp ) register NODE *p;  {
ragge
1.22
585         int o = p->n_op;
ragge
1.1
586
587         ifo == CM ){
ragge
1.22
588                 p->n_left = fixargsp->n_left );
589                 p->n_right = fixargsp->n_right );
ragge
1.1
590                 returnp );
591                 }
592
ragge
1.22
593         ifp->n_type == STRTY || p->n_type == UNIONTY ){
ragge
1.28
594                 p = block(STARGpNILp->n_typep->n_dimp->n_sue);
ragge
1.22
595                 p->n_left = buildtreeUNARY ANDp->n_leftNIL );
ragge
1.1
596                 p = clocal(p);
597                 }
598         else ifo == FCON )
599                 p = makety(pDOUBLE00);
600         returnp );
ragge
1.2
601 }
ragge
1.1
602
ragge
1.2
603 /*
604  * apply the op o to the lval part of p; if binary, rhs is val
605  * works only on integer constants
606  */
607 int
608 conval(NODE *pint oNODE *q)
609 {
ragge
1.1
610         int iu;
611         CONSZ val;
612         TWORD utype;
613
ragge
1.22
614         val = q->n_lval;
615         u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
ragge
1.1
616         ifu && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
617
ragge
1.23
618         if (p->n_sp != NULL && q->n_sp != NULL)
619                 return(0);
620         if (q->n_sp != NULL && o != PLUS)
621                 return(0);
622         if (p->n_sp != NULL && o != PLUS && o != MINUS)
623                 return(0);
ragge
1.1
624
625         /* usual type conversions -- handle casts of constants */
626 #define ISLONG(t)       ((t) == LONG || (t) == ULONG)
ragge
1.6
627 #define ISLONGLONG(t)   ((t) == LONGLONG || (t) == ULONGLONG)
ragge
1.22
628         if (ISLONG(p->n_type) || ISLONG(q->n_type))
ragge
1.1
629                 utype = u ? ULONG : LONG;
ragge
1.22
630         else if (ISLONGLONG(p->n_type) || ISLONGLONG(q->n_type))
ragge
1.6
631                 utype = u ? ULONGLONG : LONGLONG;
ragge
1.1
632         else
633                 utype = u ? UNSIGNED : INT;
ragge
1.22
634         if( !ISPTR(p->n_type) && p->n_type != utype )
ragge
1.26
635                 p = makety(putype0MKSUE(utype));
ragge
1.22
636         ifq->n_type != utype )
ragge
1.26
637                 q = makety(qutype0MKSUE(utype));
ragge
1.1
638
639         switcho ){
640
641         case PLUS:
ragge
1.22
642                 p->n_lval += val;
ragge
1.23
643                 if (p->n_sp == NULL) {
ragge
1.22
644                         p->n_rval = q->n_rval;
645                         p->n_type = q->n_type;
ragge
1.23
646                 }
ragge
1.1
647                 break;
648         case MINUS:
ragge
1.22
649                 p->n_lval -= val;
ragge
1.1
650                 break;
651         case MUL:
ragge
1.22
652                 p->n_lval *= val;
ragge
1.1
653                 break;
654         case DIV:
655                 ifval == 0 ) uerror"division by 0" );
ragge
1.22
656                 else if ( u ) p->n_lval = (unsignedp->n_lval / val;
657                 else p->n_lval /= val;
ragge
1.1
658                 break;
659         case MOD:
660                 ifval == 0 ) uerror"division by 0" );
ragge
1.22
661                 else if ( u ) p->n_lval = (unsignedp->n_lval % val;
662                 else p->n_lval %= val;
ragge
1.1
663                 break;
664         case AND:
ragge
1.22
665                 p->n_lval &= val;
ragge
1.1
666                 break;
667         case OR:
ragge
1.22
668                 p->n_lval |= val;
ragge
1.1
669                 break;
670         case ER:
ragge
1.22
671                 p->n_lval ^= val;
ragge
1.1
672                 break;
673         case LS:
674                 i = val;
ragge
1.22
675                 p->n_lval = p->n_lval << i;
ragge
1.1
676                 break;
677         case RS:
678                 i = val;
ragge
1.22
679                 if ( u ) p->n_lval = (unsignedp->n_lval >> i;
680                 else p->n_lval = p->n_lval >> i;
ragge
1.1
681                 break;
682
683         case UNARY MINUS:
ragge
1.22
684                 p->n_lval = - p->n_lval;
ragge
1.1
685                 break;
686         case COMPL:
ragge
1.22
687                 p->n_lval = ~p->n_lval;
ragge
1.1
688                 break;
689         case NOT:
ragge
1.22
690                 p->n_lval = !p->n_lval;
ragge
1.1
691                 break;
692         case LT:
ragge
1.22
693                 p->n_lval = p->n_lval < val;
ragge
1.1
694                 break;
695         case LE:
ragge
1.22
696                 p->n_lval = p->n_lval <= val;
ragge
1.1
697                 break;
698         case GT:
ragge
1.22
699                 p->n_lval = p->n_lval > val;
ragge
1.1
700                 break;
701         case GE:
ragge
1.22
702                 p->n_lval = p->n_lval >= val;
ragge
1.1
703                 break;
704         case ULT:
ragge
1.22
705                 p->n_lval = p->n_lval < (unsignedval;
ragge
1.1
706                 break;
707         case ULE:
ragge
1.22
708                 p->n_lval = p->n_lval <= (unsignedval;
ragge
1.1
709                 break;
710         case UGT:
ragge
1.22
711                 p->n_lval = p->n_lval > (unsignedval;
ragge
1.1
712                 break;
713         case UGE:
ragge
1.22
714                 p->n_lval = p->n_lval >= (unsignedval;
ragge
1.1
715                 break;
716         case EQ:
ragge
1.22
717                 p->n_lval = p->n_lval == val;
ragge
1.1
718                 break;
719         case NE:
ragge
1.22
720                 p->n_lval = p->n_lval != val;
ragge
1.1
721                 break;
722         default:
723                 return(0);
724                 }
725         return(1);
726         }
727
ragge
1.7
728 /*
729  * Checks p for the existance of a pun.  This is called when the op of p
730  * is ASSIGN, RETURN, CAST, COLON, or relational.
731  * One case is when enumerations are used: this applies only to lint.
732  * In the other case, one operand is a pointer, the other integer type
733  * we check that this integer is in fact a constant zero...
734  * in the case of ASSIGN, any assignment of pointer to integer is illegal
735  * this falls out, because the LHS is never 0.
736  */
ragge
1.2
737 void
ragge
1.7
738 chkpun(NODE *p)
739 {
ragge
1.2
740         NODE *q;
ragge
1.28
741         int t1t2, *d1, *d2ref1ref2;
ragge
1.1
742
ragge
1.22
743         t1 = p->n_left->n_type;
744         t2 = p->n_right->n_type;
ragge
1.1
745
ragge
1.7
746         /* check for enumerations */
747         if (t1==ENUMTY || t2==ENUMTY) {
ragge
1.1
748                 /* rob pike says this is obnoxious...
ragge
1.22
749                 if( logop( p->n_op ) && p->n_op != EQ && p->n_op != NE )
ragge
1.1
750                         werror( "comparison of enums" ); */
ragge
1.7
751                 if (t1==ENUMTY && t2==ENUMTY) {
ragge
1.26
752                         if (p->n_left->n_sue!=p->n_right->n_sue)
ragge
1.7
753                                 werror("enumeration type clash, "
ragge
1.22
754                                     "operator %s"opst[p->n_op]);
ragge
1.1
755                         return;
756                 }
ragge
1.7
757                 if (t1 == ENUMTY)
758                         t1 = INT;
759                 if (t2 == ENUMTY)
760                         t2 = INT;
761         }
ragge
1.1
762
763         ref1 = ISPTR(t1) || ISARY(t1);
764         ref2 = ISPTR(t2) || ISARY(t2);
765
ragge
1.7
766         if (ref1 ^ ref2) {
767                 if (ref1)
ragge
1.22
768                         q = p->n_right;
ragge
1.7
769                 else
ragge
1.22
770                         q = p->n_left;
771                 if (q->n_op != ICON || q->n_lval != 0)
ragge
1.7
772                         werror("illegal combination of pointer "
ragge
1.22
773                             "and integer, op %s"opst[p->n_op]);
ragge
1.7
774         } else if (ref1) {
775                 if (t1 == t2) {
ragge
1.26
776                         if (p->n_left->n_sue != p->n_right->n_sue) {
ragge
1.5
777                                 werror("illegal structure pointer combination");
ragge
1.1
778                                 return;
ragge
1.5
779                         }
ragge
1.28
780                         d1 = p->n_left->n_dim;
781                         d2 = p->n_right->n_dim;
ragge
1.7
782                         for (;;) {
783                                 if (ISARY(t1)) {
ragge
1.28
784                                         if (*d1 != *d2) {
ragge
1.7
785                                                 werror("illegal array "
786                                                     "size combination");
ragge
1.1
787                                                 return;
ragge
1.5
788                                         }
ragge
1.1
789                                         ++d1;
790                                         ++d2;
ragge
1.5
791                                 } else
ragge
1.7
792                                         if (!ISPTR(t1))
ragge
1.5
793                                                 break;
ragge
1.1
794                                 t1 = DECREF(t1);
795                         }
ragge
1.7
796                 } else if (t1 != INCREF(UNDEF) && t2 != INCREF(UNDEF))
797                         werror("illegal pointer combination");
ragge
1.1
798         }
ragge
1.5
799 }
ragge
1.1
800
801 NODE *
ragge
1.10
802 stref(NODE *p)
803 {
ragge
1.26
804         struct suedef *sue;
ragge
1.1
805         TWORD t;
ragge
1.28
806         int *ddscalign;
ragge
1.1
807         OFFSZ off;
808         register struct symtab *q;
809
810         /* make p->x */
811         /* this is also used to reference automatic variables */
812
ragge
1.23
813         q = p->n_right->n_sp;
ragge
1.22
814         p->n_right->n_op = FREE;
815         p->n_op = FREE;
816         p = pconvert(p->n_left);
ragge
1.1
817
818         /* make p look like ptr to x */
819
ragge
1.22
820         if (!ISPTR(p->n_type))
821                 p->n_type = PTR+UNIONTY;
ragge
1.1
822
ragge
1.10
823         t = INCREF(q->stype);
ragge
1.28
824         d = q->sdim;
ragge
1.26
825         sue = q->ssue;
ragge
1.1
826
ragge
1.26
827         p = makety(ptdsue);
ragge
1.1
828
829         /* compute the offset to be added */
830
ragge
1.23
831         off = q->soffset;
ragge
1.1
832         dsc = q->sclass;
833
ragge
1.10
834         if (dsc & FIELD) {  /* normalize offset */
ragge
1.1
835                 align = ALINT;
ragge
1.26
836                 sue = MKSUE(INT);
ragge
1.1
837                 off = (off/align)*align;
ragge
1.10
838         }
839         if (off != 0)
ragge
1.26
840                 p = clocal(block(PLUSpoffcon(offtdsue), tdsue));
ragge
1.1
841
ragge
1.10
842         p = buildtree(UNARY MULpNIL);
ragge
1.1
843
844         /* if field, build field info */
845
ragge
1.10
846         if (dsc & FIELD) {
ragge
1.26
847