xref: /aosp_15_r20/external/compiler-rt/test/asan/TestCases/init-order-atexit.cc (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // Test for the following situation:
2*7c3d14c8STreehugger Robot // (1) global A is constructed.
3*7c3d14c8STreehugger Robot // (2) exit() is called during construction of global B.
4*7c3d14c8STreehugger Robot // (3) destructor of A reads uninitialized global C from another module.
5*7c3d14c8STreehugger Robot // We do *not* want to report init-order bug in this case.
6*7c3d14c8STreehugger Robot 
7*7c3d14c8STreehugger Robot // RUN: %clangxx_asan -O0 %s %p/Helpers/init-order-atexit-extra.cc -o %t
8*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_init_order=true not %run %t 2>&1 | FileCheck %s
9*7c3d14c8STreehugger Robot 
10*7c3d14c8STreehugger Robot #include <stdio.h>
11*7c3d14c8STreehugger Robot #include <stdlib.h>
12*7c3d14c8STreehugger Robot 
13*7c3d14c8STreehugger Robot void AccessC();
14*7c3d14c8STreehugger Robot 
15*7c3d14c8STreehugger Robot class A {
16*7c3d14c8STreehugger Robot  public:
A()17*7c3d14c8STreehugger Robot   A() { }
~A()18*7c3d14c8STreehugger Robot   ~A() { AccessC(); printf("PASSED\n"); }
19*7c3d14c8STreehugger Robot   // CHECK-NOT: AddressSanitizer
20*7c3d14c8STreehugger Robot   // CHECK: PASSED
21*7c3d14c8STreehugger Robot };
22*7c3d14c8STreehugger Robot 
23*7c3d14c8STreehugger Robot A a;
24*7c3d14c8STreehugger Robot 
25*7c3d14c8STreehugger Robot class B {
26*7c3d14c8STreehugger Robot  public:
B()27*7c3d14c8STreehugger Robot   B() { exit(1); }
~B()28*7c3d14c8STreehugger Robot   ~B() { }
29*7c3d14c8STreehugger Robot };
30*7c3d14c8STreehugger Robot 
31*7c3d14c8STreehugger Robot B b;
32