]> git.sur5r.net Git - cc65/blob - test/val/cq81.c
Merge pull request #133 from pfusik/fix-char-cast
[cc65] / test / val / cq81.c
1 /*
2   !!DESCRIPTION!! C-Manual Chapter 8.1: storage class specifiers
3   !!ORIGIN!!      LCC 4.1 Testsuite
4   !!LICENCE!!     own, freely distributeable for non-profit. read CPYRIGHT.LCC
5 */
6
7 struct defs {
8      int cbits;          /* No. of bits per char           */
9      int ibits;          /*                 int            */
10      int sbits;          /*                 short          */
11      int lbits;          /*                 long           */
12      int ubits;          /*                 unsigned       */
13      int fbits;          /*                 float          */
14      int dbits;          /*                 double         */
15      #ifndef NO_FLOATS
16         float fprec;        /* Smallest number that can be    */
17         float dprec;        /* significantly added to 1.      */
18      #endif
19      int flgs;           /* Print return codes, by section */
20      int flgm;           /* Announce machine dependencies  */
21      int flgd;           /* give explicit diagnostics      */
22      int flgl;           /* Report local return codes.     */
23      int rrc;            /* recent return code             */
24      int crc;            /* Cumulative return code         */
25      char rfs[8];        /* Return from section            */
26 };
27
28      int lbits;          /*                 long           */
29      int ubits;          /*                 unsigned       */
30      int fbits;          /*                 float          */
31      int dbits;          /*                 double         */
32      #ifndef NO_FLOATS
33         float fprec;        /* Smallest number that can be    */
34         float dprec;        /* significantly added to 1.      */
35      #endif
36      int flgs;           /* Print return codes, by section */
37      int flgm;           /* Announce machine dependencies  */
38      int flgd;           /* give explicit diagnostics      */
39      int flgl;           /* Report local return codes.     */
40      int rrc;            /* recent return code             */
41      int crc;            /* Cumulative return code         */
42      char rfs[8];        /* Return from section            */
43
44 #ifdef NO_IMPLICIT_FUNC_PROTOTYPES
45 regc();
46 regp();
47 regi();
48 #endif
49
50 #ifndef NO_OLD_FUNC_DECL
51 s81(pd0)              /* 8.1 Storage Class Specifiers    */
52 struct defs *pd0;
53 #else
54 int s81(struct defs *pd0)
55 #endif
56 {
57    static char s81er[] = "s81,er%d\n";
58    static char qs81[8] = "s81    ";
59    char *ps, *pt;
60    int k, rc, j, crc, prc, irc;
61    register char rchar;
62             char nrchar;
63    register int *rptr;
64             int *nrptr;
65    register int rint;
66             int nrint;
67    static char badtest[] = "Register count for %s is unreliable.\n";
68    static char goodtest[] = "%d registers assigned to %s variables.\n";
69
70    rc = 0;
71    crc = 0;
72    prc = 0;
73    irc = 0;
74    ps = qs81;
75    pt = pd0->rfs;
76
77    while(*pt++ = *ps++);
78
79 /*    The storage class specifiers are:
80
81         auto
82         static
83         extern
84         register
85         typedef
86
87       The first three of these were treated earlier, in s4. The last
88    will be checked in s88. "Register" remains.
89
90       There are three flavors of register, viz., char, int and pointer.
91    We wish first to ascertain that the representations as register
92    are consistent with the corresponding nonregister representations.
93                                                                  */
94
95    k = 1;
96    for (j=0; j<50; j++){
97      rchar = k;
98      nrchar = k;
99      rptr = &k;
100      nrptr = &k;
101      rint = k;
102      nrint = k;
103
104      if ( rchar != nrchar ) crc = 1;
105      if ( rptr != nrptr ) prc = 1;
106      if ( rint != nrint ) irc = 1;
107      k = k<<1;
108    }
109
110    if ( crc != 0 ) {
111      rc = rc+1;
112      if( pd0 -> flgd != 0 ) printf(s81er,1);
113    }
114
115    if ( prc != 0 ) {
116      rc = rc+2;
117      if( pd0 -> flgd != 0 ) printf(s81er,2);
118    }
119
120    if ( irc != 0 ) {
121      rc = rc+4;
122      if( pd0 -> flgd != 0 ) printf(s81er,4);
123    }
124
125 /*   Now we check to see if variables are actually being assigned
126      to registers.                       */
127
128    k = regc();
129    if ( pd0->flgm != 0 ) {
130      if ( k < 0 ) printf(badtest,"char");
131      else printf(goodtest,k,"char");
132    }
133
134    k = regp();
135    if ( pd0->flgm != 0 ) {
136      if ( k<0 ) printf(badtest,"pointer");
137      else printf(goodtest,k,"pointer");
138    }
139
140    k = regi();
141    if ( pd0->flgm != 0 ) {
142      if ( k<0 ) printf(badtest,"int");
143      else printf(goodtest,k,"int");
144    }
145
146    return rc;
147 }
148 regc() {     /*   char to register assignment   */
149 /*   Testing a variable whose storage class has been spec-
150 ified as "register" is somewhat tricky, but it can be done in a
151 fairly reliable fashion by taking advantage of our knowledge of the
152 ways in which compilers operate. If we declare a collection of vari-
153 ables of the same storage class, we would expect that, when storage
154 for these variables is actually allocated, the variables will be
155 bunched together and ordered according to one of the following
156 criteria:
157
158      (a) the order in which they were defined.
159      (b) the order in which they are used.
160      (c) alphabetically.
161      (d) the order in which they appear in the compiler's
162          symbol table.
163      (e) some other way.
164
165      Hence, if we define a sequence of variables in close alpha-
166 betical order, and use them in the same order in which we define
167 them, we would expect the differences between the addresses of
168 successive variables to be constant, except in case (d) where the
169 symbol table is a hash table, or in case (e). If a subsequence in
170 the middle of this sequence is selected, and for this subsequence,
171 every other variable is specified to be "register", and address
172 differences are taken between adjacent nonregister variables, we would
173 still expect to find constant differences if the "register" vari-
174 ables were actually assigned to registers, and some other diff-
175 erences if they were not. Specifically, if we had N variables
176 specified as "register" of which the first n were actually ass-
177 igned to registers, we would expect the sequence of differences
178 to consist of a number of occurrences of some number, followed by
179 N-n occurrences of some other number, followed by several occurr-
180 ences of the first number. If we get a sequence like this, we can
181 determine, by simple subtraction, how many (if any) variables are
182 being assigned to registers. If we get some other sequence, we know
183 that the test is invalid.                                     */
184
185             char r00;
186             char r01;
187             char r02;
188             char r03;
189    register char r04;
190             char r05;
191    register char r06;
192             char r07;
193    register char r08;
194             char r09;
195    register char r10;
196             char r11;
197    register char r12;
198             char r13;
199    register char r14;
200             char r15;
201    register char r16;
202             char r17;
203    register char r18;
204             char r19;
205    register char r20;
206             char r21;
207    register char r22;
208             char r23;
209    register char r24;
210             char r25;
211    register char r26;
212             char r27;
213    register char r28;
214             char r29;
215    register char r30;
216             char r31;
217    register char r32;
218             char r33;
219    register char r34;
220             char r35;
221             char r36;
222             char r37;
223             char r38;
224
225    int s, n1, n2, nr, j, d[22];
226    r00 = 0;
227    r01 = 1;
228    r02 = 2;
229    r03 = 3;
230    r04 = 4;
231    r05 = 5;
232    r06 = 6;
233    r07 = 7;
234    r08 = 8;
235    r09 = 9;
236    r10 = 10;
237    r11 = 11;
238    r12 = 12;
239    r13 = 13;
240    r14 = 14;
241    r15 = 15;
242    r16 = 16;
243    r17 = 17;
244    r18 = 18;
245    r19 = 19;
246    r20 = 20;
247    r21 = 21;
248    r22 = 22;
249    r23 = 23;
250    r24 = 24;
251    r25 = 25;
252    r26 = 26;
253    r27 = 27;
254    r28 = 28;
255    r29 = 29;
256    r30 = 30;
257    r31 = 31;
258    r32 = 32;
259    r33 = 33;
260    r34 = 34;
261    r35 = 35;
262    r36 = 36;
263    r37 = 37;
264    r38 = 38;
265
266    d[0] = &r01 - &r00;
267    d[1] = &r02 - &r01;
268    d[2] = &r03 - &r02;
269    d[3] = &r05 - &r03;
270    d[4] = &r07 - &r05;
271    d[5] = &r09 - &r07;
272    d[6] = &r11 - &r09;
273    d[7] = &r13 - &r11;
274    d[8] = &r15 - &r13;
275    d[9] = &r17 - &r15;
276    d[10] = &r19 - &r17;
277    d[11] = &r21 - &r19;
278    d[12] = &r23 - &r21;
279    d[13] = &r25 - &r23;
280    d[14] = &r27 - &r25;
281    d[15] = &r29 - &r27;
282    d[16] = &r31 - &r29;
283    d[17] = &r33 - &r31;
284    d[18] = &r35 - &r33;
285    d[19] = &r36 - &r35;
286    d[20] = &r37 - &r36;
287    d[21] = &r38 - &r37;
288
289 /*   The following FSM analyzes the string of differences. It accepts
290 strings of the form a+b+a+ and returns 16 minus the number of bs,
291 which is the number of variables that actually got into registers.
292 Otherwise it signals rejection by returning -1., indicating that the
293 test is unreliable.              */
294
295    n1 = d[0];
296    s = 1;
297
298    for (j=0; j<22; j++)
299      switch (s) {
300        case 1: if (d[j] != n1) {
301                 n2 = d[j];
302                 s = 2;
303                 nr = 1;
304                }
305                break;
306        case 2: if (d[j] == n1) {
307                 s = 3;
308                 break;
309                }
310                if (d[j] == n2) {
311                 nr = nr+1;
312                 break;
313                }
314                s = 4;
315                break;
316        case 3: if (d[j] != n1) s = 4;
317                break;
318      }
319    ;
320
321    if (s == 3) return 16-nr;
322    else return -1;
323 }
324 regi() {     /*   int to register assignment    */
325 /*   Testing a variable whose storage class has been spec-
326 ified as "register" is somewhat tricky, but it can be done in a
327 fairly reliable fashion by taking advantage of our knowledge of the
328 ways in which compilers operate. If we declare a collection of vari-
329 ables of the same storage class, we would expect that, when storage
330 for these variables is actually allocated, the variables will be
331 bunched together and ordered according to one of the following
332 criteria:
333
334      (a) the order in which they were defined.
335      (b) the order in which they are used.
336      (c) alphabetically.
337      (d) the order in which they appear in the compiler's
338          symbol table.
339      (e) some other way.
340
341      Hence, if we define a sequence of variables in close alpha-
342 betical order, and use them in the same order in which we define
343 them, we would expect the differences between the addresses of
344 successive variables to be constant, except in case (d) where the
345 symbol table is a hash table, or in case (e). If a subsequence in
346 the middle of this sequence is selected, and for this subsequence,
347 every other variable is specified to be "register", and address
348 differences are taken between adjacent nonregister variables, we would
349 still expect to find constant differences if the "register" vari-
350 ables were actually assigned to registers, and some other diff-
351 erences if they were not. Specifically, if we had N variables
352 specified as "register" of which the first n were actually ass-
353 igned to registers, we would expect the sequence of differences
354 to consist of a number of occurrences of some number, followed by
355 N-n occurrences of some other number, followed by several occurr-
356 ences of the first number. If we get a sequence like this, we can
357 determine, by simple subtraction, how many (if any) variables are
358 being assigned to registers. If we get some other sequence, we know
359 that the test is invalid.                                     */
360
361             int r00;
362             int r01;
363             int r02;
364             int r03;
365    register int r04;
366             int r05;
367    register int r06;
368             int r07;
369    register int r08;
370             int r09;
371    register int r10;
372             int r11;
373    register int r12;
374             int r13;
375    register int r14;
376             int r15;
377    register int r16;
378             int r17;
379    register int r18;
380             int r19;
381    register int r20;
382             int r21;
383    register int r22;
384             int r23;
385    register int r24;
386             int r25;
387    register int r26;
388             int r27;
389    register int r28;
390             int r29;
391    register int r30;
392             int r31;
393    register int r32;
394             int r33;
395    register int r34;
396             int r35;
397             int r36;
398             int r37;
399             int r38;
400
401    int s, n1, n2, nr, j, d[22];
402
403    r00 = 0;
404    r01 = 1;
405    r02 = 2;
406    r03 = 3;
407    r04 = 4;
408    r05 = 5;
409    r06 = 6;
410    r07 = 7;
411    r08 = 8;
412    r09 = 9;
413    r10 = 10;
414    r11 = 11;
415    r12 = 12;
416    r13 = 13;
417    r14 = 14;
418    r15 = 15;
419    r16 = 16;
420    r17 = 17;
421    r18 = 18;
422    r19 = 19;
423    r20 = 20;
424    r21 = 21;
425    r22 = 22;
426    r23 = 23;
427    r24 = 24;
428    r25 = 25;
429    r26 = 26;
430    r27 = 27;
431    r28 = 28;
432    r29 = 29;
433    r30 = 30;
434    r31 = 31;
435    r32 = 32;
436    r33 = 33;
437    r34 = 34;
438    r35 = 35;
439    r36 = 36;
440    r37 = 37;
441    r38 = 38;
442
443    d[0] = &r01 - &r00;
444    d[1] = &r02 - &r01;
445    d[2] = &r03 - &r02;
446    d[3] = &r05 - &r03;
447    d[4] = &r07 - &r05;
448    d[5] = &r09 - &r07;
449    d[6] = &r11 - &r09;
450    d[7] = &r13 - &r11;
451    d[8] = &r15 - &r13;
452    d[9] = &r17 - &r15;
453    d[10] = &r19 - &r17;
454    d[11] = &r21 - &r19;
455    d[12] = &r23 - &r21;
456    d[13] = &r25 - &r23;
457    d[14] = &r27 - &r25;
458    d[15] = &r29 - &r27;
459    d[16] = &r31 - &r29;
460    d[17] = &r33 - &r31;
461    d[18] = &r35 - &r33;
462    d[19] = &r36 - &r35;
463    d[20] = &r37 - &r36;
464    d[21] = &r38 - &r37;
465
466 /*   The following FSM analyzes the string of differences. It accepts
467 strings of the form a+b+a+ and returns 16 minus the number of bs,
468 which is the number of variables that actually got into registers.
469 Otherwise it signals rejection by returning -1., indicating that the
470 test is unreliable.              */
471
472    n1 = d[0];
473    s = 1;
474
475    for (j=0; j<22; j++)
476      switch (s) {
477        case 1: if (d[j] != n1) {
478                 n2 = d[j];
479                 s = 2;
480                 nr = 1;
481                }
482                break;
483        case 2: if (d[j] == n1) {
484                 s = 3;
485                 break;
486                }
487                if (d[j] == n2) {
488                 nr = nr+1;
489                 break;
490                }
491                s = 4;
492                break;
493        case 3: if (d[j] != n1) s = 4;
494                break;
495      }
496    ;
497
498    if (s == 3) return 16-nr;
499    else return -1;
500 }
501 regp() {     /*   pointer to register assignment   */
502 /*   Testing a variable whose storage class has been spec-
503 ified as "register" is somewhat tricky, but it can be done in a
504 fairly reliable fashion by taking advantage of our knowledge of the
505 ways in which compilers operate. If we declare a collection of vari-
506 ables of the same storage class, we would expect that, when storage
507 for these variables is actually allocated, the variables will be
508 bunched together and ordered according to one of the following
509 criteria:
510
511      (a) the order in which they were defined.
512      (b) the order in which they are used.
513      (c) alphabetically.
514      (d) the order in which they appear in the compiler's
515          symbol table.
516      (e) some other way.
517
518      Hence, if we define a sequence of variables in close alpha-
519 betical order, and use them in the same order in which we define
520 them, we would expect the differences between the addresses of
521 successive variables to be constant, except in case (d) where the
522 symbol table is a hash table, or in case (e). If a subsequence in
523 the middle of this sequence is selected, and for this subsequence,
524 every other variable is specified to be "register", and address
525 differences are taken between adjacent nonregister variables, we would
526 still expect to find constant differences if the "register" vari-
527 ables were actually assigned to registers, and some other diff-
528 erences if they were not. Specifically, if we had N variables
529 specified as "register" of which the first n were actually ass-
530 igned to registers, we would expect the sequence of differences
531 to consist of a number of occurrences of some number, followed by
532 N-n occurrences of some other number, followed by several occurr-
533 ences of the first number. If we get a sequence like this, we can
534 determine, by simple subtraction, how many (if any) variables are
535 being assigned to registers. If we get some other sequence, we know
536 that the test is invalid.                                     */
537
538             int *r00;
539             int *r01;
540             int *r02;
541             int *r03;
542    register int *r04;
543             int *r05;
544    register int *r06;
545             int *r07;
546    register int *r08;
547             int *r09;
548    register int *r10;
549             int *r11;
550    register int *r12;
551             int *r13;
552    register int *r14;
553             int *r15;
554    register int *r16;
555             int *r17;
556    register int *r18;
557             int *r19;
558    register int *r20;
559             int *r21;
560    register int *r22;
561             int *r23;
562    register int *r24;
563             int *r25;
564    register int *r26;
565             int *r27;
566    register int *r28;
567             int *r29;
568    register int *r30;
569             int *r31;
570    register int *r32;
571             int *r33;
572    register int *r34;
573             int *r35;
574             int *r36;
575             int *r37;
576             int *r38;
577
578    int s, n1, n2, nr, j, d[22];
579
580    r00 = (int *)&r00;
581    r01 = (int *)&r01;
582    r02 = (int *)&r02;
583    r03 = (int *)&r03;
584    r04 = (int *)&r05;
585    r05 = (int *)&r05;
586    r06 = (int *)&r07;
587    r07 = (int *)&r07;
588    r08 = (int *)&r09;
589    r09 = (int *)&r09;
590    r10 = (int *)&r11;
591    r11 = (int *)&r11;
592    r12 = (int *)&r13;
593    r13 = (int *)&r13;
594    r14 = (int *)&r15;
595    r15 = (int *)&r15;
596    r16 = (int *)&r17;
597    r17 = (int *)&r17;
598    r18 = (int *)&r19;
599    r19 = (int *)&r19;
600    r20 = (int *)&r21;
601    r21 = (int *)&r21;
602    r22 = (int *)&r23;
603    r23 = (int *)&r23;
604    r24 = (int *)&r25;
605    r25 = (int *)&r25;
606    r26 = (int *)&r27;
607    r27 = (int *)&r27;
608    r28 = (int *)&r29;
609    r29 = (int *)&r29;
610    r30 = (int *)&r31;
611    r31 = (int *)&r31;
612    r32 = (int *)&r33;
613    r33 = (int *)&r33;
614    r34 = (int *)&r35;
615    r35 = (int *)&r35;
616    r36 = (int *)&r36;
617    r37 = (int *)&r37;
618    r38 = (int *)&r38;
619
620    d[0] = &r01 - &r00;
621    d[1] = &r02 - &r01;
622    d[2] = &r03 - &r02;
623    d[3] = &r05 - &r03;
624    d[4] = &r07 - &r05;
625    d[5] = &r09 - &r07;
626    d[6] = &r11 - &r09;
627    d[7] = &r13 - &r11;
628    d[8] = &r15 - &r13;
629    d[9] = &r17 - &r15;
630    d[10] = &r19 - &r17;
631    d[11] = &r21 - &r19;
632    d[12] = &r23 - &r21;
633    d[13] = &r25 - &r23;
634    d[14] = &r27 - &r25;
635    d[15] = &r29 - &r27;
636    d[16] = &r31 - &r29;
637    d[17] = &r33 - &r31;
638    d[18] = &r35 - &r33;
639    d[19] = &r36 - &r35;
640    d[20] = &r37 - &r36;
641    d[21] = &r38 - &r37;
642
643 /*   The following FSM analyzes the string of differences. It accepts
644 strings of the form a+b+a+ and returns 16 minus the number of bs,
645 which is the number of variables that actually got into registers.
646 Otherwise it signals rejection by returning -1., indicating that the
647 test is unreliable.              */
648
649    n1 = d[0];
650    s = 1;
651    for (j=0; j<22; j++)
652      switch (s) {
653        case 1: if (d[j] != n1) {
654                 n2 = d[j];
655                 s = 2;
656                 nr = 1;
657                }
658                break;
659        case 2: if (d[j] == n1) {
660                 s = 3;
661                 break;
662                }
663                if (d[j] == n2) {
664                 nr = nr+1;
665                 break;
666                }
667                s = 4;
668                break;
669        case 3: if (d[j] != n1) s = 4;
670                break;
671      }
672    ;
673
674    if (s == 3) return 16-nr;
675    else return -1;
676 }
677
678 /*********************************************************************************************
679  the main loop that launches the sections
680 *********************************************************************************************/
681
682 #ifndef NO_TYPELESS_STRUCT_PTR
683         int section(int j,struct* pd0){
684 #else
685         int section(int j,void* pd0){
686 #endif
687         switch(j){
688                 case 0: return s81(pd0);
689         }
690 }
691
692 #define cq_sections 1
693
694 /*
695         C REFERENCE MANUAL (main)
696 */
697
698 #ifndef NO_OLD_FUNC_DECL
699 main(n,args)
700 int n;
701 char **args;
702 {
703 #else
704 int main(int n,char **args) {
705 #endif
706
707 int j;
708 static struct defs d0, *pd0;
709         
710    d0.flgs = 1;          /* These flags dictate            */
711    d0.flgm = 1;          /*     the verbosity of           */
712    d0.flgd = 1;          /*         the program.           */
713    d0.flgl = 1;
714
715    pd0 = &d0;
716
717    for (j=0; j<cq_sections; j++) {
718      d0.rrc=section(j,pd0);
719      d0.crc=d0.crc+d0.rrc;
720      if(d0.flgs != 0) printf("Section %s returned %d.\n",d0.rfs,d0.rrc);
721    }
722
723    if(d0.crc == 0) printf("\nNo errors detected.\n");
724    else printf("\nFailed.\n");
725
726    return d0.crc;
727 }