xref: /llvm-project/compiler-rt/test/cfi/anon-namespace.cpp (revision 3ccd23e1166ff7d79eb89579c0cd5056934a8f6c)
1e0c4f7ebSPeter Collingbourne // RUN: %clangxx_cfi -c -DTU1 -o %t1.o %s
2e0c4f7ebSPeter Collingbourne // RUN: %clangxx_cfi -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
3702548d9SPeter Collingbourne // RUN: %clangxx_cfi -o %t1 %t1.o %t2.o
4*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t1 2>&1 | FileCheck --check-prefix=CFI %s
5e0c4f7ebSPeter Collingbourne 
6f1d13da2SPeter Collingbourne // RUN: %clangxx_cfi -c -DTU1 -DB32 -o %t1.o %s
7f1d13da2SPeter Collingbourne // RUN: %clangxx_cfi -c -DTU2 -DB32 -o %t2.o %S/../cfi/anon-namespace.cpp
8702548d9SPeter Collingbourne // RUN: %clangxx_cfi -o %t2 %t1.o %t2.o
9*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t2 2>&1 | FileCheck --check-prefix=CFI %s
10f1d13da2SPeter Collingbourne 
11f1d13da2SPeter Collingbourne // RUN: %clangxx_cfi -c -DTU1 -DB64 -o %t1.o %s
12f1d13da2SPeter Collingbourne // RUN: %clangxx_cfi -c -DTU2 -DB64 -o %t2.o %S/../cfi/anon-namespace.cpp
13702548d9SPeter Collingbourne // RUN: %clangxx_cfi -o %t3 %t1.o %t2.o
14*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t3 2>&1 | FileCheck --check-prefix=CFI %s
15f1d13da2SPeter Collingbourne 
16f1d13da2SPeter Collingbourne // RUN: %clangxx_cfi -c -DTU1 -DBM -o %t1.o %s
17f1d13da2SPeter Collingbourne // RUN: %clangxx_cfi -c -DTU2 -DBM -o %t2.o %S/../cfi/anon-namespace.cpp
18702548d9SPeter Collingbourne // RUN: %clangxx_cfi -o %t4 %t1.o %t2.o
19*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t4 2>&1 | FileCheck --check-prefix=CFI %s
20f1d13da2SPeter Collingbourne 
21e0c4f7ebSPeter Collingbourne // RUN: %clangxx -c -DTU1 -o %t1.o %s
22e0c4f7ebSPeter Collingbourne // RUN: %clangxx -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
23702548d9SPeter Collingbourne // RUN: %clangxx -o %t5 %t1.o %t2.o
24*3ccd23e1SFilipe Cabecinhas // RUN: %run %t5 2>&1 | FileCheck --check-prefix=NCFI %s
25e0c4f7ebSPeter Collingbourne 
26175d6332SPeter Collingbourne // RUN: %clangxx_cfi_diag -c -DTU1 -o %t1.o %s
27175d6332SPeter Collingbourne // RUN: %clangxx_cfi_diag -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
28702548d9SPeter Collingbourne // RUN: %clangxx_cfi_diag -o %t6 %t1.o %t2.o
29*3ccd23e1SFilipe Cabecinhas // RUN: %run %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
30175d6332SPeter Collingbourne 
31e0c4f7ebSPeter Collingbourne // Tests that the CFI mechanism treats classes in the anonymous namespace in
32e0c4f7ebSPeter Collingbourne // different translation units as having distinct identities. This is done by
33e0c4f7ebSPeter Collingbourne // compiling two translation units TU1 and TU2 containing a class named B in an
34e0c4f7ebSPeter Collingbourne // anonymous namespace, and testing that the program crashes if TU2 attempts to
35e0c4f7ebSPeter Collingbourne // use a TU1 B as a TU2 B.
36e0c4f7ebSPeter Collingbourne 
37e0c4f7ebSPeter Collingbourne // FIXME: This test should not require that the paths supplied to the compiler
38e0c4f7ebSPeter Collingbourne // are different. It currently does so because bitset names have global scope
39e0c4f7ebSPeter Collingbourne // so we have to mangle the file path into the bitset name.
40e0c4f7ebSPeter Collingbourne 
41a084e16eSAlexey Samsonov // REQUIRES: cxxabi
42a084e16eSAlexey Samsonov 
43e0c4f7ebSPeter Collingbourne #include <stdio.h>
44f1d13da2SPeter Collingbourne #include "utils.h"
45e0c4f7ebSPeter Collingbourne 
46e0c4f7ebSPeter Collingbourne struct A {
47e0c4f7ebSPeter Collingbourne   virtual void f() = 0;
48e0c4f7ebSPeter Collingbourne };
49e0c4f7ebSPeter Collingbourne 
50e0c4f7ebSPeter Collingbourne namespace {
51e0c4f7ebSPeter Collingbourne 
52e0c4f7ebSPeter Collingbourne struct B : A {
f__anon4dac90060111::B53e0c4f7ebSPeter Collingbourne   virtual void f() {}
54e0c4f7ebSPeter Collingbourne };
55e0c4f7ebSPeter Collingbourne 
56e0c4f7ebSPeter Collingbourne }
57e0c4f7ebSPeter Collingbourne 
58e0c4f7ebSPeter Collingbourne A *mkb();
59e0c4f7ebSPeter Collingbourne 
60e0c4f7ebSPeter Collingbourne #ifdef TU1
61e0c4f7ebSPeter Collingbourne 
mkb()62e0c4f7ebSPeter Collingbourne A *mkb() {
63e0c4f7ebSPeter Collingbourne   return new B;
64e0c4f7ebSPeter Collingbourne }
65e0c4f7ebSPeter Collingbourne 
66e0c4f7ebSPeter Collingbourne #endif  // TU1
67e0c4f7ebSPeter Collingbourne 
68e0c4f7ebSPeter Collingbourne #ifdef TU2
69e0c4f7ebSPeter Collingbourne 
main()70e0c4f7ebSPeter Collingbourne int main() {
71ea087056SPeter Collingbourne   create_derivers<B>();
72f1d13da2SPeter Collingbourne 
73e0c4f7ebSPeter Collingbourne   A *a = mkb();
74f1d13da2SPeter Collingbourne   break_optimization(a);
75e0c4f7ebSPeter Collingbourne 
76e0c4f7ebSPeter Collingbourne   // CFI: 1
77e0c4f7ebSPeter Collingbourne   // NCFI: 1
78e0c4f7ebSPeter Collingbourne   fprintf(stderr, "1\n");
79e0c4f7ebSPeter Collingbourne 
80175d6332SPeter Collingbourne   // CFI-DIAG: runtime error: control flow integrity check for type '(anonymous namespace)::B' failed during base-to-derived cast
81702548d9SPeter Collingbourne   // CFI-DIAG-NEXT: note: vtable is of type '{{.*}}anonymous namespace{{.*}}::B'
82175d6332SPeter Collingbourne   // CFI-DIAG: runtime error: control flow integrity check for type '(anonymous namespace)::B' failed during virtual call
83702548d9SPeter Collingbourne   // CFI-DIAG-NEXT: note: vtable is of type '{{.*}}anonymous namespace{{.*}}::B'
84e0c4f7ebSPeter Collingbourne   ((B *)a)->f(); // UB here
85e0c4f7ebSPeter Collingbourne 
86702548d9SPeter Collingbourne   // CFI-NOT: {{^2$}}
87702548d9SPeter Collingbourne   // NCFI: {{^2$}}
88e0c4f7ebSPeter Collingbourne   fprintf(stderr, "2\n");
89e0c4f7ebSPeter Collingbourne }
90e0c4f7ebSPeter Collingbourne 
91e0c4f7ebSPeter Collingbourne #endif  // TU2
92