1 // Test to make sure basic initialization order errors are caught. 2 3 // RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t 4 // RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \ 5 // RUN: | %symbolize | FileCheck %s 6 // RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t 7 // RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \ 8 // RUN: | %symbolize | FileCheck %s 9 10 // Do not test with optimization -- the error may be optimized away. 11 12 #include <cstdio> 13 14 // The structure of the test is: 15 // "x", "y", "z" are dynamically initialized globals. 16 // Value of "x" depends on "y", value of "y" depends on "z". 17 // "x" and "z" are defined in this TU, "y" is defined in another one. 18 // Thus we shoud stably report initialization order fiasco independently of 19 // the translation unit order. 20 21 int initZ() { 22 return 5; 23 } 24 int z = initZ(); 25 26 // 'y' is a dynamically initialized global residing in a different TU. This 27 // dynamic initializer will read the value of 'y' before main starts. The 28 // result is undefined behavior, which should be caught by initialization order 29 // checking. 30 extern int y; 31 int __attribute__((noinline)) initX() { 32 return y + 1; 33 // CHECK: {{AddressSanitizer: initialization-order-fiasco}} 34 // CHECK: {{READ of size .* at 0x.* thread T0}} 35 // CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}} 36 } 37 38 // This initializer begins our initialization order problems. 39 static int x = initX(); 40 41 int main() { 42 // ASan should have caused an exit before main runs. 43 printf("PASS\n"); 44 // CHECK-NOT: PASS 45 return 0; 46 } 47