summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2015-02-21 01:36:08 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2015-02-21 01:36:08 +0000
commit4f329a291f815d455decdbccb3c61a22226f43f1 (patch)
treeb8b202369090b42fc0230ccff2eb28814dd8a042
parent061391b2a6bc3cded72268ab3af4677cb6fca45e (diff)
CFI: Add tests for 32-bit, 64-bit and memory bitsets. Break optimization in more places.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@230116 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--test/cfi/anon-namespace.cpp32
-rw-r--r--test/cfi/multiple-inheritance.cpp35
-rw-r--r--test/cfi/overwrite.cpp26
-rw-r--r--test/cfi/simple-fail.cpp26
-rw-r--r--test/cfi/simple-pass.cpp4
-rw-r--r--test/cfi/utils.h53
-rw-r--r--test/cfi/vdtor.cpp26
7 files changed, 199 insertions, 3 deletions
diff --git a/test/cfi/anon-namespace.cpp b/test/cfi/anon-namespace.cpp
index f634ab352..0c2c68996 100644
--- a/test/cfi/anon-namespace.cpp
+++ b/test/cfi/anon-namespace.cpp
@@ -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
diff --git a/test/cfi/multiple-inheritance.cpp b/test/cfi/multiple-inheritance.cpp
index 1b03af4a1..523af6f72 100644
--- a/test/cfi/multiple-inheritance.cpp
+++ b/test/cfi/multiple-inheritance.cpp
@@ -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
diff --git a/test/cfi/overwrite.cpp b/test/cfi/overwrite.cpp
index 74cb3fdcb..d7e58d927 100644
--- a/test/cfi/overwrite.cpp
+++ b/test/cfi/overwrite.cpp
@@ -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
diff --git a/test/cfi/simple-fail.cpp b/test/cfi/simple-fail.cpp
index de3b7ed1b..d8f3b487c 100644
--- a/test/cfi/simple-fail.cpp
+++ b/test/cfi/simple-fail.cpp
@@ -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
diff --git a/test/cfi/simple-pass.cpp b/test/cfi/simple-pass.cpp
index e8eb3939c..50e7d9256 100644
--- a/test/cfi/simple-pass.cpp
+++ b/test/cfi/simple-pass.cpp
@@ -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/test/cfi/utils.h b/test/cfi/utils.h
new file mode 100644
index 000000000..5c290d151
--- /dev/null
+++ b/test/cfi/utils.h
@@ -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
diff --git a/test/cfi/vdtor.cpp b/test/cfi/vdtor.cpp
index f8101bac8..e21883c38 100644
--- a/test/cfi/vdtor.cpp
+++ b/test/cfi/vdtor.cpp
@@ -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