mirror of
https://github.com/microsoft/GSL.git
synced 2025-04-01 08:56:29 -04:00
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.
This commit is contained in:
parent
c832885f15
commit
cb03a17b7e
@ -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<float>, "!ToIntegerCompilesFor<float>");
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
@ -18,13 +18,14 @@
|
||||
|
||||
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
||||
|
||||
#include <algorithm> // for addressof
|
||||
#include <cstdint> // for uint16_t
|
||||
#include <memory> // for shared_ptr, make_shared, operator<, opera...
|
||||
#include <sstream> // for operator<<, ostringstream, basic_ostream:...
|
||||
#include <string> // for basic_string, operator==, string, operator<<
|
||||
#include <typeinfo> // for type_info
|
||||
#include <variant> // for variant, monostate, get
|
||||
#include <algorithm> // for addressof
|
||||
#include <cstdint> // for uint16_t
|
||||
#include <memory> // for shared_ptr, make_shared, operator<, opera...
|
||||
#include <sstream> // for operator<<, ostringstream, basic_ostream:...
|
||||
#include <string> // for basic_string, operator==, string, operator<<
|
||||
#include <type_traits> // for declval
|
||||
#include <typeinfo> // for type_info
|
||||
#include <variant> // for variant, monostate, get
|
||||
|
||||
#include "deathTestCommon.h"
|
||||
using namespace gsl;
|
||||
@ -145,12 +146,6 @@ TEST(notnull_tests, TestNotNullConstructors)
|
||||
{
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
not_null<int*> p = nullptr; // yay...does not compile!
|
||||
not_null<std::vector<char>*> p1 = 0; // yay...does not compile!
|
||||
not_null<int*> p2; // yay...does not compile!
|
||||
std::unique_ptr<int> up = std::make_unique<int>(120);
|
||||
not_null<int*> p3 = up;
|
||||
|
||||
// Forbid non-nullptr assignable types
|
||||
not_null<std::vector<int>> f(std::vector<int>{1});
|
||||
not_null<int> 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<Unrelated*> r = p;
|
||||
not_null<Unrelated*> s = reinterpret_cast<Unrelated*>(p);
|
||||
#endif
|
||||
not_null<Unrelated*> t(reinterpret_cast<Unrelated*>(p.get()));
|
||||
EXPECT_TRUE(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
|
||||
|
||||
(void)static_cast<MyDerived*>(p);
|
||||
(void)static_cast<MyBase*>(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 <class...>
|
||||
using void_t = void;
|
||||
#endif // __cplusplus < 201703l
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool CtorCompilesFor_A = false;
|
||||
template <typename U>
|
||||
static constexpr bool
|
||||
CtorCompilesFor_A<U, void_t<decltype(gsl::not_null<void*>{std::declval<U>()})>> = true;
|
||||
static_assert(CtorCompilesFor_A<void*>, "CtorCompilesFor_A<void*>");
|
||||
static_assert(!CtorCompilesFor_A<std::nullptr_t>, "!CtorCompilesFor_A<std::nullptr_t>");
|
||||
|
||||
template <typename U, int N, typename = void>
|
||||
static constexpr bool CtorCompilesFor_B = false;
|
||||
template <typename U, int N>
|
||||
static constexpr bool CtorCompilesFor_B<U, N, void_t<decltype(gsl::not_null<U>{N})>> = true;
|
||||
static_assert(!CtorCompilesFor_B<void*, 0>, "!CtorCompilesFor_B<void*, 0>");
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool CtorCompilesFor_C = false;
|
||||
template <typename U>
|
||||
static constexpr bool
|
||||
CtorCompilesFor_C<U, void_t<decltype(gsl::not_null<U*>{std::declval<std::unique_ptr<U>>()})>> =
|
||||
true;
|
||||
static_assert(!CtorCompilesFor_C<int>, "CtorCompilesFor_C<int>");
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool DefaultCtorCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool DefaultCtorCompilesFor<U, void_t<decltype(gsl::not_null<U>{})>> = true;
|
||||
static_assert(!DefaultCtorCompilesFor<void*>, "!DefaultCtorCompilesFor<void*>");
|
||||
|
||||
template <typename U, typename V, typename = void>
|
||||
static constexpr bool AssignmentCompilesFor = false;
|
||||
template <typename U, typename V>
|
||||
static constexpr bool
|
||||
AssignmentCompilesFor<U, V,
|
||||
void_t<decltype(std::declval<gsl::not_null<U*>&>().operator=(
|
||||
std::declval<gsl::not_null<V*>&>()))>> = true;
|
||||
static_assert(AssignmentCompilesFor<MyBase, MyDerived>, "AssignmentCompilesFor<MyBase, MyDerived>");
|
||||
static_assert(!AssignmentCompilesFor<MyBase, Unrelated>,
|
||||
"!AssignmentCompilesFor<MyBase, Unrelated>");
|
||||
static_assert(!AssignmentCompilesFor<Unrelated, MyDerived>,
|
||||
"!AssignmentCompilesFor<Unrelated, MyDerived>");
|
||||
static_assert(!AssignmentCompilesFor<MyDerived, MyBase>,
|
||||
"!AssignmentCompilesFor<MyDerived, MyBase>");
|
||||
|
||||
template <typename U, typename V, typename = void>
|
||||
static constexpr bool CastCompilesFor_A = false;
|
||||
template <typename U, typename V>
|
||||
static constexpr bool CastCompilesFor_A<
|
||||
U, V, void_t<decltype(static_cast<U*>(std::declval<gsl::not_null<V*>&>()))>> = true;
|
||||
static_assert(CastCompilesFor_A<MyDerived, MyDerived>, "CastCompilesFor_A<MyDerived, MyDerived>");
|
||||
static_assert(CastCompilesFor_A<MyBase, MyDerived>, "CastCompilesFor_A<MyBase, MyDerived>");
|
||||
static_assert(!CastCompilesFor_A<MyDerived, MyBase>, "!CastCompilesFor_A<MyDerived, MyBase>");
|
||||
static_assert(!CastCompilesFor_A<Unrelated, MyDerived>, "!CastCompilesFor_A<Unrelated, MyDerived>");
|
||||
|
||||
template <typename U, typename V, typename = void>
|
||||
static constexpr bool CastCompilesFor_B = false;
|
||||
template <typename U, typename V>
|
||||
static constexpr bool CastCompilesFor_B<
|
||||
U, V, void_t<decltype(reinterpret_cast<U*>(std::declval<gsl::not_null<V*>&>()))>> = true;
|
||||
static_assert(!CastCompilesFor_B<MyDerived, MyDerived>, "!CastCompilesFor_A<MyDerived, MyDerived>");
|
||||
static_assert(!CastCompilesFor_B<Unrelated, MyDerived>, "!CastCompilesFor_A<Unrelated, MyDerived>");
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool HelperCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool HelperCompilesFor<U, void_t<decltype(helper(std::declval<U>()))>> = true;
|
||||
static_assert(HelperCompilesFor<gsl::not_null<int*>>, "HelperCompilesFor<gsl::not_null<int*>>");
|
||||
static_assert(!HelperCompilesFor<gsl::not_null<const int*>>,
|
||||
"!HelperCompilesFor<gsl::not_null<const int*>>");
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <gsl/pointers> // for owner
|
||||
#include <type_traits> // 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<int> integerTest = 10;
|
||||
owner<std::shared_ptr<int>> sharedPtrTest(new int(10));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if __cplusplus >= 201703l
|
||||
using std::void_t;
|
||||
#else // __cplusplus >= 201703l
|
||||
template <class...>
|
||||
using void_t = void;
|
||||
#endif // __cplusplus < 201703l
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool OwnerCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool OwnerCompilesFor<U, void_t<decltype(gsl::owner<U>{})>> =
|
||||
true;
|
||||
static_assert(OwnerCompilesFor<int*>, "OwnerCompilesFor<int*>");
|
||||
static_assert(!OwnerCompilesFor<int>, "!OwnerCompilesFor<int>");
|
||||
static_assert(!OwnerCompilesFor<std::shared_ptr<int>>, "!OwnerCompilesFor<std::shared_ptr<int>>");
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <type_traits> // 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<const int*> 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<int*> p = nullptr; // yay...does not compile!
|
||||
strict_not_null<std::vector<char>*> p1 = 0; // yay...does not compile!
|
||||
strict_not_null<int*> p2; // yay...does not compile!
|
||||
std::unique_ptr<int> up = std::make_unique<int>(120);
|
||||
strict_not_null<int*> p3 = up;
|
||||
|
||||
// Forbid non-nullptr assignable types
|
||||
strict_not_null<std::vector<int>> f(std::vector<int>{1});
|
||||
strict_not_null<int> z(10);
|
||||
@ -170,10 +163,6 @@ TEST(strict_notnull_tests, TestStrictNotNull)
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
strict_not_null<int*> snn = &x;
|
||||
strict_helper(&x);
|
||||
strict_helper_const(&x);
|
||||
strict_helper(return_pointer());
|
||||
strict_helper_const(return_pointer_const());
|
||||
#endif
|
||||
|
||||
const strict_not_null<int*> snn1{&x};
|
||||
@ -190,17 +179,10 @@ TEST(strict_notnull_tests, TestStrictNotNull)
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
strict_not_null<int*> snn = &x;
|
||||
strict_helper(&x);
|
||||
strict_helper_const(&x);
|
||||
strict_helper(return_pointer());
|
||||
strict_helper_const(return_pointer_const());
|
||||
#endif
|
||||
|
||||
const strict_not_null<const int*> 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<const int*> snn1{&x};
|
||||
const strict_not_null<const int*> 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<const int*> nn1 = snn;
|
||||
const not_null<const int*> 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<const int*> snn1{nn};
|
||||
const strict_not_null<const int*> 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<int*> 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 <class...>
|
||||
using void_t = void;
|
||||
#endif // __cplusplus < 201703l
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool CtorCompilesFor_A = false;
|
||||
template <typename U>
|
||||
static constexpr bool
|
||||
CtorCompilesFor_A<U, void_t<decltype(gsl::strict_not_null<void*>{std::declval<U>()})>> = true;
|
||||
static_assert(CtorCompilesFor_A<void*>, "CtorCompilesFor_A<void*>");
|
||||
static_assert(!CtorCompilesFor_A<std::nullptr_t>, "!CtorCompilesFor_A<std::nullptr_t>");
|
||||
|
||||
template <typename U, int N, typename = void>
|
||||
static constexpr bool CtorCompilesFor_B = false;
|
||||
template <typename U, int N>
|
||||
static constexpr bool CtorCompilesFor_B<U, N, void_t<decltype(gsl::strict_not_null<U>{N})>> = true;
|
||||
static_assert(!CtorCompilesFor_B<void*, 0>, "!CtorCompilesFor_B<void*, 0>");
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool CtorCompilesFor_C = false;
|
||||
template <typename U>
|
||||
static constexpr bool CtorCompilesFor_C<
|
||||
U, void_t<decltype(gsl::strict_not_null<U*>{std::declval<std::unique_ptr<U>>()})>> =
|
||||
true;
|
||||
static_assert(!CtorCompilesFor_C<int>, "CtorCompilesFor_C<int>");
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool DefaultCtorCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool DefaultCtorCompilesFor<U, void_t<decltype(gsl::strict_not_null<U>{})>> = true;
|
||||
static_assert(!DefaultCtorCompilesFor<void*>, "!DefaultCtorCompilesFor<void*>");
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool StrictHelperCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool
|
||||
StrictHelperCompilesFor<U, void_t<decltype(strict_helper(std::declval<U>()))>> = true;
|
||||
static_assert(StrictHelperCompilesFor<strict_not_null<int*>>,
|
||||
"StrictHelperCompilesFor<strict_not_null<int*>>");
|
||||
static_assert(!StrictHelperCompilesFor<const strict_not_null<const int*>>,
|
||||
"!StrictHelperCompilesFor<const strict_not_null<const int*>>");
|
||||
static_assert(!StrictHelperCompilesFor<const not_null<const int*>>,
|
||||
"!StrictHelperCompilesFor<const not_null<const int*>>");
|
||||
static_assert(!StrictHelperCompilesFor<int*>, "!StrictHelperCompilesFor<int*>");
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool HelperCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool
|
||||
HelperCompilesFor<U, void_t<decltype(helper(std::declval<U>()))>> = true;
|
||||
static_assert(HelperCompilesFor<not_null<int*>>,
|
||||
"HelperCompilesFor<not_null<int*>>");
|
||||
static_assert(!HelperCompilesFor<const strict_not_null<const int*>>,
|
||||
"!HelperCompilesFor<const strict_not_null<const int*>>");
|
||||
static_assert(!HelperCompilesFor<const not_null<const int*>>,
|
||||
"!HelperCompilesFor<const not_null<const int*>>");
|
||||
static_assert(HelperCompilesFor<int*>, "HelperCompilesFor<int*>");
|
||||
|
||||
template <typename U, typename = void>
|
||||
static constexpr bool StrictHelperConstCompilesFor = false;
|
||||
template <typename U>
|
||||
static constexpr bool
|
||||
StrictHelperConstCompilesFor<U, void_t<decltype(strict_helper_const(std::declval<U>()))>> = true;
|
||||
static_assert(StrictHelperConstCompilesFor<strict_not_null<const int*>>,
|
||||
"StrictHelperCompilesFor<strict_not_null<const int*>>");
|
||||
static_assert(!StrictHelperConstCompilesFor<const int*>, "!StrictHelperCompilesFor<const int*>");
|
||||
|
Loading…
x
Reference in New Issue
Block a user