Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030619140917

Diff

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