Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030622211330

Diff

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