xref: /llvm-project/compiler-rt/test/asan/TestCases/initialization-bug.cpp (revision 38e9660eaa3478b003cbc48cb4ed0adcf22e053a)
1673dc3d4SNico Weber // Test to make sure basic initialization order errors are caught.
2673dc3d4SNico Weber 
31f3c92f9SJulian Lettner // RUN: %clangxx_asan %min_macos_deployment_target=10.11 -O0 %s %p/Helpers/initialization-bug-extra2.cpp -o %t-INIT-ORDER-EXE
4673dc3d4SNico Weber // RUN: %env_asan_opts=check_initialization_order=true not %run %t-INIT-ORDER-EXE 2>&1 | FileCheck %s
5673dc3d4SNico Weber 
6673dc3d4SNico Weber // Do not test with optimization -- the error may be optimized away.
7673dc3d4SNico Weber 
8673dc3d4SNico Weber // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=186
9*38e9660eSPaul Robinson // XFAIL: target={{.*windows-msvc.*}}
10673dc3d4SNico Weber 
11673dc3d4SNico Weber #include <cstdio>
12673dc3d4SNico Weber 
13673dc3d4SNico Weber // The structure of the test is:
14673dc3d4SNico Weber // "x", "y", "z" are dynamically initialized globals.
15673dc3d4SNico Weber // Value of "x" depends on "y", value of "y" depends on "z".
16673dc3d4SNico Weber // "x" and "z" are defined in this TU, "y" is defined in another one.
17a1e7e401SKazuaki Ishizaki // Thus we should stably report initialization order fiasco independently of
18673dc3d4SNico Weber // the translation unit order.
19673dc3d4SNico Weber 
initZ()20673dc3d4SNico Weber int initZ() {
21673dc3d4SNico Weber   return 5;
22673dc3d4SNico Weber }
23673dc3d4SNico Weber int z = initZ();
24673dc3d4SNico Weber 
25673dc3d4SNico Weber // 'y' is a dynamically initialized global residing in a different TU.  This
26673dc3d4SNico Weber // dynamic initializer will read the value of 'y' before main starts.  The
27673dc3d4SNico Weber // result is undefined behavior, which should be caught by initialization order
28673dc3d4SNico Weber // checking.
29673dc3d4SNico Weber extern int y;
initX()30673dc3d4SNico Weber int __attribute__((noinline)) initX() {
31673dc3d4SNico Weber   return y + 1;
32673dc3d4SNico Weber   // CHECK: {{AddressSanitizer: initialization-order-fiasco}}
33673dc3d4SNico Weber   // CHECK: {{READ of size .* at 0x.* thread T0}}
34673dc3d4SNico Weber   // CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}}
35673dc3d4SNico Weber   // CHECK: registered at:
36673dc3d4SNico Weber   // CHECK: 0x{{.*}} in __asan_register_globals
37673dc3d4SNico Weber }
38673dc3d4SNico Weber 
39673dc3d4SNico Weber // This initializer begins our initialization order problems.
40673dc3d4SNico Weber static int x = initX();
41673dc3d4SNico Weber 
main()42673dc3d4SNico Weber int main() {
43673dc3d4SNico Weber   // ASan should have caused an exit before main runs.
44673dc3d4SNico Weber   printf("PASS\n");
45673dc3d4SNico Weber   // CHECK-NOT: PASS
46673dc3d4SNico Weber   return 0;
47673dc3d4SNico Weber }
48