Home | History | Annotate | Download | only in lit_tests
      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