2 int cbits
; /* No. of bits per char */
6 int ubits
; /* unsigned */
8 int dbits
; /* double */
9 float fprec
; /* Smallest number that can be */
10 float dprec
; /* significantly added to 1. */
11 int flgs
; /* Print return codes, by section */
12 int flgm
; /* Announce machine dependencies */
13 int flgd
; /* give explicit diagnostics */
14 int flgl
; /* Report local return codes. */
15 int rrc
; /* recent return code */
16 int crc
; /* Cumulative return code */
17 char rfs
[8]; /* Return from section */
19 main(n
,args
) /* C REFERENCE MANUAL */
24 /* This program performs a series of tests on a C compiler,
25 based on information in the
29 which appears as Appendix A to the book "The C Programming
30 Language" by Brian W. Kernighan and Dennis M. Ritchie
31 (Prentice-Hall, 1978, $10.95). This Appendix is hereafter
32 referred to as "the Manual".
34 The rules followed in writing this program are:
36 1. The entire program is written in legal C, according
37 to the Manual. It should compile with no error messages,
38 although some warning messages may be produced by some
39 compilers. Failure to compile should be interpreted as
42 2. The program is clean, in that it does not make use
43 of any features of the operating system on which it runs,
44 with the sole exceptions of the printf() function, and an
45 internal "options" routine, which is easily excised.
47 3. No global variables are used, except for the spec-
48 ific purpose of testing the global variable facility.
50 The program is divided into modules having names of the
51 form snnn... These modules correspond to those sections of the
52 Manual, as identified by boldface type headings, in which
53 there is something to test. For example, s241() corresponds
54 to section 2.4.1 of the Manual (Integer constants) and tests
55 the facilities described therein. The module numbering
56 scheme is ambiguous, especially when it names modules
57 referring to more than one section; module s7813, for ex-
58 ample, deals with sections 7.8 through 7.13. Nonetheless,
59 it is surprisingly easy to find a section in the Manual
60 corresponding to a section of code, and vice versa.
62 Note also that there seem to be "holes" in the program,
63 at least from the point of view that there exist sections in the
64 Manual for which there is no corresponding code. Such holes
65 arise from three causes: (a) there is nothing in that partic-
66 ular section to test, (b) everything in that section is tested
67 elsewhere, and (c) it was deemed advisable not to check cer-
68 tain features like preprocessor or listing control features.
70 Modules are called by a main program main(). The mod-
71 ules that are called, and the sequence in which they are
72 called, are determined by two lists in main(), in which the
73 module names appear. The first list (an extern statement)
74 declares the module names to be external. The second (a stat-
75 ic int statement) names the modules and defines the sequence
76 in which they are called. There is no need for these lists
77 to be in the same order, but it is probably a good idea to keep
78 them that way in the interest of clarity. Since there are no
79 cross-linkages between modules, new modules may be added,
80 or old ones deleted, simply by editing the lists, with one
81 exception: section s26, which pokes around at the hardware
82 trying to figure out the characteristics of the machine that
83 it is running on, saves information that is subsequently
84 used by sections s626, s72, and s757. If this program is
85 to be broken up into smallish pieces, say for running on
86 a microcomputer, take care to see that s26 is called before
87 calling any of the latter three sections. The size
88 of the lists, i.e., the number of modules to be called, is
89 not explicitly specified as a program parameter, but is
90 determined dynamically using the sizeof operator.
92 Communication between the main program and the modules
93 takes place in two ways. In all cases, a pointer to a structure
94 is passed to the called module. The structure contains flags
95 that will determine the type of information to be published
96 by the module, and fields that may be written in by the
97 module. The former include "flgm" and "flgd", which, if set
98 to a nonzero value, specify that machine dependencies are to
99 be announced or that error messages are to be printed, re-
100 spectively. The called module's name, and the hardware char-
101 acteristics probed in s26() comprise the latter.
104 Also, in all cases, a return code is returned by the called
105 module. A return code of zero indicates that all has gone well;
106 nonzero indicates otherwise. Since more than one type of error
107 may be detected by a module, the return code is a composite
108 of error indicators, which, individually, are given as numbers
109 that are powers of two. Thus, a return code of 10 indicates
110 that two specific errors, 8 and 2, were detected. Whether or
111 not the codes returned by the modules are printed by the main
112 program is determined by setting "flgs" to 1 (resp. 0).
114 The entire logic of the main program is contained in the
115 half-dozen or so lines at the end. The somewhat cryptic
118 d0.rrc = (*sec[j])(pd0);
120 in the for loop calls the modules. The rest of the code is
121 reasonably straightforward.
123 Finally, in each of the modules, there is the following
129 static char snnner[] = "snnn,er%d\n";
130 static char qsnnn[8] = "snnn ";
137 while(*pt++ = *ps++);
139 used for housekeeping, handshaking and module initialization.
155 s7813(struct defs
*),
167 static int (*sec
[])() = {
191 static struct defs d0
, *pd0
;
193 d0
.flgs
= 1; /* These flags dictate */
194 d0
.flgm
= 1; /* the verbosity of */
195 d0
.flgd
= 1; /* the program. */
200 for (j
=0; j
<sizeof(sec
) / sizeof(sec
[0]); j
++) {
201 d0
.rrc
= (*sec
[j
])(pd0
);
202 d0
.crc
= d0
.crc
+d0
.rrc
;
203 if(d0
.flgs
!= 0) printf("Section %s returned %d.\n",d0
.rfs
,d0
.rrc
);
206 if(d0
.crc
== 0) printf("\nNo errors detected.\n");
207 else printf("\nFailed.\n");
210 s22(pd0
) /* 2.2 Identifiers (Names) */
216 static char s22er
[] = "s22,er%d\n";
217 static char qs22
[8] = "s22 ";
225 while (*pt
++ = *ps
++);
227 /* An identifier is a sequence of letters and digits;
228 the first character must be a letter. The under-
229 score _ counts as a letter. */
235 if(a
+_
+_234
+a234
!= 10) {
237 if(pd0
->flgd
!= 0) printf(s22er
,1);
240 /* Upper and lower case letters are different. */
245 if (pd0
->flgd
!= 0) printf(s22er
,4);
250 s241(pd0
) /* 2.4.1 Integer constants
251 2.4.2 Explicit long constants */
255 static char s241er
[] = "s241,er%d\n";
256 static char qs241
[8] = "s241 ";
259 static long g
[39] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
260 0,6,0,8,0,12,0,16,0,18,0,20,0,24,
261 0,28,0,30,0,32,0,36};
262 long d
[39], o
[39], x
[39];
268 while (*pt
++ = *ps
++);
270 /* An integer constant consisting of a sequence of digits is
271 taken to be octal if it begins with 0 (digit zero), decimal
296 if( pd0
->flgd
!= 0 ) printf(s241er
,1);
299 /* A sequence of digits preceded by 0x or 0X (digit zero)
300 is taken to be a hexadecimal integer. The hexadecimal
301 digits include a or A through f or F with values 10
304 if ( 0x00abcdef != 0xabcdef
305 || 0xabcdef != 0Xabcdef || 0Xabcdef != 0XAbcdef
306 || 0XAbcdef != 0XABcdef || 0XABcdef != 0XABCdef
307 || 0XABCdef != 0XABCDef || 0XABCDef != 0XABCDEf
308 || 0XABCDEf != 0XABCDEF || 0xABCDEF != 11259375 ){
311 if( pd0
->flgd
!= 0 ) printf(s241er
,2);
314 /* A decimal constant whose value exceeds the largest signed
315 machine integer is taken to be long; an octal or hex con-
316 stant which exceeds the largest unsigned machine integer
317 is likewise taken to be long. */
319 if ( sizeof 010000000000 != sizeof(long) /* 2**30 */
320 || sizeof 1073741824 != sizeof(long) /* ditto */
321 || sizeof 0x40000000 != sizeof(long) ){ /* " */
324 if( pd0
->flgd
!= 0 ) printf(s241er
,4);
327 /* A decimal, octal, or hexadecimal constant immediately followed
328 by l (letter ell) or L is a long constant. */
330 if ( sizeof 67l != sizeof(long)
331 || sizeof 67L != sizeof(long)
332 || sizeof 067l != sizeof(long)
333 || sizeof 067L != sizeof(long)
334 || sizeof 0X67l
!= sizeof(long)
335 || sizeof 0x67L
!= sizeof(long) ){
338 if( pd0
-> flgd
!= 0 ) printf(s241er
,8);
341 /* Finally, we test to see that decimal (d), octal (o),
342 and hexadecimal (x) constants representing the same values
343 agree among themselves, and with computed values, at spec-
344 ified points over an appropriate range. The points select-
345 ed here are those with the greatest potential for caus-
346 ing trouble, i.e., zero, 1-16, and values of 2**n and
347 2**n - 1 where n is some multiple of 4 or 6. Unfortunately,
348 just what happens when a value is too big to fit in a
349 long is undefined; however, it would be nice if what
350 happened were at least consistent... */
352 for ( j
=0; j
<17; j
++ ) g
[j
] = j
;
353 for ( j
=18; j
<39; ) {
359 d
[0] = 0; o
[0] = 00; x
[0] = 0x0;
360 d
[1] = 1; o
[1] = 01; x
[1] = 0x1;
361 d
[2] = 2; o
[2] = 02; x
[2] = 0x2;
362 d
[3] = 3; o
[3] = 03; x
[3] = 0x3;
363 d
[4] = 4; o
[4] = 04; x
[4] = 0x4;
364 d
[5] = 5; o
[5] = 05; x
[5] = 0x5;
365 d
[6] = 6; o
[6] = 06; x
[6] = 0x6;
366 d
[7] = 7; o
[7] = 07; x
[7] = 0x7;
367 d
[8] = 8; o
[8] = 010; x
[8] = 0x8;
368 d
[9] = 9; o
[9] = 011; x
[9] = 0x9;
369 d
[10] = 10; o
[10] = 012; x
[10] = 0xa;
370 d
[11] = 11; o
[11] = 013; x
[11] = 0xb;
371 d
[12] = 12; o
[12] = 014; x
[12] = 0xc;
372 d
[13] = 13; o
[13] = 015; x
[13] = 0xd;
373 d
[14] = 14; o
[14] = 016; x
[14] = 0xe;
374 d
[15] = 15; o
[15] = 017; x
[15] = 0xf;
375 d
[16] = 16; o
[16] = 020; x
[16] = 0x10;
376 d
[17] = 63; o
[17] = 077; x
[17] = 0x3f;
377 d
[18] = 64; o
[18] = 0100; x
[18] = 0x40;
378 d
[19] = 255; o
[19] = 0377; x
[19] = 0xff;
379 d
[20] = 256; o
[20] = 0400; x
[20] = 0x100;
380 d
[21] = 4095; o
[21] = 07777; x
[21] = 0xfff;
381 d
[22] = 4096; o
[22] = 010000; x
[22] = 0x1000;
382 d
[23] = 65535; o
[23] = 0177777; x
[23] = 0xffff;
383 d
[24] = 65536; o
[24] = 0200000; x
[24] = 0x10000;
384 d
[25] = 262143; o
[25] = 0777777; x
[25] = 0x3ffff;
385 d
[26] = 262144; o
[26] = 01000000; x
[26] = 0x40000;
386 d
[27] = 1048575; o
[27] = 03777777; x
[27] = 0xfffff;
387 d
[28] = 1048576; o
[28] = 04000000; x
[28] = 0x100000;
388 d
[29] = 16777215; o
[29] = 077777777; x
[29] = 0xffffff;
389 d
[30] = 16777216; o
[30] = 0100000000; x
[30] = 0x1000000;
390 d
[31] = 268435455; o
[31] = 01777777777; x
[31] = 0xfffffff;
391 d
[32] = 268435456; o
[32] = 02000000000; x
[32] = 0x10000000;
392 d
[33] = 1073741823; o
[33] = 07777777777; x
[33] = 0x3fffffff;
393 d
[34] = 1073741824; o
[34] = 010000000000; x
[34] = 0x40000000;
394 d
[35] = 4294967295; o
[35] = 037777777777; x
[35] = 0xffffffff;
395 d
[36] = 4294967296; o
[36] = 040000000000; x
[36] = 0x100000000;
396 d
[37] = 68719476735; o
[37] = 0777777777777; x
[37] = 0xfffffffff;
397 d
[38] = 68719476736; o
[38] = 01000000000000; x
[38] = 0x1000000000;
401 for (j
=0; j
<39; j
++){
406 if( pd0
-> flgm
!= 0 ) {
407 /* printf(s241er,16); save in case opinions change... */
408 printf("Decimal and octal/hex constants sometimes give\n");
409 printf(" different results when assigned to longs.\n");
411 /* lrc = 1; save... */
415 if (lrc
!= 0) rc
=16;
420 long pow2(n
) /* Calculate 2**n by multiplying, not shifting */
428 s243(pd0
) /* 2.4.3 Character constants */
431 static char s243er
[] = "s243,er%d\n";
432 static char qs243
[8] = "s243 ";
440 while(*pt
++ = *ps
++);
442 /* One of the problems that arises when testing character constants
443 is that of definition: What, exactly, is the character set?
444 In order to guarantee a certain amount of machine independence,
445 the character set we will use here is the set of characters writ-
446 able as escape sequences in C, plus those characters used in writ-
447 ing C programs, i.e.,
450 ABCDEFGHIJKLMNOPQRSTUVWXYZ 26
451 abcdefghijklmnopqrstuvwxyz 26
455 ~!"#%&()_=-^|{}[]+;*:<>,.?/ 27
456 extra special characters:
468 Any specific implementation of C may of course support additional
471 /* Since the value of a character constant is the numerical value
472 of the character in the machine's character set, there should
473 be a one-to-one correspondence between characters and values. */
477 chars
['a'] = 1; chars
['A'] = 1; chars
['~'] = 1; chars
['0'] = 1;
478 chars
['b'] = 1; chars
['B'] = 1; chars
['!'] = 1; chars
['1'] = 1;
479 chars
['c'] = 1; chars
['C'] = 1; chars
['"'] = 1; chars
['2'] = 1;
480 chars
['d'] = 1; chars
['D'] = 1; chars
['#'] = 1; chars
['3'] = 1;
481 chars
['e'] = 1; chars
['E'] = 1; chars
['%'] = 1; chars
['4'] = 1;
482 chars
['f'] = 1; chars
['F'] = 1; chars
['&'] = 1; chars
['5'] = 1;
483 chars
['g'] = 1; chars
['G'] = 1; chars
['('] = 1; chars
['6'] = 1;
484 chars
['h'] = 1; chars
['H'] = 1; chars
[')'] = 1; chars
['7'] = 1;
485 chars
['i'] = 1; chars
['I'] = 1; chars
['_'] = 1; chars
['8'] = 1;
486 chars
['j'] = 1; chars
['J'] = 1; chars
['='] = 1; chars
['9'] = 1;
487 chars
['k'] = 1; chars
['K'] = 1; chars
['-'] = 1;
488 chars
['l'] = 1; chars
['L'] = 1; chars
['^'] = 1;
489 chars
['m'] = 1; chars
['M'] = 1; chars
['|'] = 1; chars
['\n'] = 1;
490 chars
['n'] = 1; chars
['N'] = 1; chars
['\t'] = 1;
491 chars
['o'] = 1; chars
['O'] = 1; chars
['{'] = 1; chars
['\b'] = 1;
492 chars
['p'] = 1; chars
['P'] = 1; chars
['}'] = 1; chars
['\r'] = 1;
493 chars
['q'] = 1; chars
['Q'] = 1; chars
['['] = 1; chars
['\f'] = 1;
494 chars
['r'] = 1; chars
['R'] = 1; chars
[']'] = 1;
495 chars
['s'] = 1; chars
['S'] = 1; chars
['+'] = 1; chars
['\\'] = 1;
496 chars
['t'] = 1; chars
['T'] = 1; chars
[';'] = 1; chars
['\''] = 1;
497 chars
['u'] = 1; chars
['U'] = 1; chars
['*'] = 1;
498 chars
['v'] = 1; chars
['V'] = 1; chars
[':'] = 1; chars
['\0'] = 1;
499 chars
['w'] = 1; chars
['W'] = 1; chars
['<'] = 1; chars
[' '] = 1;
500 chars
['x'] = 1; chars
['X'] = 1; chars
['>'] = 1;
501 chars
['y'] = 1; chars
['Y'] = 1; chars
[','] = 1;
502 chars
['z'] = 1; chars
['Z'] = 1; chars
['.'] = 1;
506 if(sumof(chars
) != 98){
508 if(pd0
->flgd
!= 0) printf(s243er
,1);
511 /* Finally, the escape \ddd consists of the backslash followed
512 by 1, 2, or 3 octal digits which are taken to specify the
513 desired character. */
515 if( '\0' != 0 || '\01' != 1 || '\02' != 2
516 || '\03' != 3 || '\04' != 4 || '\05' != 5
517 || '\06' != 6 || '\07' != 7 || '\10' != 8
518 || '\17' != 15 || '\20' != 16 || '\77' != 63
519 || '\100' != 64 || '\177' != 127 ){
522 if(pd0
->flgd
!= 0) printf(s243er
,8);
532 for (j
=0; j
<256; j
++) *x
++ = 0;
543 for(j
=0; j
<256; j
++) total
= total
+ *p
++;
551 static char s244er
[] = "s244,er%d\n";
552 static char qs244
[8] = "s244 ";
557 while(*pt
++ = *ps
++);
561 /* Unfortunately, there's not a lot we can do with floating constants.
562 We can check to see that the various representations can be com-
563 piled, that the conversion is such that they yield the same hard-
564 ware representations in all cases, and that all representations
565 thus checked are double precision. */
577 for (j
=0; j
<7; j
++) if(a
[j
] != a
[j
+1]) lrc
= 1;
580 if(pd0
->flgd
!= 0) printf(s244er
,1);
584 if ( (sizeof .1250E+04 ) != sizeof(double)
585 || (sizeof 1.250E3
) != sizeof(double)
586 || (sizeof 12.50E02
) != sizeof(double)
587 || (sizeof 1.250e+1 ) != sizeof(double)
588 || (sizeof 1250e00
) != sizeof(double)
589 || (sizeof 12500.e
-01) != sizeof(double)
590 || (sizeof 125000e-2 ) != sizeof(double)
591 || (sizeof 1250. ) != sizeof(double)){
593 if(pd0
->flgd
!= 0) printf(s244er
,2);
604 static char s25er
[] = "s25,er%d\n";
605 static char qs25
[8] = "s25 ";
610 while(*pt
++ = *ps
++);
613 /* A string is a sequence of characters surrounded by double
614 quotes, as in "...". */
618 /* A string has type "array of characters" and storage class
619 static and is initialized with the given characters. */
621 if ( s
[0] != s
[1] || s
[1] != s
[2]
625 if(pd0
->flgd
!= 0) printf(s25er
,1);
628 /* The compiler places a null byte \0 at the end of each string
629 so the program which scans the string can find its end. */
633 if(pd0
->flgd
!= 0) printf(s25er
,4);
636 /* In a string, the double quote character " must be preceded
639 if( ".\"."[1] != '"' ){
641 if(pd0
->flgd
!= 0) printf(s25er
,8);
644 /* In addition, the same escapes described for character constants
647 s
= "\n\t\b\r\f\\\'";
658 if( pd0
->flgd
!= 0) printf(s25er
,16);
661 /* Finally, a \ and an immediately following newline are ignored */
667 for (j
=0; j
<sizeof "queep!"; j
++) if(s
[j
] != s2
[j
]) lrc
= 1;
670 if(pd0
->flgd
!= 0) printf(s25er
,32);
674 s26(pd0
) /* 2.6 Hardware Characteristics */
677 static char qs26
[8] = "s26 ";
680 float temp
, one
, delta
;
682 static char s
[] = "%3d bits in %ss.\n";
683 static char s2
[] = "%e is the least number that can be added to 1. (%s).\n";
688 while(*pt
++ = *ps
++);
690 /* Here, we shake the machinery a little to see what falls
691 out. First, we find out how many bits are in a char. */
699 pd0
->cbits
= pd0
->cbits
+1;
701 /* That information lets us determine the size of everything else. */
703 pd0
->ibits
= pd0
->cbits
* sizeof(int);
704 pd0
->sbits
= pd0
->cbits
* sizeof(short);
705 pd0
->lbits
= pd0
->cbits
* sizeof(long);
706 pd0
->ubits
= pd0
->cbits
* sizeof(unsigned);
707 pd0
->fbits
= pd0
->cbits
* sizeof(float);
708 pd0
->dbits
= pd0
->cbits
* sizeof(double);
710 /* We have now almost reconstructed the table in section 2.6, the
711 exception being the range of the floating point hardware.
712 Now there are just so many ways to conjure up a floating point
713 representation system that it's damned near impossible to guess
714 what's going on by writing a program to interpret bit patterns.
715 Further, the information isn't all that useful, if we consider
716 the fact that machines that won't handle numbers between 10**30
717 and 10**-30 are very hard to find, and that people playing with
718 numbers outside that range have a lot more to worry about than
719 just the capacity of the characteristic.
721 A much more useful measure is the precision, which can be ex-
722 pressed in terms of the smallest number that can be added to
723 1. without loss of significance. We calculate that here, for
733 pd0
->fprec
= delta
* 4.;
737 while(tempd
!= oned
) {
741 pd0
->dprec
= delta
* 4.;
743 /* Now, if anyone's interested, we publish the results. */
746 printf(s
,pd0
->cbits
,"char");
747 printf(s
,pd0
->ibits
,"int");
748 printf(s
,pd0
->sbits
,"short");
749 printf(s
,pd0
->lbits
,"long");
750 printf(s
,pd0
->ubits
,"unsigned");
751 printf(s
,pd0
->fbits
,"float");
752 printf(s
,pd0
->dbits
,"double");
753 printf(s2
,pd0
->fprec
,"float");
754 printf(s2
,pd0
->dprec
,"double");
756 /* Since we are only exploring and perhaps reporting, but not
757 testing any features, we cannot return an error code. */
762 s4(pd0
) /* 4. What's in a name? */
765 static char s4er
[] = "s4,er%d\n";
766 static char qs4
[8] = "s4 ";
770 short sint
; /* short integer, for size test */
771 int pint
; /* plain */
772 long lint
; /* long */
780 while(*pt
++ = *ps
++);
782 /* There are four declarable storage classes: automatic,
783 static, external, and register. Automatic variables have
784 been dealt with extensively thus far, and will not be specif-
785 ically treated in this section. Register variables are treated
788 Static variables are local to a block, but retain their
789 values upon reentry to a block, even after control has left
793 if(svtest(j
) != zero()){
795 if(pd0
->flgd
!= 0) printf(s4er
,1);
799 /* External variables exist and retain their values throughout
800 the execution of the entire program, and may be used for comm-
801 unication between functions, even separately compiled functions.
807 if(pd0
->flgd
!= 0) printf(s4er
,2);
810 Characters have been tested elsewhere (in s243).
812 Up to three sizes of integer, declared short int, int, and
813 long int, are available. Longer integers provide no less storage
814 than shorter ones, but implementation may make either short
815 integers, or long integers, or both, equivalent to plain
819 if(sizeof lint
< sizeof pint
|| sizeof pint
< sizeof sint
){
822 if(pd0
->flgd
!= 0) printf(s4er
,4);
825 /* Unsigned integers, declared unsigned, obey the laws of
826 arithmetic modulo 2**n, where n is the number of bits in the
832 for(j
=0; j
<(sizeof target
)*pd0
->cbits
; j
++){
838 if(mask
!= 1 || target
!= 0){
841 if(pd0
->flgd
!= 0) printf(s4er
,8);
857 case 1: if(k
!= 1978) rc
= 1;
864 case 2: if(k
!= 1929) rc
= 1;
870 zero(){ /* Returns a value of zero, possibly */
871 static k
; /* with side effects, as it's called */
872 int rc
; /* alternately with svtest, above, */
873 k
= 2; /* and has the same internal storage */
874 rc
= 0; /* requirements. */
878 if(extvar
!= 1066) return 1;
881 s61(pd0
) /* Characters and integers */
884 static char s61er
[] = "s61,er%d\n";
885 static char qs61
[8] = "s61 ";
886 short from
, shortint
;
887 long int to
, longint
;
893 static char upper_alpha
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
894 static char lower_alpha
[] = "abcdefghijklmnopqrstuvwxyz";
895 static char numbers
[] = "0123456789";
896 static char special_characters
[] = "~!\"#%&()_=-^|{}[]+;*:<>,.?/";
897 static char extra_special_characters
[] = "\n\t\b\r\f\\\'";
898 static char blank_and_NUL
[] = " \0";
904 while (*pt
++ = *ps
++);
906 /* A character or a short integer may be used wherever
907 an integer may be used. In all cases, the value is converted
908 to integer. This principle is extensively used throughout this
909 program, and will not be explicitly tested here. */
911 /* Conversion of a shorter integer to a longer always
912 involves sign extension. */
919 if(pd0
->flgd
!= 0) printf(s61er
,1);
922 /* It is guaranteed that a member of the standard char-
923 acter set is nonnegative. */
928 pc
[3] = special_characters
;
929 pc
[4] = extra_special_characters
;
930 pc
[5] = blank_and_NUL
;
934 while(*pc
[j
]) if(*pc
[j
]++ < 0) lrc
=1;
938 if(pd0
->flgd
!= 0) printf(s61er
,2);
941 /* When a longer integer is converted to a shorter or
942 to a char, it is truncated on the left; excess bits are
945 longint
= 1048579; /* =2**20+3 */
949 if((shortint
!= longint
&& shortint
!= 3) ||
950 (charint
!= longint
&& charint
!= 3)) {
952 if(pd0
->flgd
!= 0) printf(s61er
,8);
957 s626(pd0
) /* 6.2 Float and double */
958 /* 6.3 Floating and integral */
959 /* 6.4 Pointers and integers */
961 /* 6.6 Arithmetic conversions */
964 static char s626er
[] = "s626,er%d\n";
965 static char qs626
[8] = "s626 ";
968 float eps
, f1
, f2
, f3
, f4
, f
;
969 long lint1
, lint2
, l
, ls
;
978 while (*pt
++ = *ps
++);
980 /* Conversions of integral values to floating type are
987 for(j
=0;j
<pd0
->lbits
-2;j
++){
989 lint2
= (lint2
<<1)|lint1
;
993 if(f1
>2.*pd0
->fprec
){
996 if(pd0
->flgd
!= 0) printf(s626er
,2);
999 /* Pointer-integer combinations are discussed in s74,
1000 "Additive operators". The unsigned-int combination
1005 i
= 125; is
= 15625;
1006 u
= 125; us
= 15625;
1007 l
= 125; ls
= 15625;
1009 d
= 125.; ds
= 15625.;
1011 for(j
=0;j
<28;j
++) t
[j
] = 0;
1013 if(c
*c
!= is
) t
[ 0] = 1;
1014 if(s
*c
!= is
) t
[ 1] = 1;
1015 if(s
*s
!= is
) t
[ 2] = 1;
1016 if(i
*c
!= is
) t
[ 3] = 1;
1017 if(i
*s
!= is
) t
[ 4] = 1;
1018 if(i
*i
!= is
) t
[ 5] = 1;
1019 if(u
*c
!= us
) t
[ 6] = 1;
1020 if(u
*s
!= us
) t
[ 7] = 1;
1021 if(u
*i
!= us
) t
[ 8] = 1;
1022 if(u
*u
!= us
) t
[ 9] = 1;
1023 if(l
*c
!= ls
) t
[10] = 1;
1024 if(l
*s
!= ls
) t
[11] = 1;
1025 if(l
*i
!= ls
) t
[12] = 1;
1026 if(l
*u
!= us
) t
[13] = 1;
1027 if(l
*l
!= ls
) t
[14] = 1;
1028 if(f
*c
!= ds
) t
[15] = 1;
1029 if(f
*s
!= ds
) t
[16] = 1;
1030 if(f
*i
!= ds
) t
[17] = 1;
1031 if(f
*u
!= ds
) t
[18] = 1;
1032 if(f
*l
!= ds
) t
[19] = 1;
1033 if(f
*f
!= ds
) t
[20] = 1;
1034 if(d
*c
!= ds
) t
[21] = 1;
1035 if(d
*s
!= ds
) t
[22] = 1;
1036 if(d
*i
!= ds
) t
[23] = 1;
1037 if(d
*u
!= ds
) t
[24] = 1;
1038 if(d
*l
!= ds
) t
[25] = 1;
1039 if(d
*f
!= ds
) t
[26] = 1;
1040 if(d
*d
!= ds
) t
[27] = 1;
1043 for(j
=0; j
<28; j
++) t0
= t0
+t
[j
];
1052 for(j
=0;j
<28;j
++) printf("%d",t
[j
]);
1057 /* When an unsigned integer is converted to long,
1058 the value of the result is the same numerically
1059 as that of the unsigned integer. */
1061 l
= (unsigned)0100000;
1062 if((long)l
> (unsigned)0100000){
1065 if(pd0
->flgd
!= 0) printf(s626er
,8);
1070 s71(pd0
) /* 7.1 Primary expressions */
1073 static char s71er
[] = "s71,er%d\n";
1074 static char qs71
[8] = "s71 ";
1077 static char q
= 'q';
1078 int x
[10], McCarthy(), clobber(), a
, b
, *p
;
1082 while (*pt
++ = *ps
++);
1084 /* Testing of expressions and operators is quite complicated,
1085 because (a) problems are apt to surface in queer combinations
1086 of operators and operands, rather than in isolation,
1087 and (b) the number of expressions needed to provoke a case
1088 of improper behaviour may be quite large. Hence, we take the
1089 following approach: for this section, and for subsequent
1090 sections through 7.15, we will check the primitive operations
1091 in isolation, thus verifying that the primitives work,
1092 after a fashion. The job of testing combinations, we will
1093 leave to a separate, machine-generated program, to be included
1094 in the C test package at some later date.
1097 /* A string is a primary expression. The identifier points to
1098 the first character of a string.
1103 if(pd0
->flgd
!= 0) printf(s71er
,1);
1105 /* A parenthesized expression is a primary expression whose
1106 type and value are the same as those of the unadorned
1111 if(pd0
->flgd
!= 0) printf(s71er
,2);
1114 /* A primary expression followed by an expression in square
1115 brackets is a primary expression. The intuitive meaning is
1116 that of a subscript. The expression E1[E2] is identical
1117 (by definition) to *((E1)+(E2)).
1121 if(x
[5] != 1942 || x
[5] != *((x
)+(5))){
1123 if(pd0
->flgd
!= 0) printf(s71er
,4);
1126 /* If the various flavors of function calls didn't work, we
1127 would never have gotten this far; however, we do need to
1128 show that functions can be recursive...
1131 if ( McCarthy(-5) != 91){
1133 if(pd0
->flgd
!= 0) printf(s71er
,8);
1136 /* and that argument passing is strictly by value. */
1144 if(a
!= 2 || b
!= 2){
1146 if(pd0
->flgd
!= 0) printf(s71er
,16);
1149 /* Finally, structures and unions are addressed thusly: */
1151 if(pd0
->dprec
!= (*pd0
).dprec
){
1153 if(pd0
->flgd
!= 0) printf(s71er
,32);
1161 if(x
>100) return x
-10;
1162 else return McCarthy( McCarthy(x
+11));
1170 s714(pd0
) /* 7.14 Assignment operators */
1173 static char f
[] = "Local error %d.\n";
1174 static char s714er
[] = "s714,er%d\n";
1175 static char qs714
[8] = "s714 ";
1176 register int prlc
, lrc
;
1191 while (*pt
++ = *ps
++);
1193 /* This section tests the assignment operators.
1195 It is an exhaustive test of all assignment statements
1200 where vl and vr are variables from the set
1201 {char,short,int,long,unsigned,float,double} and op is
1202 one of the assignment operators. There are 395 such
1205 The initial values for the variables have been chosen
1206 so that both the initial values and the results will
1207 "fit" in just about any implementation, and that the re-
1208 sults will be such that they test for the proper form-
1209 ation of composite operators, rather than checking for
1210 the valid operation of those operators' components.
1211 For example, in checking >>=, we want to verify that
1212 a right shift and a move take place, rather than
1213 whether or not there may be some peculiarities about
1214 the right shift. Such tests have been made previously,
1215 and to repeat them here would be to throw out a red
1218 The table below lists the operators, assignment targets,
1219 initial values for left and right operands, and the
1220 expected values of the results.
1223 = += -= *= /= %= >>= <<= &= ^= |=
1224 char 2 7 3 10 2 1 1 20 8 6 14
1225 short 2 7 3 10 2 1 1 20 8 6 14
1226 int 2 7 3 10 2 1 1 20 8 6 14
1227 long 2 7 3 10 2 1 1 20 8 6 14
1228 unsigned 2 7 3 10 2 1 1 20 8 6 14
1229 float 2 7 3 10 2.5 | |
1230 double 2 7 3 10 2.5 | |
1232 initial (5,2) | (5,2) | (12,10)
1234 The following machine-generated program reflects the
1235 tests described in the table.
1242 if(prlc
) printf(f
,lrc
);
1248 if(prlc
) printf(f
,lrc
);
1254 if(prlc
) printf(f
,lrc
);
1260 if(prlc
) printf(f
,lrc
);
1266 if(prlc
) printf(f
,lrc
);
1272 if(prlc
) printf(f
,lrc
);
1278 if(prlc
) printf(f
,lrc
);
1284 if(prlc
) printf(f
,lrc
);
1290 if(prlc
) printf(f
,lrc
);
1296 if(prlc
) printf(f
,lrc
);
1302 if(prlc
) printf(f
,lrc
);
1308 if(prlc
) printf(f
,lrc
);
1314 if(prlc
) printf(f
,lrc
);
1320 if(prlc
) printf(f
,lrc
);
1326 if(prlc
) printf(f
,lrc
);
1332 if(prlc
) printf(f
,lrc
);
1338 if(prlc
) printf(f
,lrc
);
1344 if(prlc
) printf(f
,lrc
);
1350 if(prlc
) printf(f
,lrc
);
1356 if(prlc
) printf(f
,lrc
);
1362 if(prlc
) printf(f
,lrc
);
1368 if(prlc
) printf(f
,lrc
);
1374 if(prlc
) printf(f
,lrc
);
1380 if(prlc
) printf(f
,lrc
);
1386 if(prlc
) printf(f
,lrc
);
1392 if(prlc
) printf(f
,lrc
);
1398 if(prlc
) printf(f
,lrc
);
1404 if(prlc
) printf(f
,lrc
);
1410 if(prlc
) printf(f
,lrc
);
1416 if(prlc
) printf(f
,lrc
);
1422 if(prlc
) printf(f
,lrc
);
1428 if(prlc
) printf(f
,lrc
);
1434 if(prlc
) printf(f
,lrc
);
1440 if(prlc
) printf(f
,lrc
);
1446 if(prlc
) printf(f
,lrc
);
1452 if(prlc
) printf(f
,lrc
);
1458 if(prlc
) printf(f
,lrc
);
1464 if(prlc
) printf(f
,lrc
);
1470 if(prlc
) printf(f
,lrc
);
1476 if(prlc
) printf(f
,lrc
);
1482 if(prlc
) printf(f
,lrc
);
1488 if(prlc
) printf(f
,lrc
);
1494 if(prlc
) printf(f
,lrc
);
1500 if(prlc
) printf(f
,lrc
);
1506 if(prlc
) printf(f
,lrc
);
1512 if(prlc
) printf(f
,lrc
);
1518 if(prlc
) printf(f
,lrc
);
1524 if(prlc
) printf(f
,lrc
);
1530 if(prlc
) printf(f
,lrc
);
1536 if(prlc
) printf(f
,lrc
);
1542 if(prlc
) printf(f
,lrc
);
1548 if(prlc
) printf(f
,lrc
);
1554 if(prlc
) printf(f
,lrc
);
1560 if(prlc
) printf(f
,lrc
);
1566 if(prlc
) printf(f
,lrc
);
1572 if(prlc
) printf(f
,lrc
);
1578 if(prlc
) printf(f
,lrc
);
1584 if(prlc
) printf(f
,lrc
);
1590 if(prlc
) printf(f
,lrc
);
1596 if(prlc
) printf(f
,lrc
);
1602 if(prlc
) printf(f
,lrc
);
1608 if(prlc
) printf(f
,lrc
);
1614 if(prlc
) printf(f
,lrc
);
1620 if(prlc
) printf(f
,lrc
);
1626 if(prlc
) printf(f
,lrc
);
1632 if(prlc
) printf(f
,lrc
);
1638 if(prlc
) printf(f
,lrc
);
1644 if(prlc
) printf(f
,lrc
);
1650 if(prlc
) printf(f
,lrc
);
1656 if(prlc
) printf(f
,lrc
);
1662 if(prlc
) printf(f
,lrc
);
1668 if(prlc
) printf(f
,lrc
);
1674 if(prlc
) printf(f
,lrc
);
1680 if(prlc
) printf(f
,lrc
);
1686 if(prlc
) printf(f
,lrc
);
1692 if(prlc
) printf(f
,lrc
);
1698 if(prlc
) printf(f
,lrc
);
1704 if(prlc
) printf(f
,lrc
);
1710 if(prlc
) printf(f
,lrc
);
1716 if(prlc
) printf(f
,lrc
);
1722 if(prlc
) printf(f
,lrc
);
1728 if(prlc
) printf(f
,lrc
);
1734 if(prlc
) printf(f
,lrc
);
1740 if(prlc
) printf(f
,lrc
);
1746 if(prlc
) printf(f
,lrc
);
1752 if(prlc
) printf(f
,lrc
);
1758 if(prlc
) printf(f
,lrc
);
1764 if(prlc
) printf(f
,lrc
);
1770 if(prlc
) printf(f
,lrc
);
1776 if(prlc
) printf(f
,lrc
);
1782 if(prlc
) printf(f
,lrc
);
1788 if(prlc
) printf(f
,lrc
);
1794 if(prlc
) printf(f
,lrc
);
1800 if(prlc
) printf(f
,lrc
);
1806 if(prlc
) printf(f
,lrc
);
1812 if(prlc
) printf(f
,lrc
);
1818 if(prlc
) printf(f
,lrc
);
1824 if(prlc
) printf(f
,lrc
);
1830 if(prlc
) printf(f
,lrc
);
1836 if(prlc
) printf(f
,lrc
);
1842 if(prlc
) printf(f
,lrc
);
1848 if(prlc
) printf(f
,lrc
);
1854 if(prlc
) printf(f
,lrc
);
1860 if(prlc
) printf(f
,lrc
);
1866 if(prlc
) printf(f
,lrc
);
1872 if(prlc
) printf(f
,lrc
);
1878 if(prlc
) printf(f
,lrc
);
1884 if(prlc
) printf(f
,lrc
);
1890 if(prlc
) printf(f
,lrc
);
1896 if(prlc
) printf(f
,lrc
);
1902 if(prlc
) printf(f
,lrc
);
1908 if(prlc
) printf(f
,lrc
);
1914 if(prlc
) printf(f
,lrc
);
1920 if(prlc
) printf(f
,lrc
);
1926 if(prlc
) printf(f
,lrc
);
1932 if(prlc
) printf(f
,lrc
);
1938 if(prlc
) printf(f
,lrc
);
1944 if(prlc
) printf(f
,lrc
);
1950 if(prlc
) printf(f
,lrc
);
1956 if(prlc
) printf(f
,lrc
);
1962 if(prlc
) printf(f
,lrc
);
1968 if(prlc
) printf(f
,lrc
);
1974 if(prlc
) printf(f
,lrc
);
1980 if(prlc
) printf(f
,lrc
);
1986 if(prlc
) printf(f
,lrc
);
1992 if(prlc
) printf(f
,lrc
);
1998 if(prlc
) printf(f
,lrc
);
2004 if(prlc
) printf(f
,lrc
);
2010 if(prlc
) printf(f
,lrc
);
2016 if(prlc
) printf(f
,lrc
);
2022 if(prlc
) printf(f
,lrc
);
2028 if(prlc
) printf(f
,lrc
);
2034 if(prlc
) printf(f
,lrc
);
2040 if(prlc
) printf(f
,lrc
);
2046 if(prlc
) printf(f
,lrc
);
2052 if(prlc
) printf(f
,lrc
);
2058 if(prlc
) printf(f
,lrc
);
2064 if(prlc
) printf(f
,lrc
);
2070 if(prlc
) printf(f
,lrc
);
2076 if(prlc
) printf(f
,lrc
);
2082 if(prlc
) printf(f
,lrc
);
2088 if(prlc
) printf(f
,lrc
);
2094 if(prlc
) printf(f
,lrc
);
2100 if(prlc
) printf(f
,lrc
);
2106 if(prlc
) printf(f
,lrc
);
2112 if(prlc
) printf(f
,lrc
);
2118 if(prlc
) printf(f
,lrc
);
2124 if(prlc
) printf(f
,lrc
);
2130 if(prlc
) printf(f
,lrc
);
2136 if(prlc
) printf(f
,lrc
);
2142 if(prlc
) printf(f
,lrc
);
2148 if(prlc
) printf(f
,lrc
);
2154 if(prlc
) printf(f
,lrc
);
2160 if(prlc
) printf(f
,lrc
);
2166 if(prlc
) printf(f
,lrc
);
2172 if(prlc
) printf(f
,lrc
);
2178 if(prlc
) printf(f
,lrc
);
2184 if(prlc
) printf(f
,lrc
);
2190 if(prlc
) printf(f
,lrc
);
2196 if(prlc
) printf(f
,lrc
);
2202 if(prlc
) printf(f
,lrc
);
2208 if(prlc
) printf(f
,lrc
);
2214 if(prlc
) printf(f
,lrc
);
2220 if(prlc
) printf(f
,lrc
);
2226 if(prlc
) printf(f
,lrc
);
2232 if(prlc
) printf(f
,lrc
);
2238 if(prlc
) printf(f
,lrc
);
2244 if(prlc
) printf(f
,lrc
);
2250 if(prlc
) printf(f
,lrc
);
2256 if(prlc
) printf(f
,lrc
);
2262 if(prlc
) printf(f
,lrc
);
2268 if(prlc
) printf(f
,lrc
);
2274 if(prlc
) printf(f
,lrc
);
2280 if(prlc
) printf(f
,lrc
);
2286 if(prlc
) printf(f
,lrc
);
2292 if(prlc
) printf(f
,lrc
);
2298 if(prlc
) printf(f
,lrc
);
2304 if(prlc
) printf(f
,lrc
);
2310 if(prlc
) printf(f
,lrc
);
2316 if(prlc
) printf(f
,lrc
);
2322 if(prlc
) printf(f
,lrc
);
2328 if(prlc
) printf(f
,lrc
);
2334 if(prlc
) printf(f
,lrc
);
2340 if(prlc
) printf(f
,lrc
);
2346 if(prlc
) printf(f
,lrc
);
2352 if(prlc
) printf(f
,lrc
);
2358 if(prlc
) printf(f
,lrc
);
2364 if(prlc
) printf(f
,lrc
);
2370 if(prlc
) printf(f
,lrc
);
2376 if(prlc
) printf(f
,lrc
);
2382 if(prlc
) printf(f
,lrc
);
2388 if(prlc
) printf(f
,lrc
);
2394 if(prlc
) printf(f
,lrc
);
2400 if(prlc
) printf(f
,lrc
);
2406 if(prlc
) printf(f
,lrc
);
2412 if(prlc
) printf(f
,lrc
);
2418 if(prlc
) printf(f
,lrc
);
2424 if(prlc
) printf(f
,lrc
);
2430 if(prlc
) printf(f
,lrc
);
2436 if(prlc
) printf(f
,lrc
);
2442 if(prlc
) printf(f
,lrc
);
2448 if(prlc
) printf(f
,lrc
);
2454 if(prlc
) printf(f
,lrc
);
2460 if(prlc
) printf(f
,lrc
);
2466 if(prlc
) printf(f
,lrc
);
2472 if(prlc
) printf(f
,lrc
);
2478 if(prlc
) printf(f
,lrc
);
2484 if(prlc
) printf(f
,lrc
);
2490 if(prlc
) printf(f
,lrc
);
2496 if(prlc
) printf(f
,lrc
);
2502 if(prlc
) printf(f
,lrc
);
2508 if(prlc
) printf(f
,lrc
);
2514 if(prlc
) printf(f
,lrc
);
2520 if(prlc
) printf(f
,lrc
);
2526 if(prlc
) printf(f
,lrc
);
2532 if(prlc
) printf(f
,lrc
);
2538 if(prlc
) printf(f
,lrc
);
2544 if(prlc
) printf(f
,lrc
);
2550 if(prlc
) printf(f
,lrc
);
2556 if(prlc
) printf(f
,lrc
);
2562 if(prlc
) printf(f
,lrc
);
2568 if(prlc
) printf(f
,lrc
);
2574 if(prlc
) printf(f
,lrc
);
2580 if(prlc
) printf(f
,lrc
);
2586 if(prlc
) printf(f
,lrc
);
2592 if(prlc
) printf(f
,lrc
);
2598 if(prlc
) printf(f
,lrc
);
2604 if(prlc
) printf(f
,lrc
);
2610 if(prlc
) printf(f
,lrc
);
2616 if(prlc
) printf(f
,lrc
);
2622 if(prlc
) printf(f
,lrc
);
2628 if(prlc
) printf(f
,lrc
);
2634 if(prlc
) printf(f
,lrc
);
2640 if(prlc
) printf(f
,lrc
);
2646 if(prlc
) printf(f
,lrc
);
2652 if(prlc
) printf(f
,lrc
);
2658 if(prlc
) printf(f
,lrc
);
2664 if(prlc
) printf(f
,lrc
);
2670 if(prlc
) printf(f
,lrc
);
2676 if(prlc
) printf(f
,lrc
);
2682 if(prlc
) printf(f
,lrc
);
2688 if(prlc
) printf(f
,lrc
);
2694 if(prlc
) printf(f
,lrc
);
2700 if(prlc
) printf(f
,lrc
);
2706 if(prlc
) printf(f
,lrc
);
2712 if(prlc
) printf(f
,lrc
);
2718 if(prlc
) printf(f
,lrc
);
2724 if(prlc
) printf(f
,lrc
);
2730 if(prlc
) printf(f
,lrc
);
2736 if(prlc
) printf(f
,lrc
);
2742 if(prlc
) printf(f
,lrc
);
2748 if(prlc
) printf(f
,lrc
);
2754 if(prlc
) printf(f
,lrc
);
2760 if(prlc
) printf(f
,lrc
);
2766 if(prlc
) printf(f
,lrc
);
2772 if(prlc
) printf(f
,lrc
);
2778 if(prlc
) printf(f
,lrc
);
2784 if(prlc
) printf(f
,lrc
);
2790 if(prlc
) printf(f
,lrc
);
2796 if(prlc
) printf(f
,lrc
);
2802 if(prlc
) printf(f
,lrc
);
2808 if(prlc
) printf(f
,lrc
);
2814 if(prlc
) printf(f
,lrc
);
2820 if(prlc
) printf(f
,lrc
);
2826 if(prlc
) printf(f
,lrc
);
2832 if(prlc
) printf(f
,lrc
);
2838 if(prlc
) printf(f
,lrc
);
2844 if(prlc
) printf(f
,lrc
);
2850 if(prlc
) printf(f
,lrc
);
2856 if(prlc
) printf(f
,lrc
);
2862 if(prlc
) printf(f
,lrc
);
2868 if(prlc
) printf(f
,lrc
);
2874 if(prlc
) printf(f
,lrc
);
2880 if(prlc
) printf(f
,lrc
);
2886 if(prlc
) printf(f
,lrc
);
2892 if(prlc
) printf(f
,lrc
);
2898 if(prlc
) printf(f
,lrc
);
2904 if(prlc
) printf(f
,lrc
);
2910 if(prlc
) printf(f
,lrc
);
2916 if(prlc
) printf(f
,lrc
);
2922 if(prlc
) printf(f
,lrc
);
2928 if(prlc
) printf(f
,lrc
);
2934 if(prlc
) printf(f
,lrc
);
2940 if(prlc
) printf(f
,lrc
);
2946 if(prlc
) printf(f
,lrc
);
2952 if(prlc
) printf(f
,lrc
);
2958 if(prlc
) printf(f
,lrc
);
2964 if(prlc
) printf(f
,lrc
);
2970 if(prlc
) printf(f
,lrc
);
2976 if(prlc
) printf(f
,lrc
);
2982 if(prlc
) printf(f
,lrc
);
2988 if(prlc
) printf(f
,lrc
);
2994 if(prlc
) printf(f
,lrc
);
3000 if(prlc
) printf(f
,lrc
);
3006 if(prlc
) printf(f
,lrc
);
3012 if(prlc
) printf(f
,lrc
);
3018 if(prlc
) printf(f
,lrc
);
3024 if(prlc
) printf(f
,lrc
);
3030 if(prlc
) printf(f
,lrc
);
3036 if(prlc
) printf(f
,lrc
);
3042 if(prlc
) printf(f
,lrc
);
3048 if(prlc
) printf(f
,lrc
);
3054 if(prlc
) printf(f
,lrc
);
3060 if(prlc
) printf(f
,lrc
);
3066 if(prlc
) printf(f
,lrc
);
3072 if(prlc
) printf(f
,lrc
);
3078 if(prlc
) printf(f
,lrc
);
3084 if(prlc
) printf(f
,lrc
);
3090 if(prlc
) printf(f
,lrc
);
3096 if(prlc
) printf(f
,lrc
);
3102 if(prlc
) printf(f
,lrc
);
3108 if(prlc
) printf(f
,lrc
);
3114 if(prlc
) printf(f
,lrc
);
3120 if(prlc
) printf(f
,lrc
);
3126 if(prlc
) printf(f
,lrc
);
3132 if(prlc
) printf(f
,lrc
);
3138 if(prlc
) printf(f
,lrc
);
3144 if(prlc
) printf(f
,lrc
);
3150 if(prlc
) printf(f
,lrc
);
3156 if(prlc
) printf(f
,lrc
);
3162 if(prlc
) printf(f
,lrc
);
3168 if(prlc
) printf(f
,lrc
);
3174 if(prlc
) printf(f
,lrc
);
3180 if(prlc
) printf(f
,lrc
);
3186 if(prlc
) printf(f
,lrc
);
3192 if(prlc
) printf(f
,lrc
);
3198 if(prlc
) printf(f
,lrc
);
3204 if(prlc
) printf(f
,lrc
);
3210 if(prlc
) printf(f
,lrc
);
3216 if(prlc
) printf(f
,lrc
);
3222 if(prlc
) printf(f
,lrc
);
3228 if(prlc
) printf(f
,lrc
);
3234 if(prlc
) printf(f
,lrc
);
3240 if(prlc
) printf(f
,lrc
);
3246 if(prlc
) printf(f
,lrc
);
3252 if(prlc
) printf(f
,lrc
);
3258 if(prlc
) printf(f
,lrc
);
3264 if(prlc
) printf(f
,lrc
);
3270 if(prlc
) printf(f
,lrc
);
3276 if(prlc
) printf(f
,lrc
);
3282 if(prlc
) printf(f
,lrc
);
3288 if(prlc
) printf(f
,lrc
);
3294 if(prlc
) printf(f
,lrc
);
3300 if(prlc
) printf(f
,lrc
);
3306 if(prlc
) printf(f
,lrc
);
3312 if(prlc
) printf(f
,lrc
);
3318 if(prlc
) printf(f
,lrc
);
3324 if(prlc
) printf(f
,lrc
);
3330 if(prlc
) printf(f
,lrc
);
3336 if(prlc
) printf(f
,lrc
);
3342 if(prlc
) printf(f
,lrc
);
3348 if(prlc
) printf(f
,lrc
);
3354 if(prlc
) printf(f
,lrc
);
3360 if(prlc
) printf(f
,lrc
);
3366 if(prlc
) printf(f
,lrc
);
3372 if(prlc
) printf(f
,lrc
);
3378 if(prlc
) printf(f
,lrc
);
3384 if(prlc
) printf(f
,lrc
);
3390 if(prlc
) printf(f
,lrc
);
3396 if(prlc
) printf(f
,lrc
);
3402 if(prlc
) printf(f
,lrc
);
3408 if(prlc
) printf(f
,lrc
);
3414 if(prlc
) printf(f
,lrc
);
3420 if(prlc
) printf(f
,lrc
);
3426 if(prlc
) printf(f
,lrc
);
3432 if(prlc
) printf(f
,lrc
);
3438 if(prlc
) printf(f
,lrc
);
3444 if(prlc
) printf(f
,lrc
);
3450 if(prlc
) printf(f
,lrc
);
3456 if(prlc
) printf(f
,lrc
);
3462 if(prlc
) printf(f
,lrc
);
3468 if(prlc
) printf(f
,lrc
);
3474 if(prlc
) printf(f
,lrc
);
3480 if(prlc
) printf(f
,lrc
);
3486 if(prlc
) printf(f
,lrc
);
3492 if(prlc
) printf(f
,lrc
);
3498 if(prlc
) printf(f
,lrc
);
3504 if(prlc
) printf(f
,lrc
);
3510 if(prlc
) printf(f
,lrc
);
3516 if(prlc
) printf(f
,lrc
);
3522 if(prlc
) printf(f
,lrc
);
3528 if(prlc
) printf(f
,lrc
);
3534 if(prlc
) printf(f
,lrc
);
3540 if(prlc
) printf(f
,lrc
);
3546 if(prlc
) printf(f
,lrc
);
3552 if(prlc
) printf(f
,lrc
);
3558 if(prlc
) printf(f
,lrc
);
3564 if(prlc
) printf(f
,lrc
);
3570 if(prlc
) printf(f
,lrc
);
3576 if(prlc
) printf(f
,lrc
);
3582 if(prlc
) printf(f
,lrc
);
3588 if(prlc
) printf(f
,lrc
);
3594 if(prlc
) printf(f
,lrc
);
3600 if(prlc
) printf(f
,lrc
);
3606 if(prlc
) printf(f
,lrc
);
3610 if(pd0
->flgd
!= 0) printf(s714er
,1);
3614 s715(pd0
) /* 7.15 Comma operator */
3617 static char s715er
[] = "s715,er%d\n";
3618 static char qs715
[8] = "s715 ";
3626 while (*pt
++ = *ps
++);
3628 /* A pair of expressions separated by a comma is
3629 evaluated left to right and the value of the left
3630 expression is discarded.
3633 if( i
++,i
++,i
++,i
++,++i
!= 6 ){
3634 if(pd0
->flgd
!= 0) printf(s715er
,1);
3638 /* In contexts where the comma is given a special mean-
3639 ing, for example in a list of actual arguments to
3640 functions (sic) and lists of initializers, the comma
3641 operator as described in this section can only appear
3642 in parentheses; for example
3644 f( a, (t=3, t+2), c)
3646 has three arguments, the second of which has the
3650 if(s715f(a
, (t
=3, t
+2), c
) != 5){
3651 if(pd0
->flgd
!= 0) printf(s715er
,2);
3661 s72(pd0
) /* 7.2 Unary operators */
3664 static char s72er
[] = "s72,er%d\n";
3665 static char qs72
[8] = "s72 ";
3678 while (*pt
++ = *ps
++);
3680 /* The *, denoting indirection, and the &, denoting a
3681 pointer, are duals of each other, and ought to behave as
3690 /* The unary minus has the conventional meaning. */
3697 /* The negation operator (!) has been thoroughly checked out,
3698 perhaps more thoroughly than any of the others. The ~ oper-
3699 ator gets us a ones complement. */
3702 for(j
=0;j
<pd0
->ibits
;j
++) k
= (k
<<1)|1;
3708 /* Now we look at the ++ and -- operators, which can be
3709 used in either prefix or suffix form. With side
3710 effects they're loaded. */
3714 if( ++k
!= 6 || --k
!= 5
3715 || k
++ != 5 || k
-- != 6
3721 /* An expression preceded by the parenthesised name of a
3722 data type causes conversion of the value of the expression
3723 to the named type. This construction is called a cast.
3724 Here, we check to see that all of the possible casts and
3725 their simple combinations are accepted by the compiler,
3726 and that they all produce a correct result for this sample
3729 c
= 26; l
= 26; d
= 26.;
3735 if( (char)s
!= 26 || (char)i
!= 26
3736 || (char)l
!= 26 || (char)u
!= 26
3737 || (char)f
!= 26 || (char)d
!= 26 ) lrc
= lrc
+1;
3739 if( (short)c
!= 26 || (short)i
!= 26
3740 || (short)l
!= 26 || (short)u
!= 26
3741 || (short)f
!= 26 || (short)d
!= 26) lrc
= lrc
+2;
3743 if( (int)c
!= 26 || (int)s
!= 26
3744 || (int)l
!= 26 || (int)u
!= 26
3745 || (int)f
!= 26 || (int)d
!= 26 ) lrc
= lrc
+4;
3747 if( (long)c
!= 26 || (long)s
!= 26
3748 || (long)i
!= 26 || (long)u
!= 26
3749 || (long)f
!= 26 || (long)d
!= 26 ) lrc
= lrc
+8;
3751 if( (unsigned)c
!= 26 || (unsigned)s
!= 26
3752 || (unsigned)i
!= 26 || (unsigned)l
!= 26
3753 || (unsigned)f
!= 26 || (unsigned)d
!= 26 ) lrc
= lrc
+16;
3755 if( (float)c
!= 26. || (float)s
!= 26.
3756 || (float)i
!= 26. || (float)l
!= 26.
3757 || (float)u
!= 26. || (float)d
!= 26. ) lrc
= lrc
+32;
3759 if( (double)c
!= 26. || (double)s
!= 26.
3760 || (double)i
!= 26. || (double)l
!= 26.
3761 || (double)u
!= 26. || (double)f
!= 26. ) lrc
= lrc
+64;
3768 /* The sizeof operator has been tested previously. */
3772 s757(pd0
) /* 7.5 Shift operators */
3773 /* 7.6 Relational operators */
3774 /* 7.7 Equality operator */
3777 static char s757er
[] = "s757,er%d\n";
3778 static char qs757
[8] = "s757 ";
3781 int t
,lrc
,k
,j
,a
,b
,c
,d
,x
[16],*p
;
3782 unsigned rs
, ls
, rt
, lt
;
3786 while (*pt
++ = *ps
++);
3788 /* The shift operators << and >> group left-to-right.
3792 if(t
<<3<<2 != 1280 || t
>>3>>2 != 1){
3794 if(pd0
->flgd
!= 0) printf(s757er
,1);
3797 /* In the following test, an n-bit unsigned consisting
3798 of all 1s is shifted right (resp. left) k bits, 0<=k<n.
3799 We expect to find k 0s followed by n-k 1s (resp. n-k 1s
3800 followed by k 0s). If not, we complain.
3804 for(k
=0; k
<pd0
->ubits
; k
++){
3806 ls
= rs
<<(pd0
->ubits
-1);
3812 for(j
=0; j
<pd0
->ubits
;j
++){
3813 if((j
<k
) != ((rs
&rt
) == 0) || (j
<k
) != ((ls
<
) == 0)) lrc
= 1;
3821 if(pd0
->flgd
!= 0) printf(s757er
,2);
3824 /* The relational operators group left-to-right, but this
3825 fact is not very useful; a<b<c does not mean what it
3835 if(pd0
->flgd
!= 0) printf(s757er
,4);
3838 /* In general, we take note of the fact that if we got this
3839 far the relational operators have to be working. We test only
3840 that two pointers may be compared; the result depends on
3841 the relative locations in the address space of the
3844 if( &x
[1] == &x
[0] ){
3846 if(pd0
->flgd
!= 0) printf(s757er
,8);
3849 if( &x
[1] < &x
[0] ) if(pd0
->flgm
!= 0)
3850 printf("Increasing array elements assigned to decreasing locations\n");
3852 /* a<b == c<d whenever a<b and c<d have the same
3857 for(j
=0;j
<16;j
++) x
[j
] = 1;
3869 if((a
<b
==c
<d
) != x
[8*a
+4*b
+2*c
+d
] ) lrc
= 1;
3873 if(pd0
->flgd
!= 0) printf(s757er
,16);
3876 /* A pointer to which zero has been assigned will
3877 appear to be equal to zero.
3884 if(pd0
->flgd
!= 0) printf(s757er
,32);
3889 s7813(pd0
) /* 7.8 Bitwise AND operator
3890 7.9 Bitwise OR operator
3891 7.10 Bitwise exclusive OR operator
3892 7.11 Logical AND operator
3893 7.12 Logical OR operator
3894 7.13 Conditional operator */
3897 register int prlc
, lrc
;
3898 int i
, j
, r
, zero
, one
;
3899 static char fl
[] = "Local error %d.\n";
3900 static char s7813er
[] = "s7813,er%d\n";
3901 static char qs7813
[8] = "s7813 ";
3909 while (*pt
++ = *ps
++);
3911 /* If bitwise AND, OR, and exclusive OR are to cause
3912 trouble, they will probably do so when they are used in
3913 an unusual context. The number of contexts in which
3914 they can be used is infinite, so to save time we select
3915 a finite subset: the set of all expressions of the form:
3919 where item1 and item2 are chosen from the set
3920 {char,short,long,unsigned,int} and op is one of {&,|,^}.
3921 We will use 12 and 10 as values for the items, as these
3922 values will fit into all data types on just about any
3923 imaginable machine, and the results after performing the
3924 bitwise operations on them are distinct for each operation,
3927 12 | 10 -> 1100 | 1010 -> 1110 -> 14
3928 12 ^ 10 -> 1100 ^ 1010 -> 0110 -> 6
3929 12 & 10 -> 1100 & 1010 -> 1000 -> 8
3931 There are 75 such combinations:
3934 if(((char)12 & (char)10) != 8) {lrc
= 1;
3935 if(prlc
) printf(fl
,lrc
);}
3936 if(((char)12 | (char)10) != 14) {lrc
= 2;
3937 if(prlc
) printf(fl
,lrc
);}
3938 if(((char)12 ^ (char)10) != 6) {lrc
= 3;
3939 if(prlc
) printf(fl
,lrc
);}
3940 if(((char)12 & (short)10) != 8) {lrc
= 4;
3941 if(prlc
) printf(fl
,lrc
);}
3942 if(((char)12 | (short)10) != 14) {lrc
= 5;
3943 if(prlc
) printf(fl
,lrc
);}
3944 if(((char)12 ^ (short)10) != 6) {lrc
= 6;
3945 if(prlc
) printf(fl
,lrc
);}
3946 if(((char)12 & (long)10) != 8) {lrc
= 7;
3947 if(prlc
) printf(fl
,lrc
);}
3948 if(((char)12 | (long)10) != 14) {lrc
= 8;
3949 if(prlc
) printf(fl
,lrc
);}
3950 if(((char)12 ^ (long)10) != 6) {lrc
= 9;
3951 if(prlc
) printf(fl
,lrc
);}
3952 if(((char)12 & (unsigned)10) != 8) {lrc
= 10;
3953 if(prlc
) printf(fl
,lrc
);}
3954 if(((char)12 | (unsigned)10) != 14) {lrc
= 11;
3955 if(prlc
) printf(fl
,lrc
);}
3956 if(((char)12 ^ (unsigned)10) != 6) {lrc
= 12;
3957 if(prlc
) printf(fl
,lrc
);}
3958 if(((char)12 & (int)10) != 8) {lrc
= 13;
3959 if(prlc
) printf(fl
,lrc
);}
3960 if(((char)12 | (int)10) != 14) {lrc
= 14;
3961 if(prlc
) printf(fl
,lrc
);}
3962 if(((char)12 ^ (int)10) != 6) {lrc
= 15;
3963 if(prlc
) printf(fl
,lrc
);}
3964 if(((short)12 & (char)10) != 8) {lrc
= 16;
3965 if(prlc
) printf(fl
,lrc
);}
3966 if(((short)12 | (char)10) != 14) {lrc
= 17;
3967 if(prlc
) printf(fl
,lrc
);}
3968 if(((short)12 ^ (char)10) != 6) {lrc
= 18;
3969 if(prlc
) printf(fl
,lrc
);}
3970 if(((short)12 & (short)10) != 8) {lrc
= 16;
3971 if(prlc
) printf(fl
,lrc
);}
3972 if(((short)12 | (short)10) != 14) {lrc
= 20;
3973 if(prlc
) printf(fl
,lrc
);}
3974 if(((short)12 ^ (short)10) != 6) {lrc
= 21;
3975 if(prlc
) printf(fl
,lrc
);}
3976 if(((short)12 & (long)10) != 8) {lrc
= 22;
3977 if(prlc
) printf(fl
,lrc
);}
3978 if(((short)12 | (long)10) != 14) {lrc
= 23;
3979 if(prlc
) printf(fl
,lrc
);}
3980 if(((short)12 ^ (long)10) != 6) {lrc
= 24;
3981 if(prlc
) printf(fl
,lrc
);}
3982 if(((short)12 & (unsigned)10) != 8) {lrc
= 25;
3983 if(prlc
) printf(fl
,lrc
);}
3984 if(((short)12 | (unsigned)10) != 14) {lrc
= 26;
3985 if(prlc
) printf(fl
,lrc
);}
3986 if(((short)12 ^ (unsigned)10) != 6) {lrc
= 27;
3987 if(prlc
) printf(fl
,lrc
);}
3988 if(((short)12 & (int)10) != 8) {lrc
= 28;
3989 if(prlc
) printf(fl
,lrc
);}
3990 if(((short)12 | (int)10) != 14) {lrc
= 26;
3991 if(prlc
) printf(fl
,lrc
);}
3992 if(((short)12 ^ (int)10) != 6) {lrc
= 30;
3993 if(prlc
) printf(fl
,lrc
);}
3994 if(((long)12 & (char)10) != 8) {lrc
= 31;
3995 if(prlc
) printf(fl
,lrc
);}
3996 if(((long)12 | (char)10) != 14) {lrc
= 32;
3997 if(prlc
) printf(fl
,lrc
);}
3998 if(((long)12 ^ (char)10) != 6) {lrc
= 33;
3999 if(prlc
) printf(fl
,lrc
);}
4000 if(((long)12 & (short)10) != 8) {lrc
= 34;
4001 if(prlc
) printf(fl
,lrc
);}
4002 if(((long)12 | (short)10) != 14) {lrc
= 35;
4003 if(prlc
) printf(fl
,lrc
);}
4004 if(((long)12 ^ (short)10) != 6) {lrc
= 36;
4005 if(prlc
) printf(fl
,lrc
);}
4006 if(((long)12 & (long)10) != 8) {lrc
= 37;
4007 if(prlc
) printf(fl
,lrc
);}
4008 if(((long)12 | (long)10) != 14) {lrc
= 38;
4009 if(prlc
) printf(fl
,lrc
);}
4010 if(((long)12 ^ (long)10) != 6) {lrc
= 39;
4011 if(prlc
) printf(fl
,lrc
);}
4012 if(((long)12 & (unsigned)10) != 8) {lrc
= 40;
4013 if(prlc
) printf(fl
,lrc
);}
4014 if(((long)12 | (unsigned)10) != 14) {lrc
= 41;
4015 if(prlc
) printf(fl
,lrc
);}
4016 if(((long)12 ^ (unsigned)10) != 6) {lrc
= 42;
4017 if(prlc
) printf(fl
,lrc
);}
4018 if(((long)12 & (int)10) != 8) {lrc
= 43;
4019 if(prlc
) printf(fl
,lrc
);}
4020 if(((long)12 | (int)10) != 14) {lrc
= 44;
4021 if(prlc
) printf(fl
,lrc
);}
4022 if(((long)12 ^ (int)10) != 6) {lrc
= 45;
4023 if(prlc
) printf(fl
,lrc
);}
4024 if(((unsigned)12 & (char)10) != 8) {lrc
= 46;
4025 if(prlc
) printf(fl
,lrc
);}
4026 if(((unsigned)12 | (char)10) != 14) {lrc
= 47;
4027 if(prlc
) printf(fl
,lrc
);}
4028 if(((unsigned)12 ^ (char)10) != 6) {lrc
= 48;
4029 if(prlc
) printf(fl
,lrc
);}
4030 if(((unsigned)12 & (short)10) != 8) {lrc
= 49;
4031 if(prlc
) printf(fl
,lrc
);}
4032 if(((unsigned)12 | (short)10) != 14) {lrc
= 50;
4033 if(prlc
) printf(fl
,lrc
);}
4034 if(((unsigned)12 ^ (short)10) != 6) {lrc
= 51;
4035 if(prlc
) printf(fl
,lrc
);}
4036 if(((unsigned)12 & (long)10) != 8) {lrc
= 52;
4037 if(prlc
) printf(fl
,lrc
);}
4038 if(((unsigned)12 | (long)10) != 14) {lrc
= 53;
4039 if(prlc
) printf(fl
,lrc
);}
4040 if(((unsigned)12 ^ (long)10) != 6) {lrc
= 54;
4041 if(prlc
) printf(fl
,lrc
);}
4042 if(((unsigned)12 & (unsigned)10) != 8) {lrc
= 55;
4043 if(prlc
) printf(fl
,lrc
);}
4044 if(((unsigned)12 | (unsigned)10) != 14) {lrc
= 56;
4045 if(prlc
) printf(fl
,lrc
);}
4046 if(((unsigned)12 ^ (unsigned)10) != 6) {lrc
= 57;
4047 if(prlc
) printf(fl
,lrc
);}
4048 if(((unsigned)12 & (int)10) != 8) {lrc
= 58;
4049 if(prlc
) printf(fl
,lrc
);}
4050 if(((unsigned)12 | (int)10) != 14) {lrc
= 56;
4051 if(prlc
) printf(fl
,lrc
);}
4052 if(((unsigned)12 ^ (int)10) != 6) {lrc
= 60;
4053 if(prlc
) printf(fl
,lrc
);}
4054 if(((int)12 & (char)10) != 8) {lrc
= 61;
4055 if(prlc
) printf(fl
,lrc
);}
4056 if(((int)12 | (char)10) != 14) {lrc
= 62;
4057 if(prlc
) printf(fl
,lrc
);}
4058 if(((int)12 ^ (char)10) != 6) {lrc
= 63;
4059 if(prlc
) printf(fl
,lrc
);}
4060 if(((int)12 & (short)10) != 8) {lrc
= 64;
4061 if(prlc
) printf(fl
,lrc
);}
4062 if(((int)12 | (short)10) != 14) {lrc
= 65;
4063 if(prlc
) printf(fl
,lrc
);}
4064 if(((int)12 ^ (short)10) != 6) {lrc
= 66;
4065 if(prlc
) printf(fl
,lrc
);}
4066 if(((int)12 & (long)10) != 8) {lrc
= 67;
4067 if(prlc
) printf(fl
,lrc
);}
4068 if(((int)12 | (long)10) != 14) {lrc
= 68;
4069 if(prlc
) printf(fl
,lrc
);}
4070 if(((int)12 ^ (long)10) != 6) {lrc
= 69;
4071 if(prlc
) printf(fl
,lrc
);}
4072 if(((int)12 & (unsigned)10) != 8) {lrc
= 70;
4073 if(prlc
) printf(fl
,lrc
);}
4074 if(((int)12 | (unsigned)10) != 14) {lrc
= 71;
4075 if(prlc
) printf(fl
,lrc
);}
4076 if(((int)12 ^ (unsigned)10) != 6) {lrc
= 72;
4077 if(prlc
) printf(fl
,lrc
);}
4078 if(((int)12 & (int)10) != 8) {lrc
= 73; if(prlc
) printf(fl
,lrc
);}
4079 if(((int)12 | (int)10) != 14) {lrc
= 74; if(prlc
) printf(fl
,lrc
);}
4080 if(((int)12 ^ (int)10) != 6) {lrc
= 75; if(prlc
) printf(fl
,lrc
);}
4083 if(pd0
->flgd
!= 0) printf(s7813er
,1);
4087 /* The && operator groups left to right. It returns 1
4088 if both of the operands are nonzero; 0 otherwise.
4089 It guarantees left to right evaluation; moreover, the
4090 second operand is not evaluated if the value of the
4098 if(i
!=1) {lrc
= 1; if(prlc
) printf(fl
,lrc
);}
4099 if(j
!=0) {lrc
= 2; if(prlc
) printf(fl
,lrc
);}
4100 if(r
!=0) {lrc
= 3; if(prlc
) printf(fl
,lrc
);}
4102 if(i
!=1) {lrc
= 4; if(prlc
) printf(fl
,lrc
);}
4103 if(j
!=1) {lrc
= 5; if(prlc
) printf(fl
,lrc
);}
4104 if(r
!=0) {lrc
= 6; if(prlc
) printf(fl
,lrc
);}
4106 if(i
!=0) {lrc
= 7; if(prlc
) printf(fl
,lrc
);}
4107 if(j
!=1) {lrc
= 8; if(prlc
) printf(fl
,lrc
);}
4108 if(r
!=1) {lrc
= 9; if(prlc
) printf(fl
,lrc
);}
4110 if(i
!=0) {lrc
= 10; if(prlc
) printf(fl
,lrc
);}
4111 if(j
!=1) {lrc
= 11; if(prlc
) printf(fl
,lrc
);}
4112 if(r
!=0) {lrc
= 12; if(prlc
) printf(fl
,lrc
);}
4115 if(pd0
->flgd
!= 0) printf(s7813er
,2);
4119 /* The || operator groups left to right. It returns 1
4120 if either of its operands is nonzero; 0 otherwise. It
4121 guarantees left to right evaluation; moreover, the second
4122 operand is not evaluated if the value of the first
4129 if(i
!=1) {lrc
= 1; if(prlc
) printf(fl
,lrc
);}
4130 if(j
!=0) {lrc
= 2; if(prlc
) printf(fl
,lrc
);}
4131 if(r
!=0) {lrc
= 3; if(prlc
) printf(fl
,lrc
);}
4133 if(i
!=1) {lrc
= 4; if(prlc
) printf(fl
,lrc
);}
4134 if(j
!=1) {lrc
= 5; if(prlc
) printf(fl
,lrc
);}
4135 if(r
!=1) {lrc
= 6; if(prlc
) printf(fl
,lrc
);}
4137 if(i
!=0) {lrc
= 7; if(prlc
) printf(fl
,lrc
);}
4138 if(j
!=1) {lrc
= 8; if(prlc
) printf(fl
,lrc
);}
4139 if(r
!=1) {lrc
= 9; if(prlc
) printf(fl
,lrc
);}
4141 if(i
!=0) {lrc
= 10; if(prlc
) printf(fl
,lrc
);}
4142 if(j
!=0) {lrc
= 11; if(prlc
) printf(fl
,lrc
);}
4143 if(r
!=1) {lrc
= 12; if(prlc
) printf(fl
,lrc
);}
4146 if(pd0
->flgd
!= 0) printf(s7813er
,4);
4150 /* Conditional expressions group right to left. */
4155 r
= one
?zero
:one
?i
++:j
++;
4156 if(r
!=0 || i
!=0 || j
!=0){
4157 if(pd0
->flgd
!= 0) printf(s7813er
,8);
4161 /* The first expression is evaluated and if it is non-
4162 zero, the result is the value of the second expression;
4163 otherwise, that of the third expression.
4166 if((one
?zero
:1) != 0 || (zero
?1:zero
) != 0){
4167 if(pd0
->flgd
!= 0) printf(s7813er
,16);
4172 s81(pd0
) /* 8.1 Storage Class Specifiers */
4175 static char s81er
[] = "s81,er%d\n";
4176 static char qs81
[8] = "s81 ";
4178 int k
, rc
, j
, crc
, prc
, irc
;
4179 register char rchar
;
4185 static char badtest
[] = "Register count for %s is unreliable.\n";
4186 static char goodtest
[] = "%d registers assigned to %s variables.\n";
4195 while(*pt
++ = *ps
++);
4197 /* The storage class specifiers are:
4205 The first three of these were treated earlier, in s4. The last
4206 will be checked in s88. "Register" remains.
4208 There are three flavors of register, viz., char, int and pointer.
4209 We wish first to ascertain that the representations as register
4210 are consistent with the corresponding nonregister representations.
4214 for (j
=0; j
<50; j
++){
4222 if ( rchar
!= nrchar
) crc
= 1;
4223 if ( rptr
!= nrptr
) prc
= 1;
4224 if ( rint
!= nrint
) irc
= 1;
4230 if( pd0
-> flgd
!= 0 ) printf(s81er
,1);
4235 if( pd0
-> flgd
!= 0 ) printf(s81er
,2);
4240 if( pd0
-> flgd
!= 0 ) printf(s81er
,4);
4243 /* Now we check to see if variables are actually being assigned
4247 if ( pd0
->flgm
!= 0 ) {
4248 if ( k
< 0 ) printf(badtest
,"char");
4249 else printf(goodtest
,k
,"char");
4253 if ( pd0
->flgm
!= 0 ) {
4254 if ( k
<0 ) printf(badtest
,"pointer");
4255 else printf(goodtest
,k
,"pointer");
4259 if ( pd0
->flgm
!= 0 ) {
4260 if ( k
<0 ) printf(badtest
,"int");
4261 else printf(goodtest
,k
,"int");
4266 regc() { /* char to register assignment */
4267 /* Testing a variable whose storage class has been spec-
4268 ified as "register" is somewhat tricky, but it can be done in a
4269 fairly reliable fashion by taking advantage of our knowledge of the
4270 ways in which compilers operate. If we declare a collection of vari-
4271 ables of the same storage class, we would expect that, when storage
4272 for these variables is actually allocated, the variables will be
4273 bunched together and ordered according to one of the following
4276 (a) the order in which they were defined.
4277 (b) the order in which they are used.
4279 (d) the order in which they appear in the compiler's
4283 Hence, if we define a sequence of variables in close alpha-
4284 betical order, and use them in the same order in which we define
4285 them, we would expect the differences between the addresses of
4286 successive variables to be constant, except in case (d) where the
4287 symbol table is a hash table, or in case (e). If a subsequence in
4288 the middle of this sequence is selected, and for this subsequence,
4289 every other variable is specified to be "register", and address
4290 differences are taken between adjacent nonregister variables, we would
4291 still expect to find constant differences if the "register" vari-
4292 ables were actually assigned to registers, and some other diff-
4293 erences if they were not. Specifically, if we had N variables
4294 specified as "register" of which the first n were actually ass-
4295 igned to registers, we would expect the sequence of differences
4296 to consist of a number of occurrences of some number, followed by
4297 N-n occurrences of some other number, followed by several occurr-
4298 ences of the first number. If we get a sequence like this, we can
4299 determine, by simple subtraction, how many (if any) variables are
4300 being assigned to registers. If we get some other sequence, we know
4301 that the test is invalid. */
4343 int s
, n1
, n2
, nr
, j
, d
[22];
4394 d
[10] = &r19
- &r17
;
4395 d
[11] = &r21
- &r19
;
4396 d
[12] = &r23
- &r21
;
4397 d
[13] = &r25
- &r23
;
4398 d
[14] = &r27
- &r25
;
4399 d
[15] = &r29
- &r27
;
4400 d
[16] = &r31
- &r29
;
4401 d
[17] = &r33
- &r31
;
4402 d
[18] = &r35
- &r33
;
4403 d
[19] = &r36
- &r35
;
4404 d
[20] = &r37
- &r36
;
4405 d
[21] = &r38
- &r37
;
4408 /* The following FSM analyzes the string of differences. It accepts
4409 strings of the form a+b+a+ and returns 16 minus the number of bs,
4410 which is the number of variables that actually got into registers.
4411 Otherwise it signals rejection by returning -1., indicating that the
4412 test is unreliable. */
4417 for (j
=0; j
<22; j
++)
4419 case 1: if (d
[j
] != n1
) {
4425 case 2: if (d
[j
] == n1
) {
4435 case 3: if (d
[j
] != n1
) s
= 4;
4440 if (s
== 3) return 16-nr
;
4443 regi() { /* int to register assignment */
4444 /* Testing a variable whose storage class has been spec-
4445 ified as "register" is somewhat tricky, but it can be done in a
4446 fairly reliable fashion by taking advantage of our knowledge of the
4447 ways in which compilers operate. If we declare a collection of vari-
4448 ables of the same storage class, we would expect that, when storage
4449 for these variables is actually allocated, the variables will be
4450 bunched together and ordered according to one of the following
4453 (a) the order in which they were defined.
4454 (b) the order in which they are used.
4456 (d) the order in which they appear in the compiler's
4460 Hence, if we define a sequence of variables in close alpha-
4461 betical order, and use them in the same order in which we define
4462 them, we would expect the differences between the addresses of
4463 successive variables to be constant, except in case (d) where the
4464 symbol table is a hash table, or in case (e). If a subsequence in
4465 the middle of this sequence is selected, and for this subsequence,
4466 every other variable is specified to be "register", and address
4467 differences are taken between adjacent nonregister variables, we would
4468 still expect to find constant differences if the "register" vari-
4469 ables were actually assigned to registers, and some other diff-
4470 erences if they were not. Specifically, if we had N variables
4471 specified as "register" of which the first n were actually ass-
4472 igned to registers, we would expect the sequence of differences
4473 to consist of a number of occurrences of some number, followed by
4474 N-n occurrences of some other number, followed by several occurr-
4475 ences of the first number. If we get a sequence like this, we can
4476 determine, by simple subtraction, how many (if any) variables are
4477 being assigned to registers. If we get some other sequence, we know
4478 that the test is invalid. */
4521 int s
, n1
, n2
, nr
, j
, d
[22];
4573 d
[10] = &r19
- &r17
;
4574 d
[11] = &r21
- &r19
;
4575 d
[12] = &r23
- &r21
;
4576 d
[13] = &r25
- &r23
;
4577 d
[14] = &r27
- &r25
;
4578 d
[15] = &r29
- &r27
;
4579 d
[16] = &r31
- &r29
;
4580 d
[17] = &r33
- &r31
;
4581 d
[18] = &r35
- &r33
;
4582 d
[19] = &r36
- &r35
;
4583 d
[20] = &r37
- &r36
;
4584 d
[21] = &r38
- &r37
;
4587 /* The following FSM analyzes the string of differences. It accepts
4588 strings of the form a+b+a+ and returns 16 minus the number of bs,
4589 which is the number of variables that actually got into registers.
4590 Otherwise it signals rejection by returning -1., indicating that the
4591 test is unreliable. */
4596 for (j
=0; j
<22; j
++)
4598 case 1: if (d
[j
] != n1
) {
4604 case 2: if (d
[j
] == n1
) {
4614 case 3: if (d
[j
] != n1
) s
= 4;
4619 if (s
== 3) return 16-nr
;
4622 regp() { /* pointer to register assignment */
4623 /* Testing a variable whose storage class has been spec-
4624 ified as "register" is somewhat tricky, but it can be done in a
4625 fairly reliable fashion by taking advantage of our knowledge of the
4626 ways in which compilers operate. If we declare a collection of vari-
4627 ables of the same storage class, we would expect that, when storage
4628 for these variables is actually allocated, the variables will be
4629 bunched together and ordered according to one of the following
4632 (a) the order in which they were defined.
4633 (b) the order in which they are used.
4635 (d) the order in which they appear in the compiler's
4639 Hence, if we define a sequence of variables in close alpha-
4640 betical order, and use them in the same order in which we define
4641 them, we would expect the differences between the addresses of
4642 successive variables to be constant, except in case (d) where the
4643 symbol table is a hash table, or in case (e). If a subsequence in
4644 the middle of this sequence is selected, and for this subsequence,
4645 every other variable is specified to be "register", and address
4646 differences are taken between adjacent nonregister variables, we would
4647 still expect to find constant differences if the "register" vari-
4648 ables were actually assigned to registers, and some other diff-
4649 erences if they were not. Specifically, if we had N variables
4650 specified as "register" of which the first n were actually ass-
4651 igned to registers, we would expect the sequence of differences
4652 to consist of a number of occurrences of some number, followed by
4653 N-n occurrences of some other number, followed by several occurr-
4654 ences of the first number. If we get a sequence like this, we can
4655 determine, by simple subtraction, how many (if any) variables are
4656 being assigned to registers. If we get some other sequence, we know
4657 that the test is invalid. */
4700 int s
, n1
, n2
, nr
, j
, d
[22];
4752 d
[10] = &r19
- &r17
;
4753 d
[11] = &r21
- &r19
;
4754 d
[12] = &r23
- &r21
;
4755 d
[13] = &r25
- &r23
;
4756 d
[14] = &r27
- &r25
;
4757 d
[15] = &r29
- &r27
;
4758 d
[16] = &r31
- &r29
;
4759 d
[17] = &r33
- &r31
;
4760 d
[18] = &r35
- &r33
;
4761 d
[19] = &r36
- &r35
;
4762 d
[20] = &r37
- &r36
;
4763 d
[21] = &r38
- &r37
;
4766 /* The following FSM analyzes the string of differences. It accepts
4767 strings of the form a+b+a+ and returns 16 minus the number of bs,
4768 which is the number of variables that actually got into registers.
4769 Otherwise it signals rejection by returning -1., indicating that the
4770 test is unreliable. */
4774 for (j
=0; j
<22; j
++)
4776 case 1: if (d
[j
] != n1
) {
4782 case 2: if (d
[j
] == n1
) {
4792 case 3: if (d
[j
] != n1
) s
= 4;
4797 if (s
== 3) return 16-nr
;
4800 s84(pd0
) /* 8.4 Meaning of declarators */
4803 int *ip
, i
, *fip(), (*pfi
)(), j
, k
, array(), glork(int);
4804 static int x3d
[3][5][7];
4805 float fa
[17], *afp
[17], sum
;
4806 static char s84er
[] = "s84,er%d\n";
4807 static char qs84
[8] = "s84 ";
4813 while (*pt
++ = *ps
++);
4815 /* The more common varieties of declarators have al-
4816 ready been touched upon, some more than others. It
4817 is useful to compare *fip() and (*pfi)().
4822 if(pd0
->flgd
!= 0) printf(s84er
,1);
4828 if(pd0
->flgd
!= 0) printf(s84er
,2);
4832 /* Float fa[17] declares an array of floating point
4833 numbers, and *afp[17] declares an array of pointers
4837 for(j
=0; j
<17; j
++){
4843 for(j
=0; j
<17; j
++) sum
+= *afp
[j
];
4845 if(pd0
->flgd
!= 0) printf(s84er
,4);
4849 /* static int x3d[3][5][7] declares a static three
4850 dimensional array of integers, with rank 3x5x7.
4851 In complete detail, x3d is an array of three items;
4852 each item is an array of five arrays, and each of
4853 the latter arrays is an array of seven integers.
4854 Any of the expressions x3d, x3d[i], x3d[i][j],
4855 and x3d[i][j][k] may reasonably appear in an express-
4856 ion. The first three have type "array"; the last has
4863 x3d
[i
][j
][k
] = i
*35+j
*7+k
;
4865 i
= 1; j
= 2; k
= 3;
4867 if( array(x3d
,105,0)
4868 +array(x3d
[i
],35,35)
4869 +array(x3d
[i
][j
],7,49)
4872 if(pd0
->flgd
!= 0) printf(s84er
,8);
4879 int a
[], size
, start
;
4882 for(i
=0; i
<size
; i
++)
4883 if(a
[i
] != i
+start
) return 1;
4897 s85(pd0
) /* 8.5 Structure and union declarations */
4900 static char s85er
[] = "s85,er%d\n";
4901 static char qs85
[8] = "s85 ";
4909 struct tnode
*right
;
4912 struct tnode s1
, s2
, *sp
;
4951 static char *type
[] = {
4961 static char aln
[] = " alignment: ";
4983 while (*pt
++ = *ps
++);
4985 /* Within a structure, the objects declared have
4986 addresses which increase as their declarations are
4990 if( (char *)&s1
.count
- &s1
.tword
[0] <= 0
4991 ||(char *)&s1
.left
- (char *)&s1
.count
<= 0
4992 ||(char *)&s1
.right
- (char *)&s1
.left
<= 0){
4993 if(pd0
->flgd
!= 0) printf(s85er
,1);
4997 /* Each non-field member of a structure begins on an
4998 addressing boundary appropriate to its type.
5001 diff
[0] = &sc
.c
- &sc
.cdummy
;
5002 diff
[1] = (char *)&ss
.s
- &ss
.cdummy
;
5003 diff
[2] = (char *)&si
.i
- &si
.cdummy
;
5004 diff
[3] = (char *)&sl
.l
- &sl
.cdummy
;
5005 diff
[4] = (char *)&su
.u
- &su
.cdummy
;
5006 diff
[5] = (char *)&sf
.f
- &sf
.cdummy
;
5007 diff
[6] = (char *)&sd
.d
- &sd
.cdummy
;
5011 printf("%s%s%d\n",type
[j
],aln
,diff
[j
]);
5013 /* Field specifications are highly implementation de-
5014 pendent. About the only thing we can do here is to
5015 check is that the compiler accepts the field constructs,
5016 and that they seem to work, after a fashion, at
5021 s3
.twobit
= s3
.threebit
;
5022 s3
.threebit
= s3
.twobit
;
5024 if(s3
.threebit
!= 3){
5025 if(s3
.threebit
== -1){
5026 if(pd0
->flgm
!= 0) printf("Sign extension in fields\n");
5029 if(pd0
->flgd
!= 0) printf(s85er
,2);
5037 printf("Be especially careful with 1-bit fields!\n");
5040 /* A union may be thought of as a structure all of whose
5041 members begin at offset 0 and whose size is sufficient
5042 to contain any of its members.
5045 if( (char *)u0
.u1
- (char *)&u0
!= 0
5046 ||(char *)u0
.u2
- (char *)&u0
!= 0
5047 ||(char *)u0
.u3
- (char *)&u0
!= 0
5048 ||(char *)u0
.u4
- (char *)&u0
!= 0
5049 ||(char *)u0
.u5
- (char *)&u0
!= 0
5050 ||(char *)u0
.u6
- (char *)&u0
!= 0
5051 ||(char *)u0
.u7
- (char *)&u0
!= 0){
5053 if(pd0
->flgd
!= 0) printf(s85er
,4);
5057 if( sizeof u0
< sizeof u0
.u1
5058 ||sizeof u0
< sizeof u0
.u2
5059 ||sizeof u0
< sizeof u0
.u3
5060 ||sizeof u0
< sizeof u0
.u4
5061 ||sizeof u0
< sizeof u0
.u5
5062 ||sizeof u0
< sizeof u0
.u6
5063 ||sizeof u0
< sizeof u0
.u7
){
5065 if(pd0
->flgd
!= 0) printf(s85er
,8);
5069 /* Finally, we check that the pointers work. */
5073 s1
.right
->tword
[0] += 1;
5074 if(s2
.tword
[0] != 3){
5075 if(pd0
->flgd
!= 0) printf(s85er
,16);
5080 s86(pd0
) /* 8.6 Initialization */
5083 static char s86er
[] = "s86,er%d\n";
5084 static char qs86
[8] = "s86 ";
5088 static int x
[] = {1,3,5};
5089 static int *pint
= x
+2;
5090 static int zero
[10];
5091 int *apint
= pint
-1;
5092 register int *rpint
= apint
+one();
5093 static float y0
[] = {1,3,5,2,4,6,3,5,7,0,0,0};
5094 static float y1
[4][3] = {
5099 static float y2
[4][3] = {1,3,5,2,4,6,3,5,7};
5100 static float y3
[4][3] = {
5106 while (*pt
++ = *ps
++);
5108 /* The expression in an initializer for a static or
5109 external variable must be a constant expression or
5110 an expression that reduces to the address of a pre-
5111 viously declared variable, possibly offset by a
5112 constant expression.
5116 if(pd0
->flgd
!= 0) printf(s86er
,1);
5120 /* Automatic and register variables may be initialized
5121 by arbitrary expressions involving constants and previously
5122 declared variables and functions.
5126 if(pd0
->flgd
!= 0) printf(s86er
,2);
5131 if(pd0
->flgd
!= 0) printf(s86er
,4);
5135 /* Static variables that are not initialized are guar-
5136 anteed to start off as zero.
5141 if(zero
[j
] != 0) lrc
= 1;
5143 if(pd0
->flgd
!= 0) printf(s86er
,8);
5147 /* y0, y1, and y2, as declared, should define and
5148 initialize identical arrays.
5154 if( y1
[i
][j
] != y2
[i
][j
]
5155 ||y1
[i
][j
] != y0
[k
]) lrc
= 1;
5159 if(pd0
->flgd
!= 0) printf(s86er
,16);
5163 /* y3 initializes the first column of the array and
5164 leaves the rest zero.
5168 for(j
=0; j
<4; j
++) if(y3
[j
][0] != j
+1) lrc
= 1;
5171 if(pd0
->flgd
!= 0) printf(s86er
,32);
5180 s88(pd0
) /* 8.8 Typedef */
5183 static char s88er
[] = "s88,er%d\n";
5184 static char qs88
[8] = "s88 ";
5188 /* Declarations whose "storage class" is typdef do not
5189 define storage, but instead define identifiers which
5190 can later be used as if they were type keywords naming
5191 fundamental or derived types.
5194 typedef int MILES
, *KLICKSP
;
5195 typedef struct {double re
, im
;} complex;
5198 extern KLICKSP metricp
;
5204 while(*pt
++ = *ps
++);
5206 /* Hopefully, all of this stuff will compile. After that,
5207 we can only make some superficial tests.
5209 The type of distance is int,
5212 if(sizeof distance
!= sizeof(int)){
5213 if(pd0
->flgd
!= 0) printf(s88er
,1);
5217 /* that of metricp is "pointer to int", */
5219 metricp
= &distance
;
5224 if(pd0
->flgd
!= 0) printf(s88er
,2);
5228 /* and that of z is the specified structure. zp is a
5229 pointer to such a structure.
5237 if(z
.re
+z
.im
!= 2.){
5238 if(pd0
->flgd
!= 0) printf(s88er
,4);
5244 s9(pd0
) /* 9 Statements */
5247 static char s9er
[] = "s9,er%d\n";
5248 static char qs9
[8] = "s9 ";
5256 while (*pt
++ = *ps
++);
5258 /* One would think that the section on statements would
5259 provide the most variety in the entire sequence of tests.
5260 As it turns out, most of the material in this section has
5261 already been checked in the process of checking out
5262 everything else, and the section at this point is somewhat
5263 anticlimactic. For this reason, we restrict ourselves
5264 to testing two features not already covered.
5266 Compound statements are delimited by braces. They have the
5267 nice property that identifiers of the auto and register
5268 variety are pushed and popped. It is currently legal to
5269 transfer into a block, but we wont...
5281 if((j
!= 3) || (k
!= 3)) lrc
= 1;
5283 if((j
!= 2) || (k
!= 2)) lrc
= 1;
5287 if(pd0
->flgd
!= 0) printf(s9er
,1);
5291 /* Goto statements go to labeled statements, we hope. */
5294 if(pd0
->flgd
!= 0) printf(s9er
,2);
5300 setev(){ /* Sets an external variable. Used */
5301 extern int extvar
; /* by s4, and should be compiled */
5302 extvar
= 1066; /* separately from s4. */
5304 int lbits
; /* long */
5305 int ubits
; /* unsigned */
5306 int fbits
; /* float */
5307 int dbits
; /* double */
5308 float fprec
; /* Smallest number that can be */
5309 float dprec
; /* significantly added to 1. */
5310 int flgs
; /* Print return codes, by section */
5311 int flgm
; /* Announce machine dependencies */
5312 int flgd
; /* give explicit diagnostics */
5313 int flgl
; /* Report local return codes. */
5314 int rrc
; /* recent return code */
5315 int crc
; /* Cumulative return code */
5316 char rfs
[8]; /* Return from section */