Author: ericwf Date: Thu Mar 22 14:28:09 2018 New Revision: 328245 URL: http://llvm.org/viewvc/llvm-project?rev=328245&view=rev Log: 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. Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp libcxx/trunk/test/support/test_macros.h Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp Thu Mar 22 14:28:09 2018 @@ -69,31 +69,32 @@ void operator delete [] (void* p, std::a 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); Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp Thu Mar 22 14:28:09 2018 @@ -53,7 +53,9 @@ void* operator new[](std::size_t s, std: 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::al assert(new_called == 1); --new_called; assert(p == DummyData); + DoNotOptimize(p); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp Thu Mar 22 14:28:09 2018 @@ -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); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp Thu Mar 22 14:28:09 2018 @@ -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); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp Thu Mar 22 14:28:09 2018 @@ -36,7 +36,7 @@ void operator delete(void* p) TEST_NOEX 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); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp Thu Mar 22 14:28:09 2018 @@ -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); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp Thu Mar 22 14:28:09 2018 @@ -46,15 +46,15 @@ void operator delete[](void* p, const st // 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); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp Thu Mar 22 14:28:09 2018 @@ -68,31 +68,32 @@ void operator delete(void* p, std::align 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); Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp Thu Mar 22 14:28:09 2018 @@ -53,7 +53,9 @@ void* operator new(std::size_t s, std::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::alig assert(new_called == 1); --new_called; assert(p == DummyData); + DoNotOptimize(DummyData); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp Thu Mar 22 14:28:09 2018 @@ -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); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp Thu Mar 22 14:28:09 2018 @@ -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); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp Thu Mar 22 14:28:09 2018 @@ -44,16 +44,16 @@ void operator delete(void* p, std::size_ 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); Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp Thu Mar 22 14:28:09 2018 @@ -49,16 +49,16 @@ void operator delete(void* p, std::size_ 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); Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp Thu Mar 22 14:28:09 2018 @@ -35,15 +35,15 @@ void operator delete(void* p, const std: 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); } Modified: libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp (original) +++ libcxx/trunk/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp Thu Mar 22 14:28:09 2018 @@ -62,16 +62,16 @@ void operator delete(void* p, std::size_ 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); Modified: libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp Thu Mar 22 14:28:09 2018 @@ -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)); Modified: libcxx/trunk/test/support/test_macros.h URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/test_macros.h?rev=328245&r1=328244&r2=328245&view=diff ============================================================================== --- libcxx/trunk/test/support/test_macros.h (original) +++ libcxx/trunk/test/support/test_macros.h Thu Mar 22 14:28:09 2018 @@ -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> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits