Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030604193605

Diff

Diff from 1.23 to:

Annotations

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

Annotated File View

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