Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030705090010

Diff

Diff from 1.42 to:

Annotations

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

Annotated File View

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