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 Weberint 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 Weberint __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 Weberint 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