diff options
author | Eric Fiselier <eric@efcs.ca> | 2018-03-22 21:28:09 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2018-03-22 21:28:09 +0000 |
commit | 107d6d684539a034c6ab3a1ae915179c5bbde8ba (patch) | |
tree | 1f7689bd71145d5448f9917ba8ca589ec742efde /libcxx | |
parent | 29a21bab087dbb2c8c7e815f4816c4d5356361f9 (diff) | |
download | bcm5719-llvm-107d6d684539a034c6ab3a1ae915179c5bbde8ba.tar.gz bcm5719-llvm-107d6d684539a034c6ab3a1ae915179c5bbde8ba.zip |
Use DoNotOptimize to prevent new/delete elision.
The new/delete tests, in particular those which test replacement
functions, often fail when the optimizer is enabled because the
calls to new/delete may be optimized away, regardless of their side-effects.
This patch converts the tests to use DoNotOptimize in order to prevent
the elision.
llvm-svn: 328245
Diffstat (limited to 'libcxx')
17 files changed, 74 insertions, 47 deletions
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp index 828feabd212..2175e29a040 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp @@ -69,31 +69,32 @@ void operator delete [] (void* p, std::align_val_t) TEST_NOEXCEPT struct alignas(OverAligned) A {}; struct alignas(std::max_align_t) B {}; -B* volatile b; // Escape the memory -A* volatile a; - int main() { reset(); { - b = new B[2]; + B *b = new B[2]; + DoNotOptimize(b); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(0 == aligned_delete_called); delete [] b; + DoNotOptimize(b); assert(1 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(0 == aligned_delete_called); } reset(); { - a = new A[2]; + A *a = new A[2]; + DoNotOptimize(a); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(0 == aligned_delete_called); delete [] a; + DoNotOptimize(a); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(1 == aligned_delete_called); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp index 82dc77efe89..d8e08a3a0bd 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp @@ -53,7 +53,9 @@ void* operator new[](std::size_t s, std::align_val_t a) TEST_THROW_SPEC(std::bad assert(s <= sizeof(DummyData)); assert(static_cast<std::size_t>(a) == OverAligned); ++new_called; - return DummyData; + void *Ret = DummyData; + DoNotOptimize(Ret); + return Ret; } void operator delete[](void* p, std::align_val_t) TEST_NOEXCEPT @@ -61,6 +63,7 @@ void operator delete[](void* p, std::align_val_t) TEST_NOEXCEPT assert(new_called == 1); --new_called; assert(p == DummyData); + DoNotOptimize(p); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp index 5aecc2da084..58ff728e633 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp @@ -41,8 +41,8 @@ int main() std::set_new_handler(my_new_handler); try { - void* volatile vp = operator new[] (std::numeric_limits<std::size_t>::max()); - ((void)vp); + void* vp = operator new[] (std::numeric_limits<std::size_t>::max()); + DoNotOptimize(vp); assert(false); } catch (std::bad_alloc&) @@ -55,8 +55,10 @@ int main() } #endif A* ap = new A[3]; + DoNotOptimize(ap); assert(ap); assert(A_constructed == 3); delete [] ap; + DoNotOptimize(ap); assert(A_constructed == 0); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp index c1606b27da7..f29f0c09e4f 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp @@ -42,7 +42,8 @@ int main() try #endif { - void*volatile vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow); + void* vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow); + DoNotOptimize(vp); assert(new_handler_called == 1); assert(vp == 0); } @@ -53,8 +54,10 @@ int main() } #endif A* ap = new(std::nothrow) A[3]; + DoNotOptimize(ap); assert(ap); assert(A_constructed == 3); delete [] ap; + DoNotOptimize(ap); assert(A_constructed == 0); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp index ba3f930c5f1..3d8467faa3e 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp @@ -36,7 +36,7 @@ void operator delete(void* p) TEST_NOEXCEPT std::free(p); } -volatile int A_constructed = 0; +int A_constructed = 0; struct A { @@ -44,15 +44,15 @@ struct A ~A() {--A_constructed;} }; -A* volatile ap; - int main() { - ap = new (std::nothrow) A[3]; + A *ap = new (std::nothrow) A[3]; + DoNotOptimize(ap); assert(ap); assert(A_constructed == 3); assert(new_called); delete [] ap; + DoNotOptimize(ap); assert(A_constructed == 0); assert(!new_called); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp index 3f8122745cc..ad4d9f469d4 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp @@ -21,7 +21,7 @@ #include "test_macros.h" -volatile int new_called = 0; +int new_called = 0; void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc) { @@ -45,15 +45,15 @@ struct A ~A() {--A_constructed;} }; -A* volatile ap; - int main() { - ap = new A[3]; + A *ap = new A[3]; + DoNotOptimize(ap); assert(ap); assert(A_constructed == 3); assert(new_called == 1); delete [] ap; + DoNotOptimize(ap); assert(A_constructed == 0); assert(new_called == 0); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp index 3925f2f5c31..a988b803d2d 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp @@ -46,15 +46,15 @@ void operator delete[](void* p, const std::nothrow_t&) TEST_NOEXCEPT // selected. struct A { ~A() {} }; -A *volatile x; - int main() { - x = new A[3]; + A *x = new A[3]; + DoNotOptimize(x); assert(0 == delete_called); assert(0 == delete_nothrow_called); delete [] x; + DoNotOptimize(x); assert(1 == delete_called); assert(0 == delete_nothrow_called); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp index d64a633007e..6f1c7511243 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp @@ -68,31 +68,32 @@ void operator delete(void* p, std::align_val_t) TEST_NOEXCEPT struct alignas(OverAligned) A {}; struct alignas(std::max_align_t) B {}; -B* volatile bp; -A* volatile ap; - int main() { reset(); { - bp = new B; + B *bp = new B; + DoNotOptimize(bp); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(0 == aligned_delete_called); delete bp; + DoNotOptimize(bp); assert(1 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(0 == aligned_delete_called); } reset(); { - ap = new A; + A *ap = new A; + DoNotOptimize(ap); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(0 == aligned_delete_called); delete ap; + DoNotOptimize(ap); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(1 == aligned_delete_called); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp index bace5c036e0..2dd4631e7f6 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp @@ -53,7 +53,9 @@ void* operator new(std::size_t s, std::align_val_t a) TEST_THROW_SPEC(std::bad_a assert(s <= sizeof(DummyData)); assert(static_cast<std::size_t>(a) == OverAligned); ++new_called; - return DummyData; + void *Ret = DummyData; + DoNotOptimize(Ret); + return Ret; } void operator delete(void* p, std::align_val_t) TEST_NOEXCEPT @@ -61,6 +63,7 @@ void operator delete(void* p, std::align_val_t) TEST_NOEXCEPT assert(new_called == 1); --new_called; assert(p == DummyData); + DoNotOptimize(DummyData); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp index 31e1901511f..a0e3eda5765 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp @@ -44,15 +44,15 @@ struct A ~A() {A_constructed = false;} }; -A* volatile ap; - int main() { - ap = new (std::nothrow) A; + A *ap = new (std::nothrow) A; + DoNotOptimize(ap); assert(ap); assert(A_constructed); assert(new_called); delete ap; + DoNotOptimize(ap); assert(!A_constructed); assert(!new_called); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp index ea6c9367b90..aa00fee56e1 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp @@ -43,15 +43,15 @@ struct A ~A() {A_constructed = false;} }; -A *volatile ap; - int main() { - ap = new A; + A *ap = new A; + DoNotOptimize(ap); assert(ap); assert(A_constructed); assert(new_called); delete ap; + DoNotOptimize(ap); assert(!A_constructed); assert(!new_called); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp index 3d947de426d..d9e0f5ca364 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp @@ -44,16 +44,16 @@ void operator delete(void* p, std::size_t) TEST_NOEXCEPT std::free(p); } -int *volatile x; - int main() { - x = new int(42); + int *x = new int(42); + DoNotOptimize(x); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(0 == sized_delete_called); delete x; + DoNotOptimize(x); assert(1 == unsized_delete_called); assert(0 == sized_delete_called); assert(0 == unsized_delete_nothrow_called); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp index 7a76725a975..5b08eb4b856 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp @@ -49,16 +49,16 @@ void operator delete(void* p, std::size_t) TEST_NOEXCEPT std::free(p); } -int *volatile x; - int main() { - x = new int(42); + int *x = new int(42); + DoNotOptimize(x); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); assert(0 == sized_delete_called); delete x; + DoNotOptimize(x); assert(0 == unsized_delete_called); assert(1 == sized_delete_called); assert(0 == unsized_delete_nothrow_called); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp index cb093f3637c..178e26db174 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp @@ -35,15 +35,15 @@ void operator delete(void* p, const std::nothrow_t&) TEST_NOEXCEPT std::free(p); } -int* volatile x; - int main() { - x = new int(42); + int *x = new int(42); + DoNotOptimize(x); assert(0 == delete_called); assert(0 == delete_nothrow_called); delete x; + DoNotOptimize(x); assert(1 == delete_called); assert(0 == delete_nothrow_called); } diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp index 40de3a09800..d5b610f7180 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp @@ -62,16 +62,16 @@ void operator delete(void* p, std::size_t) TEST_NOEXCEPT std::free(p); } -int* volatile x; - int main() { - x = new int(42); + int *x = new int(42); + DoNotOptimize(x); assert(0 == sized_delete_called); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); delete x; + DoNotOptimize(x); assert(1 == sized_delete_called); assert(0 == unsized_delete_called); assert(0 == unsized_delete_nothrow_called); diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp index 930da0b79b8..70c5e46965a 100644 --- a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp @@ -14,6 +14,7 @@ #include <memory> #include <cassert> +#include <iostream> #include "test_macros.h" #include "count_new.hpp" @@ -59,7 +60,8 @@ void test_aligned() { assert(T::constructed == 0); globalMemCounter.last_new_size = 0; globalMemCounter.last_new_align = 0; - T* volatile ap = a.allocate(3); + T* ap = a.allocate(3); + DoNotOptimize(ap); assert(globalMemCounter.checkOutstandingNewEq(1)); assert(globalMemCounter.checkNewCalledEq(1)); assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned)); @@ -79,6 +81,7 @@ void test_aligned() { globalMemCounter.last_new_size = 0; globalMemCounter.last_new_align = 0; T* volatile ap2 = a.allocate(11, (const void*)5); + DoNotOptimize(ap2); assert(globalMemCounter.checkOutstandingNewEq(1)); assert(globalMemCounter.checkNewCalledEq(1)); assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned)); @@ -87,6 +90,7 @@ void test_aligned() { assert(T::constructed == 0); globalMemCounter.last_delete_align = 0; a.deallocate(ap2, 11); + DoNotOptimize(ap2); assert(globalMemCounter.checkOutstandingNewEq(0)); assert(globalMemCounter.checkDeleteCalledEq(1)); assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned)); diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h index 42eed4ce498..848f1407635 100644 --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -221,8 +221,18 @@ struct is_same<T, T> { enum {value = 1}; }; #if defined(__GNUC__) || defined(__clang__) template <class Tp> -inline void DoNotOptimize(Tp const& value) { - asm volatile("" : : "g"(value) : "memory"); +inline +void DoNotOptimize(Tp const& value) { + asm volatile("" : : "r,m"(value) : "memory"); +} + +template <class Tp> +inline void DoNotOptimize(Tp& value) { +#if defined(__clang__) + asm volatile("" : "+r,m"(value) : : "memory"); +#else + asm volatile("" : "+m,r"(value) : : "memory"); +#endif } #else #include <intrin.h> |