From cb03a17b7eb179e9c922f44710df131ad55dca39 Mon Sep 17 00:00:00 2001 From: Werner Henze Date: Sat, 28 Dec 2024 17:19:42 +0100 Subject: [PATCH] More checks for non-compilable code - Remove some of the checks in `#ifdef CONFIRM_COMPILATION_ERRORS` and add compile time checks for these tests. - `algorithm_tests.cpp` and `span_test.cpp` have not been touched. --- tests/byte_tests.cpp | 6 +- tests/notnull_tests.cpp | 127 ++++++++++++++++++++++----------- tests/owner_tests.cpp | 25 ++++--- tests/strict_notnull_tests.cpp | 113 ++++++++++++++++++----------- 4 files changed, 177 insertions(+), 94 deletions(-) diff --git a/tests/byte_tests.cpp b/tests/byte_tests.cpp index ca94a9b..77a947a 100644 --- a/tests/byte_tests.cpp +++ b/tests/byte_tests.cpp @@ -67,6 +67,8 @@ TEST(byte_tests, construction) to_byte(char{}); to_byte(3); to_byte(3u); + to_byte<-1>(); + to_byte<256u>(); #endif } @@ -174,7 +176,3 @@ static constexpr bool static_assert(!ToIntegerCompilesFor, "!ToIntegerCompilesFor"); } // namespace - -#ifdef CONFIRM_COMPILATION_ERRORS -copy(src_span_static, dst_span_static); -#endif diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index b6f8b37..4b8381d 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -18,13 +18,14 @@ #include // for not_null, operator<, operator<=, operator> -#include // for addressof -#include // for uint16_t -#include // for shared_ptr, make_shared, operator<, opera... -#include // for operator<<, ostringstream, basic_ostream:... -#include // for basic_string, operator==, string, operator<< -#include // for type_info -#include // for variant, monostate, get +#include // for addressof +#include // for uint16_t +#include // for shared_ptr, make_shared, operator<, opera... +#include // for operator<<, ostringstream, basic_ostream:... +#include // for basic_string, operator==, string, operator<< +#include // for declval +#include // for type_info +#include // for variant, monostate, get #include "deathTestCommon.h" using namespace gsl; @@ -145,12 +146,6 @@ TEST(notnull_tests, TestNotNullConstructors) { { #ifdef CONFIRM_COMPILATION_ERRORS - not_null p = nullptr; // yay...does not compile! - not_null*> p1 = 0; // yay...does not compile! - not_null p2; // yay...does not compile! - std::unique_ptr up = std::make_unique(120); - not_null p3 = up; - // Forbid non-nullptr assignable types not_null> f(std::vector{1}); not_null z(10); @@ -288,15 +283,11 @@ TEST(notnull_tests, TestNotNullCasting) q = p; // allowed with heterogeneous copy ctor EXPECT_TRUE(q == p); -#ifdef CONFIRM_COMPILATION_ERRORS - q = u; // no viable conversion possible between MyBase* and Unrelated* - p = q; // not possible to implicitly convert MyBase* to MyDerived* - - not_null r = p; - not_null s = reinterpret_cast(p); -#endif not_null t(reinterpret_cast(p.get())); EXPECT_TRUE(reinterpret_cast(p.get()) == reinterpret_cast(t.get())); + + (void)static_cast(p); + (void)static_cast(p); } TEST(notnull_tests, TestNotNullAssignment) @@ -454,9 +445,6 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction) const int i = 42; not_null x{&i}; -#ifdef CONFIRM_COMPILATION_ERRORS - helper(not_null{&i}); -#endif helper_const(not_null{&i}); EXPECT_TRUE(*x == 42); @@ -478,9 +466,6 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction) const int* p = &i; not_null x{p}; -#ifdef CONFIRM_COMPILATION_ERRORS - helper(not_null{p}); -#endif helper_const(not_null{p}); EXPECT_TRUE(*x == 42); @@ -514,14 +499,6 @@ TEST(notnull_tests, TestNotNullConstructorTypeDeduction) EXPECT_DEATH(helper(not_null{p}), expected); EXPECT_DEATH(helper_const(not_null{p}), expected); } - -#ifdef CONFIRM_COMPILATION_ERRORS - { - not_null x{nullptr}; - helper(not_null{nullptr}); - helper_const(not_null{nullptr}); - } -#endif } TEST(notnull_tests, TestVariantEmplace) @@ -552,9 +529,6 @@ TEST(notnull_tests, TestMakeNotNull) const int i = 42; const auto x = make_not_null(&i); -#ifdef CONFIRM_COMPILATION_ERRORS - helper(make_not_null(&i)); -#endif helper_const(make_not_null(&i)); EXPECT_TRUE(*x == 42); @@ -576,9 +550,6 @@ TEST(notnull_tests, TestMakeNotNull) const int* p = &i; const auto x = make_not_null(p); -#ifdef CONFIRM_COMPILATION_ERRORS - helper(make_not_null(p)); -#endif helper_const(make_not_null(p)); EXPECT_TRUE(*x == 42); @@ -654,3 +625,79 @@ TEST(notnull_tests, TestStdHash) EXPECT_FALSE(hash_nn(nn) == hash_intptr(nullptr)); } } + +#if __cplusplus >= 201703l +using std::void_t; +#else // __cplusplus >= 201703l +template +using void_t = void; +#endif // __cplusplus < 201703l + +template +static constexpr bool CtorCompilesFor_A = false; +template +static constexpr bool + CtorCompilesFor_A{std::declval()})>> = true; +static_assert(CtorCompilesFor_A, "CtorCompilesFor_A"); +static_assert(!CtorCompilesFor_A, "!CtorCompilesFor_A"); + +template +static constexpr bool CtorCompilesFor_B = false; +template +static constexpr bool CtorCompilesFor_B{N})>> = true; +static_assert(!CtorCompilesFor_B, "!CtorCompilesFor_B"); + +template +static constexpr bool CtorCompilesFor_C = false; +template +static constexpr bool + CtorCompilesFor_C{std::declval>()})>> = + true; +static_assert(!CtorCompilesFor_C, "CtorCompilesFor_C"); + +template +static constexpr bool DefaultCtorCompilesFor = false; +template +static constexpr bool DefaultCtorCompilesFor{})>> = true; +static_assert(!DefaultCtorCompilesFor, "!DefaultCtorCompilesFor"); + +template +static constexpr bool AssignmentCompilesFor = false; +template +static constexpr bool + AssignmentCompilesFor&>().operator=( + std::declval&>()))>> = true; +static_assert(AssignmentCompilesFor, "AssignmentCompilesFor"); +static_assert(!AssignmentCompilesFor, + "!AssignmentCompilesFor"); +static_assert(!AssignmentCompilesFor, + "!AssignmentCompilesFor"); +static_assert(!AssignmentCompilesFor, + "!AssignmentCompilesFor"); + +template +static constexpr bool CastCompilesFor_A = false; +template +static constexpr bool CastCompilesFor_A< + U, V, void_t(std::declval&>()))>> = true; +static_assert(CastCompilesFor_A, "CastCompilesFor_A"); +static_assert(CastCompilesFor_A, "CastCompilesFor_A"); +static_assert(!CastCompilesFor_A, "!CastCompilesFor_A"); +static_assert(!CastCompilesFor_A, "!CastCompilesFor_A"); + +template +static constexpr bool CastCompilesFor_B = false; +template +static constexpr bool CastCompilesFor_B< + U, V, void_t(std::declval&>()))>> = true; +static_assert(!CastCompilesFor_B, "!CastCompilesFor_A"); +static_assert(!CastCompilesFor_B, "!CastCompilesFor_A"); + +template +static constexpr bool HelperCompilesFor = false; +template +static constexpr bool HelperCompilesFor()))>> = true; +static_assert(HelperCompilesFor>, "HelperCompilesFor>"); +static_assert(!HelperCompilesFor>, + "!HelperCompilesFor>"); diff --git a/tests/owner_tests.cpp b/tests/owner_tests.cpp index 87c7cec..3b7a38b 100644 --- a/tests/owner_tests.cpp +++ b/tests/owner_tests.cpp @@ -17,6 +17,7 @@ #include #include // for owner +#include // for declval using namespace gsl; @@ -32,12 +33,18 @@ TEST(owner_tests, basic_test) delete p; } -TEST(owner_tests, check_pointer_constraint) -{ -#ifdef CONFIRM_COMPILATION_ERRORS - { - owner integerTest = 10; - owner> sharedPtrTest(new int(10)); - } -#endif -} +#if __cplusplus >= 201703l +using std::void_t; +#else // __cplusplus >= 201703l +template +using void_t = void; +#endif // __cplusplus < 201703l + +template +static constexpr bool OwnerCompilesFor = false; +template +static constexpr bool OwnerCompilesFor{})>> = + true; +static_assert(OwnerCompilesFor, "OwnerCompilesFor"); +static_assert(!OwnerCompilesFor, "!OwnerCompilesFor"); +static_assert(!OwnerCompilesFor>, "!OwnerCompilesFor>"); diff --git a/tests/strict_notnull_tests.cpp b/tests/strict_notnull_tests.cpp index 82f9c5c..0fbc34c 100644 --- a/tests/strict_notnull_tests.cpp +++ b/tests/strict_notnull_tests.cpp @@ -17,6 +17,8 @@ #include // for not_null, operator<, operator<=, operator> #include +#include // for declval + #include "deathTestCommon.h" using namespace gsl; @@ -53,21 +55,12 @@ GSL_SUPPRESS(f.4) // NO-FORMAT: attribute bool strict_helper_const(strict_not_null p) { return *p == 12; } int* return_pointer() { return nullptr; } -#ifdef CONFIRM_COMPILATION_ERRORS -const int* return_pointer_const() { return nullptr; } -#endif } // namespace TEST(strict_notnull_tests, TestStrictNotNullConstructors) { { #ifdef CONFIRM_COMPILATION_ERRORS - strict_not_null p = nullptr; // yay...does not compile! - strict_not_null*> p1 = 0; // yay...does not compile! - strict_not_null p2; // yay...does not compile! - std::unique_ptr up = std::make_unique(120); - strict_not_null p3 = up; - // Forbid non-nullptr assignable types strict_not_null> f(std::vector{1}); strict_not_null z(10); @@ -170,10 +163,6 @@ TEST(strict_notnull_tests, TestStrictNotNull) #ifdef CONFIRM_COMPILATION_ERRORS strict_not_null snn = &x; - strict_helper(&x); - strict_helper_const(&x); - strict_helper(return_pointer()); - strict_helper_const(return_pointer_const()); #endif const strict_not_null snn1{&x}; @@ -190,17 +179,10 @@ TEST(strict_notnull_tests, TestStrictNotNull) #ifdef CONFIRM_COMPILATION_ERRORS strict_not_null snn = &x; - strict_helper(&x); - strict_helper_const(&x); - strict_helper(return_pointer()); - strict_helper_const(return_pointer_const()); #endif const strict_not_null snn1{&x}; -#ifdef CONFIRM_COMPILATION_ERRORS - helper(snn1); -#endif helper_const(snn1); EXPECT_TRUE(*snn1 == 42); @@ -227,9 +209,6 @@ TEST(strict_notnull_tests, TestStrictNotNull) strict_not_null snn1{&x}; const strict_not_null snn2{&x}; -#ifdef CONFIRM_COMPILATION_ERRORS - strict_helper(snn1); -#endif strict_helper_const(snn1); strict_helper_const(snn2); @@ -261,9 +240,6 @@ TEST(strict_notnull_tests, TestStrictNotNull) const not_null nn1 = snn; const not_null nn2{snn}; -#ifdef CONFIRM_COMPILATION_ERRORS - helper(snn); -#endif helper_const(snn); EXPECT_TRUE(snn == nn1); @@ -303,9 +279,6 @@ TEST(strict_notnull_tests, TestStrictNotNull) const strict_not_null snn1{nn}; const strict_not_null snn2{nn}; -#ifdef CONFIRM_COMPILATION_ERRORS - strict_helper(nn); -#endif strict_helper_const(nn); EXPECT_TRUE(snn1 == nn); @@ -319,12 +292,6 @@ TEST(strict_notnull_tests, TestStrictNotNull) EXPECT_TRUE(hash_nn(snn1) == hash_nn(snn2)); EXPECT_TRUE(hash_snn(snn1) == hash_snn(nn)); } - -#ifdef CONFIRM_COMPILATION_ERRORS - { - strict_not_null p{nullptr}; - } -#endif } #if defined(__cplusplus) && (__cplusplus >= 201703L) @@ -351,9 +318,6 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction) const int i = 42; strict_not_null x{&i}; -#ifdef CONFIRM_COMPILATION_ERRORS - helper(strict_not_null{&i}); -#endif helper_const(strict_not_null{&i}); EXPECT_TRUE(*x == 42); @@ -375,9 +339,6 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction) const int* p = &i; strict_not_null x{p}; -#ifdef CONFIRM_COMPILATION_ERRORS - helper(strict_not_null{p}); -#endif helper_const(strict_not_null{p}); EXPECT_TRUE(*x == 42); @@ -415,3 +376,73 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction) #endif } #endif // #if defined(__cplusplus) && (__cplusplus >= 201703L) + +#if __cplusplus >= 201703l +using std::void_t; +#else // __cplusplus >= 201703l +template +using void_t = void; +#endif // __cplusplus < 201703l + +template +static constexpr bool CtorCompilesFor_A = false; +template +static constexpr bool + CtorCompilesFor_A{std::declval()})>> = true; +static_assert(CtorCompilesFor_A, "CtorCompilesFor_A"); +static_assert(!CtorCompilesFor_A, "!CtorCompilesFor_A"); + +template +static constexpr bool CtorCompilesFor_B = false; +template +static constexpr bool CtorCompilesFor_B{N})>> = true; +static_assert(!CtorCompilesFor_B, "!CtorCompilesFor_B"); + +template +static constexpr bool CtorCompilesFor_C = false; +template +static constexpr bool CtorCompilesFor_C< + U, void_t{std::declval>()})>> = + true; +static_assert(!CtorCompilesFor_C, "CtorCompilesFor_C"); + +template +static constexpr bool DefaultCtorCompilesFor = false; +template +static constexpr bool DefaultCtorCompilesFor{})>> = true; +static_assert(!DefaultCtorCompilesFor, "!DefaultCtorCompilesFor"); + +template +static constexpr bool StrictHelperCompilesFor = false; +template +static constexpr bool + StrictHelperCompilesFor()))>> = true; +static_assert(StrictHelperCompilesFor>, + "StrictHelperCompilesFor>"); +static_assert(!StrictHelperCompilesFor>, + "!StrictHelperCompilesFor>"); +static_assert(!StrictHelperCompilesFor>, + "!StrictHelperCompilesFor>"); +static_assert(!StrictHelperCompilesFor, "!StrictHelperCompilesFor"); + +template +static constexpr bool HelperCompilesFor = false; +template +static constexpr bool + HelperCompilesFor()))>> = true; +static_assert(HelperCompilesFor>, + "HelperCompilesFor>"); +static_assert(!HelperCompilesFor>, + "!HelperCompilesFor>"); +static_assert(!HelperCompilesFor>, + "!HelperCompilesFor>"); +static_assert(HelperCompilesFor, "HelperCompilesFor"); + +template +static constexpr bool StrictHelperConstCompilesFor = false; +template +static constexpr bool + StrictHelperConstCompilesFor()))>> = true; +static_assert(StrictHelperConstCompilesFor>, + "StrictHelperCompilesFor>"); +static_assert(!StrictHelperConstCompilesFor, "!StrictHelperCompilesFor");