C 1 1 1, C,.,,, if, for,.,, while, switch,,,. Orange4,, GCC-8.0.0 LLVM/Clang-6.0 ( 2017 12 ).,,,, Enriching Generation of Control Statements and Data Structures for Random Test of C Compilers Based on Equivalence Transformation Takakura Shogo 1 Iwatsuji Mitsuyoshi 1 Ishiura Nagisa 1 Abstract: This article proposes a method of enriching program generation in random testing of C compilers based on equivalence transformation on test programs. While the conventional method based on equivalence transformation can only generate programs with scalar variables, assign statements, if and for statements, the proposed method enables generation of arrays, structs, unions, as well as while and switch andfunction calls. Orange4 C compiler test system extended with the proposed method has detected bugs in the latest development versions of GCC-8.0.0 and LLVM/Clang-6.0 which had been missed by the existing test methods. Keywords: compiler, random test, equivalence transformation, minimization, reliability 1.,.,.,,., 1 Kwansei Gauin Uniersity, 2 1 Gakuen, Sanda, Hyogo, 669 1337, Japan [1]. C, Csmith [2]. Csmith C, 2010 3 GCC LLVM/Clang 79 202,. Csmith,,.,, 9
1:. Csmith,, (B!=0? A/B : A),.,., Orange3 [3], Orange4 [4],., Csmith., Csmith GCC LLVM.,,., Orange3, Orange4,, if for., Orange4, C, Csmith.,., if, for while, switch, [5].,,,. Orange4, Csmith, Csmith., C GCC-8.0.0, LLVM/Clang-6.0, 2. 2. 2.1 1.,.,,, ( ).,,.,,.., ( ),. Csmith [2]., ( ),. Quest [6] Orange3 [3], Orange4 [4].. Csmith,,.,,.,,. Quest, Csmith, Orange3.. Proteus [7], Athena [8], Hermes [9] Csmith. Orange4,. 2.2 Csmith Csmith [2] 2.,,,. if, for,, goto. Csmith,., 26 safe mul func uint8 t u u,, 1. 20, for,., 22, 24., while case switch. Csmith, C-Reduce [10]. C- Reduce C,. C,,., 10
1: #pragma pack(push) 2: #pragma pack(1) 3: struct S1 { 4: volatile int32 t f0; 5: struct S0 f4; 6: volatile uint8 t f7; 7: ; 8: #pragma pack(pop) 9: union U3 { 10: const uint32 t f0; 11: const volatile int64 t f1; 12: int32 t f2; 13: ; 14:... 15: static uint32 t * func 1(void) 16: 17: { 18:... 19: if (func 2(g 31[3])) { 20: for (i = 0; i < 1; i++) 21: l 96[i] = &g 97; 22: (****g 1658) = ((((safe mod func int32 t s s( 23: g 450[(g 133.f6 + 2)][(g 133.f6 + 3)], g 62)) >= 24: l 172), 0x5318L), (g 1725, l 1726)); 24: (*p 61) = ((*g 821) = (safe lshift func uint8 t u u( 25: ((safe mul func uint8 t u u(g 22.f1, l 1371)) 26: ((++l 1664) > l 1667)), l 1336))); 27: 28:... 29: 30:... 31: int main ( int argc, char* argv[]) 32: { 33:... 34: func 1(); 35:... 36:. 2: Csmith 2.3 Orange4 Orange4 [4] 3. Orange4,. 12 for., 22 24. for if,. Orange4, return 0; ( )., 4,.,.,.,. Orange4, 1.,. Orange4,,,., for, 0 1.,, 1: #define OK() 3: #define NG(fmt,val) builtin abort() 3: const volatile signed int x9 = -59; 4: int main (void) 5: { 6: static unsigned long long x0 = 7LLU; 7: static const volatile signed long x1 = 0L; 8:... 9: int t0 = 46; 10: signed long t1 = 297271L; 11:... 12: for( i = x9*x6-x8; i < x5+x5; i -= x7+x3 ) { 13: t0 = x3 x0*x2-x4; 14: t1 = x5*x5-x6+x2/x7; 15: if( x1<<x1 ) { 16: t2 = x8>>x4/t0+x10*x10+x11; 17: 18: else { 19: t3 = x14 x16; 20: 21: 22: if (t0 == 120) { OK(); else { NG("%d", t6); 23: if (t1 == 220) { OK(); else { NG("%d", t6); 24: if (t3 == 22) { OK(); else { NG("%d", t6); 25: return 0; 26: 3: Orange4 4: Orange4 s volatile, 2,. Orange4,.,., (),., Orange4,, Csmith. 3. Orange4, Orange4,. while, switch, [5],,,. 3.1 3.1.1,,,, Orange4. 6. 5, (x2.m1[2][3].m4)., ([][]), 11
1: int func0(int a0[5], long a1) { 2:... 3: t50 = a0[2] + x43; 4: if (t50 == -59000) {OK(); else {NG(); 5: return t50 + x51 - a0[4]; 6: 7: int main(void) { 8: int x6[5] = {1227,4,-59433,-106,24; 9: int t42[3][5] = { {-3290,559,23085,26668,-38567, {358148,8,4,35388,85600, {12594474,-293697,979,-125774,1138055 ; 10:... 11: t42[1][2] = (x4 - x3) - func0(x6, x11 * x12) ;// = 100 12: unsigned int t48[x6[1] + t42[1][2]]; 13: t48[0] = x6[1] * x11; 14: t42[x12][t4[4]] = (x5 && t48[x16 + t1]) + t2; 15:... 16: if (t42[1][2] == 100) {OK(); else {NG(); 17: 5: 6: (2, 3)..,.,,.,,. 3.1.2 5.,,,.,, 11 14, x6[1].,,.. 6,. 12., 13 14,,.,., 11., 3.,,,.,,,,. 1: struct s0 { 2: signed int m0; 3: unsigned int m1; 4: ; 5: union u0 { 6: signed int m0; 7: struct s0 m1; 8: ; 9: struct s1 { 10: signed int m0[2][2]; 11: union u0 m1; 12: struct s0 m2[2]; 13: union u0 m3[5]; 14: ; 15: void func0(struct s1 a0, long a1) { 16: t50 = a0.m0 + x43; 17: if (t50 == -59000) {OK(); else {NG(); 18: 19: int main(void) { 20: struct s0 t0 = {64, 33; 21: union u0 x1= {16; 22: struct s1 x2 = {{{0, 3, {2, 8, {66, {{125, 33, {64, 666;... 23: func0(x2, x33 + x1.m0); 24: t0.m1 = x3 + x1.m0 - x2.m2[x3-x4].m1 - x15; 25: if (t0.m1 == 647){ 26:... 27: 7: 3.1.3 7. 1 14,,,,., 21 1, 1. 3.2 3.2.1 while,.,, while case switch. 3.2.2,,. 8. 8 f1 5, 5. 13 14 f1 (5, 9),. volatile,,. 6 7,,. 3.2.3 while, while for 0 1. 0 while, 9 (a), 12
1: int f1 ( unsigned short a1, long a2 ){ 2: t1 = ((x23 * a1) >> x2 & x8); 3: t2 = (t1 x5); 4:... 5: t99 = (x15 * x2) - (x10 - a1); 6: if( a1 == 5 ){OK(); else{ng(); 7: if( a2 == 9 ){OK(); else{ng(); 8: return (a1-x3); 9: 10: int main(void){ 11: int x1 = 34; 12:... 13: int t3 = ((x2 + f1((x2*x7), (x1-x5))) & x8) 14: int t4 = (t3 < x7) >> f1((t3/x9), (x8-x7)) / x5; 15:... while( 0 ){ while( 1 ){ if ( 1 ){ 8: while( ((x3<<t7)&(a8%x5)) ){ (a) 0 while while( (t2*x4)!=(x1>>x10) ){ if( (a1-x11)-(x2/t5) ){ (b) 1 while 9: while 0 while,.., 1 while, 9 (b), 1 while. 0 1 ( ), volatile, 2. 3.2.4 switch switch 10., switch case ( {3, 4), switch ( 4) (default )., switch. 3.3,.,,,. while, while, 0 while, 1 while.,.,. 11. 5 t0,.. switch ( 4 ) { case 3: case 4: default: switch ( (t2*x4)!=(x1>>x10) ) { case (a0-x13)-(x21/t3): case (x3-a3)*(t6*x12): default: 10: switch 1: int t0[3] = {0, 1, 2; 2: x0 = 5; 3: int main(void) 4: { 5: t1 = t0[0] + x0 + t0[1 * t0[1]]; 6: if (t1 == 6) {OK(); else {NG(); 7: 1: int t0 0 = 0; int t0 1 = 1; 2: x0 = 5; 3: int main(void) 4: { 5: t1 = t0 0 + x0 + t0 1; 6: if (t1 == 6) {OK(); else {NG(); 7: 11: 1: compiler Csmith Orange4 time[h] #error time[h] #error GCC-4.4.7 46.4 5 54.5 25 GCC-4.5.4 30.2 1 56.7 30 GCC-4.6.4 31.3 0 56.4 10 GCC-4.7.3 35.6 0 62.1 10 (Ubuntu 14.04 LTS, Xeon, 3.60GHz, RAM 16GB) 4. Orange4 Perl 5.20.2. Ubuntu Linux Mac OSX Unix. Csmith GCC 1. #error. 100,000,., Csmith 15.3 KB, Orange4 8.9 KB. 2, Csmith. *., 2. 12., Csmith Orange4.. (a), t 1 10 if, 11 return 0;, -O3, t 0, builtin abort();. (b), -O1 linker 13
2: Csmith Csmith Orange4 ( ) if for Csmith,, 0 1 * while * switch * goto *, * 1: int a[2] = {0,1; 2: int x = 129; 3: int main (void) 4: { 5: volatile int v = 0; 6: int t = x; 7: for (int i=0; i < (1+v+v+v+v+v+v+v+v+a[a[0]]); i++) { 8: t = a[(signed char)(130-x)]; 9: 10: if (t!= 1) builtin abort(); 11: return 0; 12: (a) GCC-8.0.0 1: #define INT MAX 0x7fffffff 2: char a[1][1] = { {1 ; 3: int x = 0; 4: int y = -INT MAX; 5: int main (void) 6: { 7: if (a[x][int MAX+y]!= 1) builtin abort(); 8: return 0; 9: (b) LLVM/Clang-6.0 12: command failed. Bugzilla * 1 *2. 3, GCC-4.8.5 11 Orange4 C-Reduce. Orange4 C-Reduce.,,. 5., C Orange4,. Csmith *1 https://bugs.llvm.org/show bug.cgi?id=35159 *2 https://gcc.gnu.org/bugzilla/show bug.cgi?id=83580 3: CPU time[sec] C-Reduce Orange4 #01 328.2 6.7 #02 155.0 24.8 #03 990.6 15.7 #04 106.0 13.9 #05 254.3 31.3 #06 76.1 4.2 #07 1697.3 5.7 #08 3888.2 23.2 #09 1521.5 20.4 #10 106.8 4.5 #11 72.8 6.6 (Ubuntu 14.04 LTS, Xeon, 3.60GHz, RAM 16GB),., GCC-8.0.0, LLVM/Clang-6.0,.,, 2 C, C., Orange4 2016 12 22 GitHub *3.,. JSPS 25330073. [1] :, Fundamentals Review, vol. 9, no. 3, pp. 188 196 (Jan. 2016). [2] X. Yang, Y. Chen, E. Eide, and J. Regehr: Finding and Understanding Bugs in C Compilers, in Proc. PLDI 2011, pp. 283 294 (June 2011). [3] E. Nagai, A. Hashimoto, and N. Ishiura: Reinforcing Random Testing of Arithmetic Optimization of C Compilers by Scaling up Size and Number of Expressions, IPSJ Trans. SLDM, vol. 7, pp. 91 100 (Aug. 2014). [4] K. Nakamura and N. Ishiura: Random Testing of C Compilers Based on Test Program Generation by Equivalence Transformation, in Proc. APCCAS 2016, pp. 676 679 (Oct. 2016). [5], : C,, VLD2017-87 (Jan. 2018). [6] C. Lindig: Find a Compiler Bug in 5 Minutes, in Proc. ACM International Symposium on Automated Analysis-Driven Debugging, pp. 3 12 (Sept. 2005). [7] V. Le, C. Sun, and Z. Su: Randomized Stress-Testing of Link-Time Optimizers, in Proc. ISSTA 2015, pp. 327 337 (July 2015). [8] V. Le, C. Sun, and Z. Su: Finding Deep Compiler Bugs via Guided Stochastic Program Mutation, in Proc. ACM OOPSLA 2015, pp. 386 399 (Oct. 2015). [9] Gergo Barany: Finding Compiler Bugs via Live Code Mutation, in Proc. OOPSLA 2016, pp. 849 863 (Oct. 2016). [10] J. Regehr, Y. Chen, P. Cuoq, E. Eide, C. Ellison and X. Yang: Test-Case Reduction for C Compiler Bugs, in Proc. PLDI 2012, pp. 335 346 (June 2012). *3 https://github.com/ishiura-compiler/orange4 14