https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/68753
>From 9824ef111975386152173916c1fd6a85264be0a0 Mon Sep 17 00:00:00 2001 From: Louis Dionne <ldionn...@gmail.com> Date: Tue, 10 Oct 2023 16:35:11 -0700 Subject: [PATCH 1/3] [libc++] Allow running the test suite with optimizations This patch adds a configuration of the libc++ test suite that enables optimizations when building the tests. It also adds a new CI configuration to exercise this on a regular basis. This is added in the context of [1], which requires building with optimizations in order to hit the bug. [1]: https://github.com/llvm/llvm-project/issues/68552 --- libcxx/cmake/caches/Generic-optimized.cmake | 4 +++ libcxx/utils/ci/buildkite-pipeline.yml | 18 +++++++++++++ libcxx/utils/ci/run-buildbot | 5 ++++ libcxx/utils/libcxx/test/params.py | 28 ++++++++++++++++++++- 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 libcxx/cmake/caches/Generic-optimized.cmake diff --git a/libcxx/cmake/caches/Generic-optimized.cmake b/libcxx/cmake/caches/Generic-optimized.cmake new file mode 100644 index 000000000000000..577a5de9f34c539 --- /dev/null +++ b/libcxx/cmake/caches/Generic-optimized.cmake @@ -0,0 +1,4 @@ +set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") +set(LIBCXX_TEST_PARAMS "optimization=speed" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") +set(LIBUNWIND_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml index ebfb35eee91e1ed..1b52d994081c46f 100644 --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -743,6 +743,24 @@ steps: limit: 2 timeout_in_minutes: 120 + - label: "Optimized build and test suite" + command: "libcxx/utils/ci/run-buildbot generic-optimized" + artifact_paths: + - "**/test-results.xml" + - "**/*.abilist" + env: + CC: "clang-${LLVM_HEAD_VERSION}" + CXX: "clang++-${LLVM_HEAD_VERSION}" + ENABLE_CLANG_TIDY: "On" + agents: + queue: "libcxx-builders" + os: "linux" + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + timeout_in_minutes: 120 + # Other non-testing CI jobs - label: "Benchmarks" command: "libcxx/utils/ci/run-buildbot benchmarks" diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot index a71318123db3b12..18243b44a3d745c 100755 --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -479,6 +479,11 @@ generic-abi-unstable) generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-abi-unstable.cmake" check-runtimes ;; +generic-optimized) + clean + generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-optimized.cmake" + check-runtimes +;; apple-system) clean diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index 456794b9b1cce95..9452f179aea3fec 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -11,7 +11,7 @@ from pathlib import Path from libcxx.test.dsl import * -from libcxx.test.features import _isMSVC +from libcxx.test.features import _isClang, _isAppleClang, _isGCC, _isMSVC _warningFlags = [ @@ -90,6 +90,21 @@ def getStdFlag(cfg, std): return "-std=" + fallbacks[std] return None +def getSpeedOptimizationFlag(cfg): + if _isClang(cfg) or _isAppleClang(cfg) or _isGCC(cfg): + return "-O3" + elif _isMSVC(cfg): + return "/O2" + else: + raise RuntimeError("Can't figure out what compiler is used in the configuration") + +def getSizeOptimizationFlag(cfg): + if _isClang(cfg) or _isAppleClang(cfg) or _isGCC(cfg): + return "-Os" + elif _isMSVC(cfg): + return "/O1" + else: + raise RuntimeError("Can't figure out what compiler is used in the configuration") # fmt: off DEFAULT_PARAMETERS = [ @@ -121,6 +136,17 @@ def getStdFlag(cfg, std): AddCompileFlag(lambda cfg: getStdFlag(cfg, std)), ], ), + Parameter( + name="optimization", + choices=["none", "speed", "size"], + type=str, + help="The version of the standard to compile the test suite with.", + default="none", + actions=lambda opt: filter(None, [ + AddCompileFlag(lambda cfg: getSpeedOptimizationFlag(cfg)) if opt == "speed" else None, + AddCompileFlag(lambda cfg: getSizeOptimizationFlag(cfg)) if opt == "size" else None, + ]), + ), Parameter( name="enable_modules", choices=["none", "clang", "clang-lsv"], >From f799be39afed6b82d1942a87cea66a4d1192d765 Mon Sep 17 00:00:00 2001 From: Louis Dionne <ldionn...@gmail.com> Date: Wed, 1 Nov 2023 10:56:30 -0400 Subject: [PATCH 2/3] Fix incorrect help --- libcxx/utils/libcxx/test/params.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index 9452f179aea3fec..9b284265f95c695 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -140,7 +140,7 @@ def getSizeOptimizationFlag(cfg): name="optimization", choices=["none", "speed", "size"], type=str, - help="The version of the standard to compile the test suite with.", + help="The optimization level to use when compiling the test suite.", default="none", actions=lambda opt: filter(None, [ AddCompileFlag(lambda cfg: getSpeedOptimizationFlag(cfg)) if opt == "speed" else None, >From fe134eb76136bbbeea4ece2b67e499a3d4cba45f Mon Sep 17 00:00:00 2001 From: Louis Dionne <ldionn...@gmail.com> Date: Wed, 1 Nov 2023 11:21:19 -0400 Subject: [PATCH 3/3] Fix failing tests due to new/delete ellision --- .../support.dynamic/libcpp_deallocate.sh.cpp | 17 +++++------ .../new.size.replace.indirect.pass.cpp | 3 +- .../new.size.replace.pass.cpp | 3 +- .../new.size_align.replace.indirect.pass.cpp | 7 +++-- ...ze_align_nothrow.replace.indirect.pass.cpp | 7 +++-- .../new.size_align_nothrow.replace.pass.cpp | 7 +++-- ...new.size_nothrow.replace.indirect.pass.cpp | 3 +- .../new.size_nothrow.replace.pass.cpp | 3 +- .../new.size.replace.pass.cpp | 3 +- ...ze_align_nothrow.replace.indirect.pass.cpp | 7 +++-- ...new.size_nothrow.replace.indirect.pass.cpp | 3 +- .../func.wrap.func.con/F.pass.cpp | 2 +- libcxx/test/support/count_new.h | 5 ++++ libcxx/test/support/escape.h | 28 +++++++++++++++++++ 14 files changed, 71 insertions(+), 27 deletions(-) create mode 100644 libcxx/test/support/escape.h diff --git a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp index 3b33737466c7419..a2c53861caba036 100644 --- a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp +++ b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp @@ -39,6 +39,7 @@ #include <string> #include <cassert> +#include "escape.h" #include "test_macros.h" TEST_DIAGNOSTIC_PUSH @@ -192,13 +193,13 @@ void test_allocator_and_new_match() { stats.reset(); #if defined(NO_SIZE) && defined(NO_ALIGN) { - int* x = new int(42); + int* x = support::escape(new int(42)); delete x; assert(stats.expect_plain()); } stats.reset(); { - AlignedType* a = new AlignedType(); + AlignedType* a = support::escape(new AlignedType()); delete a; assert(stats.expect_plain()); } @@ -207,14 +208,14 @@ void test_allocator_and_new_match() { stats.reset(); #if TEST_STD_VER >= 11 { - int* x = new int(42); + int* x = support::escape(new int(42)); delete x; assert(stats.expect_plain()); } #endif stats.reset(); { - AlignedType* a = new AlignedType(); + AlignedType* a = support::escape(new AlignedType()); delete a; assert(stats.expect_align(TEST_ALIGNOF(AlignedType))); } @@ -222,13 +223,13 @@ void test_allocator_and_new_match() { #elif defined(NO_ALIGN) stats.reset(); { - int* x = new int(42); + int* x = support::escape(new int(42)); delete x; assert(stats.expect_size(sizeof(int))); } stats.reset(); { - AlignedType* a = new AlignedType(); + AlignedType* a = support::escape(new AlignedType()); delete a; assert(stats.expect_size(sizeof(AlignedType))); } @@ -236,13 +237,13 @@ void test_allocator_and_new_match() { #else stats.reset(); { - int* x = new int(42); + int* x = support::escape(new int(42)); delete x; assert(stats.expect_size(sizeof(int))); } stats.reset(); { - AlignedType* a = new AlignedType(); + AlignedType* a = support::escape(new AlignedType()); delete a; assert(stats.expect_size_align(sizeof(AlignedType), TEST_ALIGNOF(AlignedType))); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.indirect.pass.cpp index 172b6cc2f2944ad..56264c25575847e 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.indirect.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.indirect.pass.cpp @@ -20,6 +20,7 @@ #include <cassert> #include <limits> +#include "escape.h" #include "test_macros.h" int new_called = 0; @@ -40,7 +41,7 @@ void operator delete(void* p) TEST_NOEXCEPT { int main(int, char**) { new_called = delete_called = 0; - int* x = new int[3]; + int* x = support::escape(new int[3]); assert(x != nullptr); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.pass.cpp index e352c00b4d0af94..1612ecba96ac9b8 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.pass.cpp @@ -19,6 +19,7 @@ #include <cassert> #include <limits> +#include "escape.h" #include "test_macros.h" int new_called = 0; @@ -38,7 +39,7 @@ void operator delete[](void* p) TEST_NOEXCEPT { int main(int, char**) { new_called = delete_called = 0; - int* x = new int[3]; + int* x = support::escape(new int[3]); assert(x != nullptr); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp index 64d987ed691b297..370aba01a2c819d 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp @@ -29,6 +29,7 @@ #include <cassert> #include <limits> +#include "escape.h" #include "test_macros.h" #include "../types.h" @@ -54,7 +55,7 @@ int main(int, char**) { // Test with an overaligned type { new_called = delete_called = 0; - OverAligned* x = new OverAligned[3]; + OverAligned* x = support::escape(new OverAligned[3]); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(static_cast<void*>(x) == DummyData); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1); @@ -65,7 +66,7 @@ int main(int, char**) { // Test with a type that is right on the verge of being overaligned { new_called = delete_called = 0; - MaxAligned* x = new MaxAligned[3]; + MaxAligned* x = support::escape(new MaxAligned[3]); assert(x != nullptr); assert(new_called == 0); @@ -76,7 +77,7 @@ int main(int, char**) { // Test with a type that is clearly not overaligned { new_called = delete_called = 0; - int* x = new int[3]; + int* x = support::escape(new int[3]); assert(x != nullptr); assert(new_called == 0); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp index a62128942eaf638..12b77c4d33c9417 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp @@ -29,6 +29,7 @@ #include <cassert> #include <limits> +#include "escape.h" #include "test_macros.h" #include "../types.h" @@ -54,7 +55,7 @@ int main(int, char**) { // Test with an overaligned type { new_called = delete_called = 0; - OverAligned* x = new (std::nothrow) OverAligned[3]; + OverAligned* x = support::escape(new (std::nothrow) OverAligned[3]); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(static_cast<void*>(x) == DummyData); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1); @@ -65,7 +66,7 @@ int main(int, char**) { // Test with a type that is right on the verge of being overaligned { new_called = delete_called = 0; - MaxAligned* x = new (std::nothrow) MaxAligned[3]; + MaxAligned* x = support::escape(new (std::nothrow) MaxAligned[3]); assert(x != nullptr); assert(new_called == 0); @@ -76,7 +77,7 @@ int main(int, char**) { // Test with a type that is clearly not overaligned { new_called = delete_called = 0; - int* x = new (std::nothrow) int[3]; + int* x = support::escape(new (std::nothrow) int[3]); assert(x != nullptr); assert(new_called == 0); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.pass.cpp index 9a830e0e82990aa..6e4b95a2eea213a 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.pass.cpp @@ -26,6 +26,7 @@ #include <cassert> #include <limits> +#include "escape.h" #include "test_macros.h" #include "../types.h" @@ -51,7 +52,7 @@ int main(int, char**) { // Test with an overaligned type { new_nothrow_called = delete_called = 0; - OverAligned* x = new (std::nothrow) OverAligned[3]; + OverAligned* x = support::escape(new (std::nothrow) OverAligned[3]); assert(static_cast<void*>(x) == DummyData); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_nothrow_called == 1); @@ -62,7 +63,7 @@ int main(int, char**) { // Test with a type that is right on the verge of being overaligned { new_nothrow_called = delete_called = 0; - MaxAligned* x = new (std::nothrow) MaxAligned[3]; + MaxAligned* x = support::escape(new (std::nothrow) MaxAligned[3]); assert(x != nullptr); assert(new_nothrow_called == 0); @@ -73,7 +74,7 @@ int main(int, char**) { // Test with a type that is clearly not overaligned { new_nothrow_called = delete_called = 0; - int* x = new (std::nothrow) int[3]; + int* x = support::escape(new (std::nothrow) int[3]); assert(x != nullptr); assert(new_nothrow_called == 0); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp index 8ad0292dcb5ca4b..2b481c21d5de01d 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp @@ -24,6 +24,7 @@ #include <cstdlib> #include <cassert> +#include "escape.h" #include "test_macros.h" int new_called = 0; @@ -44,7 +45,7 @@ void operator delete(void* p) TEST_NOEXCEPT { int main(int, char**) { new_called = delete_called = 0; - int* x = new (std::nothrow) int[3]; + int* x = support::escape(new (std::nothrow) int[3]); assert(x != nullptr); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.pass.cpp index b85e15ce64b48ac..f06940ba3701855 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.pass.cpp @@ -18,6 +18,7 @@ #include <cstdlib> #include <cassert> +#include "escape.h" #include "test_macros.h" int new_nothrow_called = 0; @@ -35,7 +36,7 @@ void operator delete[](void* p) TEST_NOEXCEPT { int main(int, char**) { new_nothrow_called = delete_called = 0; - int* x = new (std::nothrow) int[3]; + int* x = support::escape(new (std::nothrow) int[3]); assert(x != nullptr); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_nothrow_called == 1); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp index a03313e5872ef3b..f992ad325c0068a 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp @@ -17,6 +17,7 @@ #include <cstdlib> #include <cassert> +#include "escape.h" #include "test_macros.h" int new_called = 0; @@ -36,7 +37,7 @@ void operator delete(void* p) TEST_NOEXCEPT { int main(int, char**) { new_called = delete_called = 0; - int* x = new int(3); + int* x = support::escape(new int(3)); assert(x != nullptr); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp index 3cbb5aaf8f0be6d..6575dce91606f6c 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp @@ -28,6 +28,7 @@ #include <cassert> #include <limits> +#include "escape.h" #include "test_macros.h" #include "../types.h" @@ -53,7 +54,7 @@ int main(int, char**) { // Test with an overaligned type { new_called = delete_called = 0; - OverAligned* x = new (std::nothrow) OverAligned; + OverAligned* x = support::escape(new (std::nothrow) OverAligned); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(static_cast<void*>(x) == DummyData); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1); @@ -64,7 +65,7 @@ int main(int, char**) { // Test with a type that is right on the verge of being overaligned { new_called = delete_called = 0; - MaxAligned* x = new (std::nothrow) MaxAligned; + MaxAligned* x = support::escape(new (std::nothrow) MaxAligned); assert(x != nullptr); assert(new_called == 0); @@ -75,7 +76,7 @@ int main(int, char**) { // Test with a type that is clearly not overaligned { new_called = delete_called = 0; - int* x = new (std::nothrow) int; + int* x = support::escape(new (std::nothrow) int); assert(x != nullptr); assert(new_called == 0); diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.indirect.pass.cpp index 2ae0dfa4f1abc41..e38376a2ce96e06 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.indirect.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.indirect.pass.cpp @@ -19,6 +19,7 @@ #include <cstdlib> #include <cassert> +#include "escape.h" #include "test_macros.h" int new_called = 0; @@ -39,7 +40,7 @@ void operator delete(void* p) TEST_NOEXCEPT { int main(int, char**) { new_called = delete_called = 0; - int* x = new (std::nothrow) int(3); + int* x = support::escape(new (std::nothrow) int(3)); assert(x != nullptr); ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1); diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp index c1ad528254af1a4..2c8e22941c999f8 100644 --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp @@ -69,7 +69,7 @@ int main(int, char**) { std::function<int(int)> f = A(); assert(A::count == 1); - assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(2)); RTTI_ASSERT(f.target<A>()); RTTI_ASSERT(f.target<int(*)(int)>() == 0); } diff --git a/libcxx/test/support/count_new.h b/libcxx/test/support/count_new.h index b6424850101625b..ef4306e520b195b 100644 --- a/libcxx/test/support/count_new.h +++ b/libcxx/test/support/count_new.h @@ -181,6 +181,11 @@ class MemCounter return disable_checking || n == outstanding_new; } + bool checkOutstandingNewLessThanOrEqual(int n) const + { + return disable_checking || outstanding_new <= n; + } + bool checkOutstandingNewNotEq(int n) const { return disable_checking || n != outstanding_new; diff --git a/libcxx/test/support/escape.h b/libcxx/test/support/escape.h new file mode 100644 index 000000000000000..a5556418a8b2e88 --- /dev/null +++ b/libcxx/test/support/escape.h @@ -0,0 +1,28 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef SUPPORT_ESCAPE_H +#define SUPPORT_ESCAPE_H + +#include "test_macros.h" + +namespace support { +// This function can be used to hide some objects from compiler optimizations. +// +// For example, this is useful to hide the result of a call to `new` and ensure +// ensure that the compiler doesn't elide the call to new/delete. Otherwise, +// elliding calls to new/delete is allowed by the Standard and compilers actually +// do it when optimizations are enabled. +template <class T> +TEST_CONSTEXPR __attribute__((noinline)) T* escape(T* ptr) TEST_NOEXCEPT { + return ptr; +} +} // namespace support + +#endif // SUPPORT_ESCAPE_H _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits