CFI: Add tests for 32-bit, 64-bit and memory bitsets. Break optimization in more...
authorPeter Collingbourne <peter@pcc.me.uk>
Sat, 21 Feb 2015 01:36:08 +0000 (01:36 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Sat, 21 Feb 2015 01:36:08 +0000 (01:36 +0000)
llvm-svn: 230116

compiler-rt/test/cfi/anon-namespace.cpp
compiler-rt/test/cfi/multiple-inheritance.cpp
compiler-rt/test/cfi/overwrite.cpp
compiler-rt/test/cfi/simple-fail.cpp
compiler-rt/test/cfi/simple-pass.cpp
compiler-rt/test/cfi/utils.h [new file with mode: 0644]
compiler-rt/test/cfi/vdtor.cpp

index f634ab3..0c2c689 100644 (file)
@@ -3,6 +3,21 @@
 // RUN: %clangxx_cfi -o %t %t1.o %t2.o
 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
 
+// RUN: %clangxx_cfi -c -DTU1 -DB32 -o %t1.o %s
+// RUN: %clangxx_cfi -c -DTU2 -DB32 -o %t2.o %S/../cfi/anon-namespace.cpp
+// RUN: %clangxx_cfi -o %t %t1.o %t2.o
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -c -DTU1 -DB64 -o %t1.o %s
+// RUN: %clangxx_cfi -c -DTU2 -DB64 -o %t2.o %S/../cfi/anon-namespace.cpp
+// RUN: %clangxx_cfi -o %t %t1.o %t2.o
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -c -DTU1 -DBM -o %t1.o %s
+// RUN: %clangxx_cfi -c -DTU2 -DBM -o %t2.o %S/../cfi/anon-namespace.cpp
+// RUN: %clangxx_cfi -o %t %t1.o %t2.o
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
 // RUN: %clangxx -c -DTU1 -o %t1.o %s
 // RUN: %clangxx -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
 // RUN: %clangxx -o %t %t1.o %t2.o
@@ -19,6 +34,7 @@
 // so we have to mangle the file path into the bitset name.
 
 #include <stdio.h>
+#include "utils.h"
 
 struct A {
   virtual void f() = 0;
@@ -45,7 +61,23 @@ A *mkb() {
 #ifdef TU2
 
 int main() {
+#ifdef B32
+  break_optimization(new Deriver<B, 0>);
+#endif
+
+#ifdef B64
+  break_optimization(new Deriver<B, 0>);
+  break_optimization(new Deriver<B, 1>);
+#endif
+
+#ifdef BM
+  break_optimization(new Deriver<B, 0>);
+  break_optimization(new Deriver<B, 1>);
+  break_optimization(new Deriver<B, 2>);
+#endif
+
   A *a = mkb();
+  break_optimization(a);
 
   // CFI: 1
   // NCFI: 1
index 1b03af4..523af6f 100644 (file)
@@ -2,6 +2,18 @@
 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
 // RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
 
+// RUN: %clangxx_cfi -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
+
 // RUN: %clangxx -o %t %s
 // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
 // RUN: %t x 2>&1 | FileCheck --check-prefix=NCFI %s
@@ -10,6 +22,7 @@
 // permits calls via virtual tables for the correct base class.
 
 #include <stdio.h>
+#include "utils.h"
 
 struct A {
   virtual void f() = 0;
@@ -27,7 +40,29 @@ void C::f() {}
 void C::g() {}
 
 int main(int argc, char **argv) {
+#ifdef B32
+  break_optimization(new Deriver<A, 0>);
+  break_optimization(new Deriver<B, 0>);
+#endif
+
+#ifdef B64
+  break_optimization(new Deriver<A, 0>);
+  break_optimization(new Deriver<A, 1>);
+  break_optimization(new Deriver<B, 0>);
+  break_optimization(new Deriver<B, 1>);
+#endif
+
+#ifdef BM
+  break_optimization(new Deriver<A, 0>);
+  break_optimization(new Deriver<A, 1>);
+  break_optimization(new Deriver<A, 2>);
+  break_optimization(new Deriver<B, 0>);
+  break_optimization(new Deriver<B, 1>);
+  break_optimization(new Deriver<B, 2>);
+#endif
+
   C *c = new C;
+  break_optimization(c);
 
   // CFI: 1
   // NCFI: 1
index 74cb3fd..d7e58d9 100644 (file)
@@ -1,6 +1,15 @@
 // RUN: %clangxx_cfi -o %t %s
 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
 
+// RUN: %clangxx_cfi -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
 // RUN: %clangxx -o %t %s
 // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
 
@@ -10,6 +19,7 @@
 // attempting to make a call through it.
 
 #include <stdio.h>
+#include "utils.h"
 
 struct A {
   virtual void f();
@@ -24,8 +34,24 @@ void foo() {
 void *fake_vtable[] = { (void *)&foo };
 
 int main() {
+#ifdef B32
+  break_optimization(new Deriver<A, 0>);
+#endif
+
+#ifdef B64
+  break_optimization(new Deriver<A, 0>);
+  break_optimization(new Deriver<A, 1>);
+#endif
+
+#ifdef BM
+  break_optimization(new Deriver<A, 0>);
+  break_optimization(new Deriver<A, 1>);
+  break_optimization(new Deriver<A, 2>);
+#endif
+
   A *a = new A;
   *((void **)a) = fake_vtable; // UB here
+  break_optimization(a);
 
   // CFI: 1
   // NCFI: 1
index de3b7ed..d8f3b48 100644 (file)
@@ -1,6 +1,15 @@
 // RUN: %clangxx_cfi -o %t %s
 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
 
+// RUN: %clangxx_cfi -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
 // RUN: %clangxx -o %t %s
 // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
 
@@ -9,6 +18,7 @@
 // pointer to such an object and attempting to make a call through it.
 
 #include <stdio.h>
+#include "utils.h"
 
 struct A {
   virtual void f();
@@ -23,7 +33,23 @@ struct B {
 void B::f() {}
 
 int main() {
+#ifdef B32
+  break_optimization(new Deriver<B, 0>);
+#endif
+
+#ifdef B64
+  break_optimization(new Deriver<B, 0>);
+  break_optimization(new Deriver<B, 1>);
+#endif
+
+#ifdef BM
+  break_optimization(new Deriver<B, 0>);
+  break_optimization(new Deriver<B, 1>);
+  break_optimization(new Deriver<B, 2>);
+#endif
+
   A *a = new A;
+  break_optimization(a);
 
   // CFI: 1
   // NCFI: 1
index e8eb393..50e7d92 100644 (file)
@@ -5,9 +5,7 @@
 // kinds of valid calls involving classes with various different linkages and
 // types of inheritance.
 
-inline void break_optimization(void *arg) {
-  __asm__ __volatile__("" : : "r" (arg) : "memory");
-}
+#include "utils.h"
 
 struct A {
   virtual void f();
diff --git a/compiler-rt/test/cfi/utils.h b/compiler-rt/test/cfi/utils.h
new file mode 100644 (file)
index 0000000..5c290d1
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+inline void break_optimization(void *arg) {
+  __asm__ __volatile__("" : : "r" (arg) : "memory");
+}
+
+// Tests will instantiate this class to pad out bit sets to test out the various
+// ways we can represent the bit set (32-bit inline, 64-bit inline, memory).
+// This class has 37 virtual member functions, which forces us to use a
+// pointer-aligned bitset.
+template <typename T, unsigned I>
+class Deriver : T {
+  virtual void f() {}
+  virtual void g() {}
+  virtual void f1() {}
+  virtual void f2() {}
+  virtual void f3() {}
+  virtual void f4() {}
+  virtual void f5() {}
+  virtual void f6() {}
+  virtual void f7() {}
+  virtual void f8() {}
+  virtual void f9() {}
+  virtual void f10() {}
+  virtual void f11() {}
+  virtual void f12() {}
+  virtual void f13() {}
+  virtual void f14() {}
+  virtual void f15() {}
+  virtual void f16() {}
+  virtual void f17() {}
+  virtual void f18() {}
+  virtual void f19() {}
+  virtual void f20() {}
+  virtual void f21() {}
+  virtual void f22() {}
+  virtual void f23() {}
+  virtual void f24() {}
+  virtual void f25() {}
+  virtual void f26() {}
+  virtual void f27() {}
+  virtual void f28() {}
+  virtual void f29() {}
+  virtual void f30() {}
+  virtual void f31() {}
+  virtual void f32() {}
+  virtual void f33() {}
+  virtual void f34() {}
+  virtual void f35() {}
+};
+
+#endif
index f8101ba..e21883c 100644 (file)
@@ -1,6 +1,15 @@
 // RUN: %clangxx_cfi -o %t %s
 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
 
+// RUN: %clangxx_cfi -DB32 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t %s
+// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+
 // RUN: %clangxx -o %t %s
 // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
 
@@ -8,6 +17,7 @@
 // via 'delete'.
 
 #include <stdio.h>
+#include "utils.h"
 
 struct A {
   virtual ~A();
@@ -22,7 +32,23 @@ struct B {
 B::~B() {}
 
 int main() {
+#ifdef B32
+  break_optimization(new Deriver<B, 0>);
+#endif
+
+#ifdef B64
+  break_optimization(new Deriver<B, 0>);
+  break_optimization(new Deriver<B, 1>);
+#endif
+
+#ifdef BM
+  break_optimization(new Deriver<B, 0>);
+  break_optimization(new Deriver<B, 1>);
+  break_optimization(new Deriver<B, 2>);
+#endif
+
   A *a = new A;
+  break_optimization(a);
 
   // CFI: 1
   // NCFI: 1