forked from OSchip/llvm-project
CFI: Update tests for various bit vector sizes following lowerbitsets optzns.
Also add a test to ensure that this doesn't regress. Differential Revision: http://reviews.llvm.org/D11584 llvm-svn: 243547
This commit is contained in:
parent
3eddf499b7
commit
ea087056ae
|
@ -19,7 +19,7 @@ if(NOT ANDROID)
|
||||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||||
# Use LLVM utils and Clang from the same build tree.
|
# Use LLVM utils and Clang from the same build tree.
|
||||||
list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS
|
list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS
|
||||||
clang clang-headers FileCheck count not llvm-nm llvm-symbolizer
|
clang clang-headers FileCheck count not llvm-config llvm-nm llvm-symbolizer
|
||||||
compiler-rt-headers)
|
compiler-rt-headers)
|
||||||
if (COMPILER_RT_HAS_PROFILE)
|
if (COMPILER_RT_HAS_PROFILE)
|
||||||
list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS profile)
|
list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS profile)
|
||||||
|
|
|
@ -3,12 +3,10 @@ configure_lit_site_cfg(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
|
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CFI_TEST_DEPS)
|
set(CFI_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
|
||||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||||
list(APPEND CFI_TEST_DEPS
|
list(APPEND CFI_TEST_DEPS
|
||||||
FileCheck
|
opt
|
||||||
clang
|
|
||||||
not
|
|
||||||
ubsan
|
ubsan
|
||||||
)
|
)
|
||||||
if(LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR)
|
if(LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR)
|
||||||
|
|
|
@ -68,20 +68,7 @@ A *mkb() {
|
||||||
#ifdef TU2
|
#ifdef TU2
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#ifdef B32
|
create_derivers<B>();
|
||||||
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();
|
A *a = mkb();
|
||||||
break_optimization(a);
|
break_optimization(a);
|
||||||
|
|
|
@ -87,20 +87,7 @@ struct C : A {
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
#ifdef B32
|
create_derivers<B>();
|
||||||
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
|
|
||||||
|
|
||||||
B *b = new B;
|
B *b = new B;
|
||||||
break_optimization(b);
|
break_optimization(b);
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
REQUIRES: asserts
|
||||||
|
|
||||||
|
RUN: %clangxx_cfi -c -o %t1.o %S/simple-fail.cpp
|
||||||
|
RUN: opt -lowerbitsets -debug-only=lowerbitsets -o /dev/null %t1.o 2>&1 | FileCheck --check-prefix=B0 %s
|
||||||
|
B0: {{1B|B@@}}: {{.*}} size 1
|
||||||
|
|
||||||
|
RUN: %clangxx_cfi -DB32 -c -o %t2.o %S/simple-fail.cpp
|
||||||
|
RUN: opt -lowerbitsets -debug-only=lowerbitsets -o /dev/null %t2.o 2>&1 | FileCheck --check-prefix=B32 %s
|
||||||
|
B32: {{1B|B@@}}: {{.*}} size 24
|
||||||
|
B32-NOT: all-ones
|
||||||
|
|
||||||
|
RUN: %clangxx_cfi -DB64 -c -o %t3.o %S/simple-fail.cpp
|
||||||
|
RUN: opt -lowerbitsets -debug-only=lowerbitsets -o /dev/null %t3.o 2>&1 | FileCheck --check-prefix=B64 %s
|
||||||
|
B64: {{1B|B@@}}: {{.*}} size 54
|
||||||
|
B64-NOT: all-ones
|
||||||
|
|
||||||
|
RUN: %clangxx_cfi -DBM -c -o %t4.o %S/simple-fail.cpp
|
||||||
|
RUN: opt -lowerbitsets -debug-only=lowerbitsets -o /dev/null %t4.o 2>&1 | FileCheck --check-prefix=BM %s
|
||||||
|
BM: {{1B|B@@}}: {{.*}} size 84
|
||||||
|
BM-NOT: all-ones
|
|
@ -2,7 +2,7 @@ import lit.formats
|
||||||
import os
|
import os
|
||||||
|
|
||||||
config.name = 'cfi'
|
config.name = 'cfi'
|
||||||
config.suffixes = ['.cpp']
|
config.suffixes = ['.cpp', '.test']
|
||||||
config.test_source_root = os.path.dirname(__file__)
|
config.test_source_root = os.path.dirname(__file__)
|
||||||
|
|
||||||
clangxx = ' '.join([config.clang] + config.cxx_mode_flags)
|
clangxx = ' '.join([config.clang] + config.cxx_mode_flags)
|
||||||
|
|
|
@ -46,26 +46,8 @@ void C::f() {}
|
||||||
void C::g() {}
|
void C::g() {}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
#ifdef B32
|
create_derivers<A>();
|
||||||
break_optimization(new Deriver<A, 0>);
|
create_derivers<B>();
|
||||||
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;
|
C *c = new C;
|
||||||
break_optimization(c);
|
break_optimization(c);
|
||||||
|
|
|
@ -40,20 +40,7 @@ void B::f() {}
|
||||||
void B::g() {}
|
void B::g() {}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#ifdef B32
|
create_derivers<B>();
|
||||||
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;
|
A *a = new A;
|
||||||
break_optimization(a);
|
break_optimization(a);
|
||||||
|
|
|
@ -39,20 +39,7 @@ void foo() {
|
||||||
void *fake_vtable[] = { 0, 0, (void *)&foo };
|
void *fake_vtable[] = { 0, 0, (void *)&foo };
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#ifdef B32
|
create_derivers<A>();
|
||||||
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;
|
A *a = new A;
|
||||||
*((void **)a) = fake_vtable + 2; // UB here
|
*((void **)a) = fake_vtable + 2; // UB here
|
||||||
|
|
|
@ -37,20 +37,7 @@ struct C : A {
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#ifdef B32
|
create_derivers<B>();
|
||||||
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
|
|
||||||
|
|
||||||
B *b = new B;
|
B *b = new B;
|
||||||
break_optimization(b);
|
break_optimization(b);
|
||||||
|
|
|
@ -74,20 +74,7 @@ struct B {
|
||||||
void B::f() {}
|
void B::f() {}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#ifdef B32
|
create_derivers<B>();
|
||||||
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;
|
A *a = new A;
|
||||||
break_optimization(a);
|
break_optimization(a);
|
||||||
|
|
|
@ -5,49 +5,63 @@ inline void break_optimization(void *arg) {
|
||||||
__asm__ __volatile__("" : : "r" (arg) : "memory");
|
__asm__ __volatile__("" : : "r" (arg) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests will instantiate this class to pad out bit sets to test out the various
|
// Tests will instantiate this class to pad out bit sets to test out the
|
||||||
// ways we can represent the bit set (32-bit inline, 64-bit inline, memory).
|
// various ways we can represent the bit set (32-bit inline, 64-bit inline,
|
||||||
// This class has 37 virtual member functions, which forces us to use a
|
// memory). Instantiating this class will trigger the instantiation of I
|
||||||
// pointer-aligned bitset.
|
// templates with I virtual tables for classes deriving from T, I-2 of which
|
||||||
|
// will be of size sizeof(void*) * 5, 1 of which will be of size sizeof(void*)
|
||||||
|
// * 3, and 1 of which will be of size sizeof(void*) * 9. (Under the MS ABI
|
||||||
|
// each virtual table will be sizeof(void*) bytes smaller). Each category
|
||||||
|
// of virtual tables is aligned to a different power of 2, precluding the
|
||||||
|
// all-ones optimization. As a result, the bit vector for the base class will
|
||||||
|
// need to contain at least I*2 entries to accommodate all the derived virtual
|
||||||
|
// tables.
|
||||||
template <typename T, unsigned I>
|
template <typename T, unsigned I>
|
||||||
class Deriver : T {
|
struct Deriver : T {
|
||||||
|
Deriver() {
|
||||||
|
break_optimization(new Deriver<T, I-1>);
|
||||||
|
}
|
||||||
virtual void f() {}
|
virtual void f() {}
|
||||||
virtual void g() {}
|
virtual void g() {}
|
||||||
virtual void f1() {}
|
virtual void h() {}
|
||||||
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() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Deriver<T, 0> : T {
|
||||||
|
virtual void f() {}
|
||||||
|
void g() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Deriver<T, 1> : T {
|
||||||
|
Deriver() {
|
||||||
|
break_optimization(new Deriver<T, 0>);
|
||||||
|
}
|
||||||
|
virtual void f() {}
|
||||||
|
virtual void g() {}
|
||||||
|
virtual void h() {}
|
||||||
|
virtual void i() {}
|
||||||
|
virtual void j() {}
|
||||||
|
virtual void k() {}
|
||||||
|
virtual void l() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Instantiate enough classes to force CFI checks for type T to use bit
|
||||||
|
// vectors of size 32 (if B32 defined), 64 (if B64 defined) or >64 (if BM
|
||||||
|
// defined).
|
||||||
|
template <typename T>
|
||||||
|
void create_derivers() {
|
||||||
|
#ifdef B32
|
||||||
|
break_optimization(new Deriver<T, 10>);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef B64
|
||||||
|
break_optimization(new Deriver<T, 25>);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BM
|
||||||
|
break_optimization(new Deriver<T, 40>);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,20 +37,7 @@ struct B {
|
||||||
B::~B() {}
|
B::~B() {}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#ifdef B32
|
create_derivers<B>();
|
||||||
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;
|
A *a = new A;
|
||||||
break_optimization(a);
|
break_optimization(a);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
# It is mostly copied from lit.cfg used by Clang.
|
# It is mostly copied from lit.cfg used by Clang.
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import lit.formats
|
import lit.formats
|
||||||
|
@ -138,3 +139,17 @@ elif config.host_os == 'Windows' and is_windows_lto_supported():
|
||||||
config.lto_flags = ["-fuse-ld=lld-link2"]
|
config.lto_flags = ["-fuse-ld=lld-link2"]
|
||||||
else:
|
else:
|
||||||
config.lto_supported = False
|
config.lto_supported = False
|
||||||
|
|
||||||
|
# Ask llvm-config about assertion mode.
|
||||||
|
try:
|
||||||
|
llvm_config_cmd = subprocess.Popen(
|
||||||
|
[os.path.join(config.llvm_tools_dir, 'llvm-config'), '--assertion-mode'],
|
||||||
|
stdout = subprocess.PIPE,
|
||||||
|
env=config.environment)
|
||||||
|
except OSError:
|
||||||
|
print("Could not find llvm-config in " + llvm_tools_dir)
|
||||||
|
exit(42)
|
||||||
|
|
||||||
|
if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
|
||||||
|
config.available_features.add('asserts')
|
||||||
|
llvm_config_cmd.wait()
|
||||||
|
|
Loading…
Reference in New Issue