From be3c3c27319e95b6c60abbe40f80cb96a695abc1 Mon Sep 17 00:00:00 2001 From: k-brac Date: Tue, 15 Jan 2019 01:43:17 +0100 Subject: [PATCH 1/6] Fixes CMAKE_VERSION check (#759) * Fixes CMAKE_VERSION check Fixes #758 by using the correct comparison operator for a version See documentation at https://cmake.org/cmake/help/latest/command/if.html Thanks to this change, gsl natvis is properly included in a visual studio solution * cmake version check for cmake < 3.7 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 71011b1..0348f79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ else() endif() -if ((CMAKE_VERSION GREATER 3.7.9) OR (CMAKE_VERSION EQUAL 3.7.9)) +if (CMAKE_VERSION VERSION_GREATER 3.7.8) if (MSVC_IDE) option(VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE) else() From 7a7d025ffa99d8602ace633793bc909ce47a8dd7 Mon Sep 17 00:00:00 2001 From: Alex Green Date: Mon, 14 Jan 2019 19:44:45 -0500 Subject: [PATCH 2/6] Make CheckRange constexpr (#754) (#755) --- include/gsl/span | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/gsl/span b/include/gsl/span index f0f7f1f..fae1522 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -544,7 +544,7 @@ public: #endif // _MSC_VER private: - static bool CheckRange(index_type idx, index_type size) noexcept + static constexpr bool CheckRange(index_type idx, index_type size) noexcept { // Optimization: // From 9ff6e19ea9e2ecf48488c0865be85bb1ca183279 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 14 Jan 2019 16:45:47 -0800 Subject: [PATCH 3/6] Dev/annagrin/remove explicit not null constructor (#743) * Added c++17 test configurations for clang5.0 and clang6.0 * Removed explicit not_null constructor, sloppy_not_null, added strict_not_null We added explicit not_null constructor in version 2.0.0. It proved very difficult to switch to the new version for large code bases that adopted previous versions of gsl, due to not_null used extensively in the code. Still, using explicit constructor is very benefitial for new code, since it encorages better API design and make null checks intentional. To resolve the issue, this change: - removes explicit keyword from not_null constructor - removes unneded sloppy_not_null type - adds strict_not_null type to behave the same way as v2 not_null - updates tests * Removed explicit not_null constructor, sloppy_not_null, added strict_not_null We added explicit not_null constructor in version 2.0.0. It proved very difficult to switch to the new version for large code bases that adopted previous versions of gsl, due to not_null used extensively in the code. Still, using explicit constructor is very benefitial for new code, since it encorages better API design and make null checks intentional. To resolve the issue, this change: - removes explicit keyword from not_null constructor - removes unneded sloppy_not_null type - adds strict_not_null type to behave the same way as v2 not_null - updates tests * fixed build break for gcc7 * added more tests * added more non-compiling tests * Addressed PR comments and suppressed a code analysis warning * Fixed test failure in not_null tests --- include/gsl/multi_span | 1 + include/gsl/pointers | 100 ++++++++++++++++- samples/gsl_transition | 130 ---------------------- tests/CMakeLists.txt | 2 +- tests/notnull_tests.cpp | 122 +++++++++++++++------ tests/sloppy_notnull_tests.cpp | 124 --------------------- tests/strict_notnull_tests.cpp | 193 +++++++++++++++++++++++++++++++++ tests/test.cpp | 3 +- 8 files changed, 384 insertions(+), 291 deletions(-) delete mode 100644 samples/gsl_transition delete mode 100644 tests/sloppy_notnull_tests.cpp create mode 100644 tests/strict_notnull_tests.cpp diff --git a/include/gsl/multi_span b/include/gsl/multi_span index dbfff92..9995808 100644 --- a/include/gsl/multi_span +++ b/include/gsl/multi_span @@ -412,6 +412,7 @@ namespace details return totalSize() / this->Base::totalSize(); } + GSL_SUPPRESS(c.128) // NO-FORMAT: attribute // no pointers to BoundsRanges should be ever used constexpr size_type elementNum(std::size_t dim) const noexcept { if (dim > 0) diff --git a/include/gsl/pointers b/include/gsl/pointers index a338856..52c2bfd 100644 --- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -72,13 +72,13 @@ public: static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); template ::value>> - constexpr explicit not_null(U&& u) : ptr_(std::forward(u)) + constexpr not_null(U&& u) : ptr_(std::forward(u)) { Expects(ptr_ != nullptr); } template ::value>> - constexpr explicit not_null(T u) : ptr_(u) + constexpr not_null(T u) : ptr_(u) { Expects(ptr_ != nullptr); } @@ -121,7 +121,7 @@ private: template auto make_not_null(T&& t) { - return gsl::not_null>>{std::forward(t)}; + return not_null>>{std::forward(t)}; } template @@ -189,6 +189,100 @@ struct hash> } // namespace std +namespace gsl +{ + +// +// strict_not_null +// +// Restricts a pointer or smart pointer to only hold non-null values, +// +// - provides a strict (i.e. explicit contructor from T) wrapper of not_null +// - to be used for new code that wishes the design to be cleaner and make not_null +// checks intentional, or in old code that would like to make the transition. +// +// To make the transition from not_null, incrementally replace not_null +// by strict_not_null and fix compilation errors +// +// Expect to +// - remove all unneded conversions from raw pointer to not_null and back +// - make API clear by specifyning not_null in parameters where needed +// - remove unnesessary asserts +// +template +class strict_not_null: public not_null +{ +public: + + template ::value>> + constexpr explicit strict_not_null(U&& u) : + not_null(std::forward(u)) + {} + + template ::value>> + constexpr explicit strict_not_null(T u) : + not_null(u) + {} + + template ::value>> + constexpr strict_not_null(const not_null& other) : + not_null(other) + {} + + template ::value>> + constexpr strict_not_null(const strict_not_null& other) : + not_null(other) + {} + + strict_not_null(strict_not_null&& other) = default; + strict_not_null(const strict_not_null& other) = default; + strict_not_null& operator=(const strict_not_null& other) = default; + strict_not_null& operator=(const not_null& other) + { + not_null::operator=(other); + return *this; + } + + // prevents compilation when someone attempts to assign a null pointer constant + strict_not_null(std::nullptr_t) = delete; + strict_not_null& operator=(std::nullptr_t) = delete; + + // unwanted operators...pointers only point to single objects! + strict_not_null& operator++() = delete; + strict_not_null& operator--() = delete; + strict_not_null operator++(int) = delete; + strict_not_null operator--(int) = delete; + strict_not_null& operator+=(std::ptrdiff_t) = delete; + strict_not_null& operator-=(std::ptrdiff_t) = delete; + void operator[](std::ptrdiff_t) const = delete; +}; + +// more unwanted operators +template +std::ptrdiff_t operator-(const strict_not_null&, const strict_not_null&) = delete; +template +strict_not_null operator-(const strict_not_null&, std::ptrdiff_t) = delete; +template +strict_not_null operator+(const strict_not_null&, std::ptrdiff_t) = delete; +template +strict_not_null operator+(std::ptrdiff_t, const strict_not_null&) = delete; + +template +auto make_strict_not_null(T&& t) { + return strict_not_null>>{std::forward(t)}; +} + +} // namespace gsl + +namespace std +{ +template +struct hash> +{ + std::size_t operator()(const gsl::strict_not_null& value) const { return hash{}(value); } +}; + +} // namespace std #if defined(_MSC_VER) && _MSC_VER < 1910 #undef constexpr #pragma pop_macro("constexpr") diff --git a/samples/gsl_transition b/samples/gsl_transition deleted file mode 100644 index 3f5bf6c..0000000 --- a/samples/gsl_transition +++ /dev/null @@ -1,130 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. -// -// This code is licensed under the MIT License (MIT). -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef GSL_TRANSITION_H -#define GSL_TRANSITION_H - -#include // for Ensures, Expects -#include // for gsl::not_null - -#if defined(_MSC_VER) && _MSC_VER < 1910 -#pragma push_macro("constexpr") -#define constexpr /*constexpr*/ - -#endif // defined(_MSC_VER) && _MSC_VER < 1910 - -namespace gsl_helpers -{ -// -// sloppy_not_null -// -// Restricts a pointer or smart pointer to only hold non-null values, -// -// - provides a sloppy (i.e. no explicit contructor from T) wrapper of gsl::not_null -// - is temporary, only to be used to incrementally transition of code -// using older version of gsl::not_null to the new one that made the constructor explicit -// -// To make the transition: -// -// - replace all occurences of gsl::not_null in your code by sloppy_not_null -// variant: rename gsl::not_null by NotNull by including the following in your code, -// foe example, in a common include file: -// -// template -// using NotNull = gsl::not_null; -// -// compile using old version of GSL -// change GSL version and replace gsl::not_null by gsl_helpers::sloppy_not_null -// in the added code lines above -// -// - compile - compilation should be successful -// - replace some sloppy_not_nulls by gsl::not_null, fix compilation erros, -// redesign as needed, compile and test -// - repeat until no sloppy_not_nulls remain -// -template -class sloppy_not_null: public gsl::not_null -{ -public: - - template ::value>> - constexpr sloppy_not_null(U&& u) : - gsl::not_null(std::forward(u)) - {} - - template ::value>> - constexpr sloppy_not_null(T u) : - gsl::not_null(u) - {} - - template ::value>> - constexpr sloppy_not_null(const gsl::not_null& other) : - gsl::not_null(other) - {} - - sloppy_not_null(sloppy_not_null&& other) = default; - sloppy_not_null(const sloppy_not_null& other) = default; - sloppy_not_null& operator=(const sloppy_not_null& other) = default; - sloppy_not_null& operator=(const gsl::not_null& other) - { - gsl::not_null::operator=(other); - return *this; - } - - // prevents compilation when someone attempts to assign a null pointer constant - sloppy_not_null(std::nullptr_t) = delete; - sloppy_not_null& operator=(std::nullptr_t) = delete; - - // unwanted operators...pointers only point to single objects! - sloppy_not_null& operator++() = delete; - sloppy_not_null& operator--() = delete; - sloppy_not_null operator++(int) = delete; - sloppy_not_null operator--(int) = delete; - sloppy_not_null& operator+=(std::ptrdiff_t) = delete; - sloppy_not_null& operator-=(std::ptrdiff_t) = delete; - void operator[](std::ptrdiff_t) const = delete; -}; - -// more unwanted operators -template -std::ptrdiff_t operator-(const sloppy_not_null&, const sloppy_not_null&) = delete; -template -sloppy_not_null operator-(const sloppy_not_null&, std::ptrdiff_t) = delete; -template -sloppy_not_null operator+(const sloppy_not_null&, std::ptrdiff_t) = delete; -template -sloppy_not_null operator+(std::ptrdiff_t, const sloppy_not_null&) = delete; - -} // namespace gsl - -namespace std -{ -template -struct hash> -{ - std::size_t operator()(const gsl_helpers::sloppy_not_null& value) const { return hash{}(value); } -}; - -} // namespace std - -#if defined(_MSC_VER) && _MSC_VER < 1910 -#undef constexpr -#pragma pop_macro("constexpr") - -#endif // defined(_MSC_VER) && _MSC_VER < 1910 - -#endif // GSL_TRANSITION_H - diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2d37a51..6edb8a0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -107,7 +107,7 @@ add_gsl_test(utils_tests) add_gsl_test(owner_tests) add_gsl_test(byte_tests) add_gsl_test(algorithm_tests) -add_gsl_test(sloppy_notnull_tests) +add_gsl_test(strict_notnull_tests) # No exception tests diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index 668c0a2..ef767c6 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -25,7 +25,7 @@ #include // for AssertionHandler, StringRef, CHECK, TEST_... -#include // for not_null, operator<, operator<=, operator> +#include // for not_null, operator<, operator<=, operator> #include // for addressof #include // for shared_ptr, make_shared, operator<, opera... @@ -128,47 +128,105 @@ struct NonCopyableNonMovable }; GSL_SUPPRESS(f.4) // NO-FORMAT: attribute -bool helper(not_null p) -{ - return *p == 12; -} - +bool helper(not_null p) { return *p == 12; } GSL_SUPPRESS(f.4) // NO-FORMAT: attribute -bool helper_const(not_null p) -{ - return *p == 12; -} +bool helper_const(not_null p) { return *p == 12; } + +int* return_pointer() { return nullptr; } +const int* return_pointer_const() { return nullptr; } GSL_SUPPRESS(con.4) // NO-FORMAT: attribute TEST_CASE("TestNotNullConstructors") { + { #ifdef CONFIRM_COMPILATION_ERRORS - not_null p = nullptr; // yay...does not compile! - not_null*> p = 0; // yay...does not compile! - not_null p; // yay...does not compile! - std::unique_ptr up = std::make_unique(120); - not_null p = up; + 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); - not_null> y({1, 2}); + // Forbid non-nullptr assignable types + not_null> f(std::vector{1}); + not_null z(10); + not_null> y({1, 2}); #endif - int i = 12; - auto rp = RefCounted(&i); - not_null p(rp); - CHECK(p.get() == &i); + } - not_null> x( - std::make_shared(10)); // shared_ptr is nullptr assignable + { + // from shared pointer + int i = 12; + auto rp = RefCounted(&i); + not_null p(rp); + CHECK(p.get() == &i); -#ifdef GSL_THROW_ON_CONTRACT_VIOLATION - int* pi = nullptr; - CHECK_THROWS_AS(not_null(pi), fail_fast); -#endif + not_null> x( + std::make_shared(10)); // shared_ptr is nullptr assignable + + int* pi = nullptr; + CHECK_THROWS_AS(not_null(pi), fail_fast); + } + + { + // from pointer to local + int t = 42; + + not_null x = &t; + helper(&t); + helper_const(&t); + + CHECK(*x == 42); + } + + { + // from raw pointer + // from not_null pointer + + int t = 42; + int* p = &t; + + not_null x = p; + helper(p); + helper_const(p); + helper(x); + helper_const(x); + + CHECK(*x == 42); + } + + { + // from raw const pointer + // from not_null const pointer + + int t = 42; + const int* cp = &t; + + not_null x = cp; + helper_const(cp); + helper_const(x); + + CHECK(*x == 42); + } + + { + // from not_null const pointer, using auto + int t = 42; + const int* cp = &t; + + auto x = not_null{cp}; + + CHECK(*x == 42); + } + + { + // from returned pointer + + CHECK_THROWS_AS(helper(return_pointer()), fail_fast); + CHECK_THROWS_AS(helper_const(return_pointer()), fail_fast); + } } -template +template GSL_SUPPRESS(con.4) // NO-FORMAT: attribute void ostream_helper(T v) { @@ -474,5 +532,5 @@ TEST_CASE("TestMakeNotNull") #endif } -static_assert(std::is_nothrow_move_constructible>::value, "not_null must be no-throw move constructible"); - +static_assert(std::is_nothrow_move_constructible>::value, + "not_null must be no-throw move constructible"); diff --git a/tests/sloppy_notnull_tests.cpp b/tests/sloppy_notnull_tests.cpp deleted file mode 100644 index 51983f5..0000000 --- a/tests/sloppy_notnull_tests.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2015 Microsoft Corporation. All rights reserved. -// -// This code is licensed under the MIT License (MIT). -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifdef _MSC_VER -// blanket turn off warnings from CppCoreCheck from catch -// so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26440 26426) // from catch - -// Fix VS2015 build breaks in Release -#pragma warning(disable : 4702) // unreachable code -#endif - -#include // for AssertionHandler, StringRef, CHECK, TEST_... - -#include // for not_null, operator<, operator<=, operator> -#include // for sloppy_not_null - -namespace gsl -{ -struct fail_fast; -} // namespace gsl - -using namespace gsl; -using namespace gsl_helpers; - -GSL_SUPPRESS(f.4) // NO-FORMAT: attribute -bool helper(not_null p) { return *p == 12; } -GSL_SUPPRESS(f.4) // NO-FORMAT: attribute -bool helper_const(not_null p) { return *p == 12; } - -GSL_SUPPRESS(f.4) // NO-FORMAT: attribute -bool sloppy_helper(sloppy_not_null p) { return *p == 12; } -GSL_SUPPRESS(f.4) // NO-FORMAT: attribute -bool sloppy_helper_const(sloppy_not_null p) { return *p == 12; } - -TEST_CASE("TestSloppyNotNull") -{ - { - // raw ptr <-> sloppy_not_null - int x = 42; - - const sloppy_not_null snn = &x; - - sloppy_helper(&x); - sloppy_helper_const(&x); - - CHECK(*snn == 42); - } - - { - // sloppy_not_null -> sloppy_not_null - int x = 42; - - sloppy_not_null snn1{&x}; - const sloppy_not_null snn2{&x}; - - sloppy_helper(snn1); - sloppy_helper_const(snn1); - - CHECK(snn1 == snn2); - } - - { - // sloppy_not_null -> not_null - int x = 42; - - sloppy_not_null snn{&x}; - - const not_null nn1 = snn; - const not_null nn2{snn}; - - helper(snn); - helper_const(snn); - - CHECK(snn == nn1); - CHECK(snn == nn2); - } - - { - // not_null -> sloppy_not_null - int x = 42; - - not_null nn{&x}; - - const sloppy_not_null snn1{nn}; - const sloppy_not_null snn2 = nn; - - sloppy_helper(nn); - sloppy_helper_const(nn); - - CHECK(snn1 == nn); - CHECK(snn2 == nn); - - std::hash> hash_snn; - std::hash> hash_nn; - - CHECK(hash_nn(snn1) == hash_nn(nn)); - CHECK(hash_snn(snn1) == hash_nn(nn)); - CHECK(hash_nn(snn1) == hash_nn(snn2)); - CHECK(hash_snn(snn1) == hash_snn(nn)); - } - -#ifdef CONFIRM_COMPILATION_ERRORS - { - sloppy_not_null p{nullptr}; - } -#endif -} - -static_assert(std::is_nothrow_move_constructible>::value, - "sloppy_not_null must be no-throw move constructible"); diff --git a/tests/strict_notnull_tests.cpp b/tests/strict_notnull_tests.cpp new file mode 100644 index 0000000..055afec --- /dev/null +++ b/tests/strict_notnull_tests.cpp @@ -0,0 +1,193 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifdef _MSC_VER +// blanket turn off warnings from CppCoreCheck from catch +// so people aren't annoyed by them when running the tool. +#pragma warning(disable : 26440 26426) // from catch + +// Fix VS2015 build breaks in Release +#pragma warning(disable : 4702) // unreachable code +#endif + +#include // for AssertionHandler, StringRef, CHECK, TEST_... +#include // for not_null, operator<, operator<=, operator> + +namespace gsl +{ +struct fail_fast; +} // namespace gsl + +using namespace gsl; + +GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +bool helper(not_null p) { return *p == 12; } +GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +bool helper_const(not_null p) { return *p == 12; } + +GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +bool strict_helper(strict_not_null p) { return *p == 12; } +GSL_SUPPRESS(f.4) // NO-FORMAT: attribute +bool strict_helper_const(strict_not_null p) { return *p == 12; } + +int* return_pointer() { return nullptr; } +const int* return_pointer_const() { return nullptr; } + +GSL_SUPPRESS(con.4) // NO-FORMAT: attribute +TEST_CASE("TestStrictNotNull") +{ + { + // raw ptr <-> strict_not_null + int x = 42; + +#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}; + + helper(snn1); + helper_const(snn1); + + CHECK(*snn1 == 42); + } + + { + // strict_not_null -> strict_not_null + int x = 42; + + strict_not_null snn1{&x}; + const strict_not_null snn2{&x}; + + strict_helper(snn1); + strict_helper_const(snn1); + strict_helper_const(snn2); + + CHECK(snn1 == snn2); + } + + { + // strict_not_null -> not_null + int x = 42; + + strict_not_null snn{&x}; + + const not_null nn1 = snn; + const not_null nn2{snn}; + + helper(snn); + helper_const(snn); + + CHECK(snn == nn1); + CHECK(snn == nn2); + } + + { + // not_null -> strict_not_null + int x = 42; + + not_null nn{&x}; + + const strict_not_null snn1{nn}; + const strict_not_null snn2{nn}; + + strict_helper(nn); + strict_helper_const(nn); + + CHECK(snn1 == nn); + CHECK(snn2 == nn); + + std::hash> hash_snn; + std::hash> hash_nn; + + CHECK(hash_nn(snn1) == hash_nn(nn)); + CHECK(hash_snn(snn1) == hash_nn(nn)); + CHECK(hash_nn(snn1) == hash_nn(snn2)); + CHECK(hash_snn(snn1) == hash_snn(nn)); + } + +#ifdef CONFIRM_COMPILATION_ERRORS + { + strict_not_null p{nullptr}; + } +#endif +} + +#if defined(__cplusplus) && (__cplusplus >= 201703L) + +GSL_SUPPRESS(con.4) // NO-FORMAT: attribute +TEST_CASE("TestStrictNotNullConstructorTypeDeduction") +{ + { + int i = 42; + + strict_not_null x{&i}; + helper(strict_not_null{&i}); + helper_const(strict_not_null{&i}); + + CHECK(*x == 42); + } + + { + int i = 42; + int* p = &i; + + strict_not_null x{p}; + helper(strict_not_null{p}); + helper_const(strict_not_null{p}); + + CHECK(*x == 42); + } + + { + auto workaround_macro = []() { + int* p1 = nullptr; + const strict_not_null x{p1}; + }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } + + { + auto workaround_macro = []() { + const int* p1 = nullptr; + const strict_not_null x{p1}; + }; + CHECK_THROWS_AS(workaround_macro(), fail_fast); + } + + { + int* p = nullptr; + + CHECK_THROWS_AS(helper(strict_not_null{p}), fail_fast); + CHECK_THROWS_AS(helper_const(strict_not_null{p}), fail_fast); + } + +#ifdef CONFIRM_COMPILATION_ERRORS + { + strict_not_null x{nullptr}; + helper(strict_not_null{nullptr}); + helper_const(strict_not_null{nullptr}); + } +#endif +} +#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L) + +static_assert(std::is_nothrow_move_constructible>::value, + "strict_not_null must be no-throw move constructible"); diff --git a/tests/test.cpp b/tests/test.cpp index dbdebb6..47daf5c 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -20,7 +20,8 @@ // blanket turn off warnings from CppCoreCheck from catch // so people aren't annoyed by them when running the tool. -#pragma warning(disable : 26401 26409 26415 26418 26426 26429 26432 26433 26434 26435 26436 26439 26440 26443 26444 26446 26447 26451 26460 26461 26466 26472 26481 26482 26485 26492 26493 26494 26495 26496 26497) // from catch +#include +#pragma warning(disable : ALL_CODE_ANALYSIS_WARNINGS) // from catch #endif // _MSC_VER #include From 6eeed739f1acb81c8b69ceae11bd5f350dab3601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johel=20Ernesto=20Guerrero=20Pe=C3=B1a?= Date: Mon, 14 Jan 2019 22:37:37 -0400 Subject: [PATCH 4/6] Make narrow constexpr (#698) --- include/gsl/gsl_util | 9 +++++++++ tests/utils_tests.cpp | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util index 542bbaa..1558044 100644 --- a/include/gsl/gsl_util +++ b/include/gsl/gsl_util @@ -37,6 +37,12 @@ #endif // _MSC_VER < 1910 #endif // _MSC_VER +#if (defined(_MSC_VER) && _MSC_VER < 1910) || (!defined(__clang__) && defined(__GNUC__) && __GUNC__ < 6) +#define GSL_CONSTEXPR_NARROW 0 +#else +#define GSL_CONSTEXPR_NARROW 1 +#endif + namespace gsl { // @@ -111,6 +117,9 @@ namespace details template GSL_SUPPRESS(type.1) // NO-FORMAT: attribute GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false) +#if GSL_CONSTEXPR_NARROW +constexpr +#endif T narrow(U u) noexcept(false) { T t = narrow_cast(u); diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index 05f8d0f..5cacd97 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -126,4 +126,8 @@ TEST_CASE("narrow") n = -42; CHECK_THROWS_AS(narrow(n), narrowing_error); + +#if GSL_CONSTEXPR_NARROW + static_assert(narrow(120) == 120, "Fix GSL_CONSTEXPR_NARROW"); +#endif } From 6418b5f4de2204cd5a335b00d2f8754301b8b382 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 15 Jan 2019 10:27:34 -0800 Subject: [PATCH 5/6] Clang cl (#762) * Added c++17 test configurations for clang5.0 and clang6.0 * Fix #739 correct cppcorecheck warnings for clang-cl * Add clang-cl configurations * Corrections Appveyor; Temporarily disable msvc compilation for faster testing (#741) * Add path to clang-cl.exe (#741) * Escape backslash in path (#741) * Update vcpkg (#741) * Check vcpkg version; try without building vcpkg; use latest clang-cl from path (#741) * Fix blocks in ps script (#741) * Try accessing APPVEYOR_BUILD_FOLDER variable (#471) * Update span size() bug confirmation test for GCC 6.5 (#741) * MSVC flags to Clang-cl; disable c++98-compat and undefined macro warnings (#741) * Suppress clang warning on tests (missing-prototypes) (#741) * Fix clang warning -Wnewline-eof (#741) * Fix clang warning -Wdouble-promotion (#741) * Set linker explicitly * Clean condition statement * For Clang, fallback to the AppVeyor installed version of CMake * Fix clang warning -Wmissing-variable-declarations * Fallback to the MSVC linker until vcpkg has been updated * Revert "Fallback to the MSVC linker until vcpkg has been updated" This reverts commit 7263f3289e6e835c32fc7800d0c2d4e58bd21178. * Fix clang warning -Wunused-member-function * Fix clang warning -Wmissing-noreturn * Fix clang warning -Winvalid-noreturn on Windows * Add macro block end comment on large #if blocks * Workaround: fallback to mscv link.exe * Workaround: get msvc paths into PowerShell through intermediate file * Workaround: fix, remove "PATH=" from text * Workaround: try with full-path; and return user PATH * Workaround: fix, escape backslashes * Revert all since "Workaround: fallback to mscv link.exe" did not work on AppVeyor This reverts the commits: bda3d6a428e5d19e97375b2e575b0f51ff1b4bc0 97062933acfb6428535c0fdcab5d94371ce72bfc 0f4fb04bac9c2d091005b791294237250dbe0668 1b0c19afd154f4ffc5ef793014c1bc2324534fd0 a5739ea5f0cd7633527b5e5d3b16a9e3ade7149f * Suppress output of git pull; remove vcpkg from cache * Re-enable AppVeyor builds for all platforms * Correct typo Co-Authored-By: Farwaykorse * Add Clang-cl 7.0.0 to the supported platforms * Revert "Fix clang warning -Wunused-member-function" This reverts commit 6fe1a4203501145ab4350b9152ecc11f3a30e49a. * Fix or locally suppress clang warning -Wunused-member-function * format touched code and correct comment * git pull --quiet * fix logic error in workaround * fix missing bracket * Suppress output of mkdir * Replace MSBuild with Ninja * Suppress output of 7z * Add architecture flags for Clang * Drop workaround for lld-link * 7-zip Overwrite and Alternative output suppression without suppressing errors Replaces 3c1c0794dd9a29908cc7c38f591bd3c7b4929677 * AppVeyor setup and CMake before build * reorder compiler configuration * remove unnecessary * remove -fno-strict-aliasing * remove -Wsign-conversion, since before v4.0 part of -Wconversion * -Wctor-dtor-privacy is GCC only * remove -Woverloaded-virtual part of -Wmost, part of -Wall * add -Wmissing-noreturn * remove the pragmas for -Wunused-member-function * Re-add MSBuild generator on AppVeyor * Print CMake commands * Add MSBuild toolset selection * Separate Architecture setting * clang-cl: add -Weverything * clang-cl -Wno-c++98-compat * clang-cl -Wno-c++98-compat-pedantic * clang-cl -Wno-missing-prototypes * clang-cl C++14 -Wno-unused-member-function * clang-cl -Wundef __GNUC__ * clang++: add -Weverything * clang++ -Wno-c++98-compat * clang++ -Wno-c++98-compat-pedantic * clang++ -Wno-missing-prototypes * clang++ -Wno-weak-vtables * clang++ C++14 -Wno-unused-member-function * clang++ fix -Wundef _MSC_VER * clang++ -Wno-padded * clang++ solve -Wdeprecated * Add AppleClang compiler target Since CMake v3.0 use of Clang for both is deprecated * clang++ v5.0 C++17 -Wno-undefined-func-template * Add VS2015 + LLVM/clang-cl to AppVeyor * Do not disable constexpr when compiling with clang-cl on Windows * Clean-up clang-only warnings (now under -Weverything) * Revert "Fix clang warning -Winvalid-noreturn on Windows" This reverts commit 2238c4760e86feebb2a18620b77312bd01055f61. * Suppress -Winvalid-noreturn for the MS STL noexception workaround * CMake: put preprocessor definition in target_compile_definitions * Solve compiler warning C4668: __GNUC__ not defined --- README.md | 1 + appveyor.yml | 94 ++++++++++++++++++++++++----- include/gsl/gsl_assert | 26 +++++--- include/gsl/gsl_byte | 12 ++-- include/gsl/gsl_util | 4 +- include/gsl/multi_span | 11 ++-- include/gsl/pointers | 8 ++- include/gsl/span | 8 +-- include/gsl/string_span | 4 +- tests/CMakeLists.txt | 92 +++++++++++++++++++--------- tests/multi_span_tests.cpp | 2 +- tests/no_exception_ensure_tests.cpp | 15 ++--- tests/no_exception_throw_tests.cpp | 12 ++-- tests/notnull_tests.cpp | 2 +- tests/span_tests.cpp | 14 +++-- tests/strided_span_tests.cpp | 12 ++-- tests/utils_tests.cpp | 2 +- 17 files changed, 213 insertions(+), 106 deletions(-) diff --git a/README.md b/README.md index f6fde29..db7d406 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ The test suite that exercises GSL has been built and passes successfully on the * Windows using Visual Studio 2015 * Windows using Visual Studio 2017 * Windows using Clang/LLVM 3.6 +* Windows using Clang/LLVM 7.0.0 * Windows using GCC 5.1 * Windows using Intel C++ Compiler 18.0 * GNU/Linux using Clang/LLVM 3.6 diff --git a/appveyor.yml b/appveyor.yml index 2fc8a16..c3e3c87 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,44 +13,108 @@ image: - Visual Studio 2017 environment: + NINJA_TAG: v1.8.2 + NINJA_SHA512: 9B9CE248240665FCD6404B989F3B3C27ED9682838225E6DC9B67B551774F251E4FF8A207504F941E7C811E7A8BE1945E7BCB94472A335EF15E23A0200A32E6D5 + NINJA_PATH: C:\Tools\ninja\ninja-%NINJA_TAG% + VCVAR2015: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat' + VCVAR2017: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat' matrix: - GSL_CXX_STANDARD: 14 + USE_TOOLSET: MSVC + USE_GENERATOR: MSBuild - GSL_CXX_STANDARD: 17 + USE_TOOLSET: MSVC + USE_GENERATOR: MSBuild + - GSL_CXX_STANDARD: 14 + USE_TOOLSET: LLVM + USE_GENERATOR: Ninja + - GSL_CXX_STANDARD: 17 + USE_TOOLSET: LLVM + USE_GENERATOR: Ninja matrix: exclude: - image: Visual Studio 2015 GSL_CXX_STANDARD: 17 + - image: Visual Studio 2015 + USE_TOOLSET: LLVM + USE_GENERATOR: MSBuild cache: - C:\cmake-3.8.0-win32-x86 + - C:\Tools\ninja install: - ps: | - if (![IO.File]::Exists("C:\cmake-3.8.0-win32-x86\bin\cmake.exe")) { - Start-FileDownload 'https://cmake.org/files/v3.8/cmake-3.8.0-win32-x86.zip' - 7z x -y cmake-3.8.0-win32-x86.zip -oC:\ + if (![IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) { + Start-FileDownload ` + "https://github.com/ninja-build/ninja/releases/download/$env:NINJA_TAG/ninja-win.zip" + $hash = (Get-FileHash ninja-win.zip -Algorithm SHA512).Hash + if ($env:NINJA_SHA512 -eq $hash) { + 7z e -y -bso0 ninja-win.zip -o"$env:NINJA_PATH" + } else { Write-Warning "Ninja download hash changed!"; Write-Output "$hash" } + } + if ([IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) { + $env:PATH = "$env:NINJA_PATH;$env:PATH" + } else { Write-Warning "Failed to find ninja.exe in expected location." } + if ($env:USE_TOOLSET -ne "LLVM") { + if (![IO.File]::Exists("C:\cmake-3.8.0-win32-x86\bin\cmake.exe")) { + Start-FileDownload 'https://cmake.org/files/v3.8/cmake-3.8.0-win32-x86.zip' + 7z x -y -bso0 cmake-3.8.0-win32-x86.zip -oC:\ + } + $env:PATH="C:\cmake-3.8.0-win32-x86\bin;$env:PATH" } - $env:PATH="C:\cmake-3.8.0-win32-x86\bin;$env:PATH" before_build: - ps: | - mkdir build - cd build - - if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2015") { - $env:generator="Visual Studio 14 2015" + if ("$env:USE_GENERATOR" -eq "Ninja") { + $GeneratorFlags = '-k 10' + $Architecture = $env:PLATFORM + if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2015") { + $env:VCVARSALL = "`"$env:VCVAR2015`" $Architecture" + } else { + $env:VCVARSALL = "`"$env:VCVAR2017`" $Architecture" + } + $env:CMakeGenFlags = "-G Ninja -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD" } else { - $env:generator="Visual Studio 15 2017" + $GeneratorFlags = '/m /v:minimal' + if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2015") { + $Generator = 'Visual Studio 14 2015' + } else { + $Generator = 'Visual Studio 15 2017' + } + if ("$env:PLATFORM" -eq "x86") { + $Architecture = "Win32" + } else { + $Architecture = "x64" + } + if ("$env:USE_TOOLSET" -eq "LLVM") { + $env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -T llvm -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD" + } else { + $env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD" + } } - if ($env:PLATFORM -eq "x64") { - $env:generator="$env:generator Win64" + if ("$env:USE_TOOLSET" -eq "LLVM") { + $env:CC = "clang-cl" + $env:CXX = "clang-cl" + if ("$env:PLATFORM" -eq "x86") { + $env:CFLAGS = "-m32"; + $env:CXXFLAGS = "-m32"; + } else { + $env:CFLAGS = "-m64"; + $env:CXXFLAGS = "-m64"; + } } - echo generator="$env:generator" - cmake .. -G "$env:generator" -DGSL_CXX_STANDARD="$env:GSL_CXX_STANDARD" + $env:CMakeBuildFlags = "--config $env:CONFIGURATION -- $GeneratorFlags" + - mkdir build + - cd build + - if %USE_GENERATOR%==Ninja (call %VCVARSALL%) + - echo %CMakeGenFlags% + - cmake .. %CMakeGenFlags% build_script: - - cmake --build . --config %CONFIGURATION% -- /m /v:minimal + - echo %CMakeBuildFlags% + - cmake --build . %CMakeBuildFlags% test_script: - ctest -j2 diff --git a/include/gsl/gsl_assert b/include/gsl/gsl_assert index 3c952e6..c704633 100644 --- a/include/gsl/gsl_assert +++ b/include/gsl/gsl_assert @@ -22,17 +22,17 @@ // // make suppress attributes parse for some compilers -// Hopefully temporary until suppresion standardization occurs +// Hopefully temporary until suppression standardization occurs // -#if defined (_MSC_VER) -#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] -#else #if defined(__clang__) #define GSL_SUPPRESS(x) [[gsl::suppress("x")]] #else +#if defined(_MSC_VER) +#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] +#else #define GSL_SUPPRESS(x) -#endif // __clang__ #endif // _MSC_VER +#endif // __clang__ // // Temporary until MSVC STL supports no-exceptions mode. @@ -42,6 +42,12 @@ #define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND #include #define RANGE_CHECKS_FAILURE 0 + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winvalid-noreturn" +#endif + #endif // @@ -98,7 +104,7 @@ namespace details #if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) typedef void (__cdecl *terminate_handler)(); - + GSL_SUPPRESS(f.6) // NO-FORMAT: attribute [[noreturn]] inline void __cdecl default_terminate_handler() { @@ -138,7 +144,7 @@ namespace details throw std::forward(exception); } -#endif +#endif // GSL_TERMINATE_ON_CONTRACT_VIOLATION } // namespace details } // namespace gsl @@ -159,9 +165,13 @@ namespace details #define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond) -#endif +#endif // GSL_THROW_ON_CONTRACT_VIOLATION #define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond) #define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond) +#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) && defined(__clang__) +#pragma clang diagnostic pop +#endif + #endif // GSL_CONTRACTS_H diff --git a/include/gsl/gsl_byte b/include/gsl/gsl_byte index bc18886..861446d 100644 --- a/include/gsl/gsl_byte +++ b/include/gsl/gsl_byte @@ -19,17 +19,17 @@ // // make suppress attributes work for some compilers -// Hopefully temporary until suppresion standardization occurs +// Hopefully temporary until suppression standardization occurs // -#if defined(_MSC_VER) -#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] -#else #if defined(__clang__) #define GSL_SUPPRESS(x) [[gsl::suppress("x")]] #else +#if defined(_MSC_VER) +#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] +#else #define GSL_SUPPRESS(x) -#endif // __clang__ #endif // _MSC_VER +#endif // __clang__ #include @@ -79,7 +79,7 @@ #endif // _MSC_VER // Use __may_alias__ attribute on gcc and clang -#if defined __clang__ || (__GNUC__ > 5) +#if defined __clang__ || (defined(__GNUC__) && __GNUC__ > 5) #define byte_may_alias __attribute__((__may_alias__)) #else // defined __clang__ || defined __GNUC__ #define byte_may_alias diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util index 1558044..4addde6 100644 --- a/include/gsl/gsl_util +++ b/include/gsl/gsl_util @@ -26,7 +26,7 @@ #include // for is_signed, integral_constant #include // for forward -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant @@ -161,7 +161,7 @@ constexpr T at(const std::initializer_list cont, const index i) } // namespace gsl -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) #if _MSC_VER < 1910 #undef constexpr #pragma pop_macro("constexpr") diff --git a/include/gsl/multi_span b/include/gsl/multi_span index 9995808..f1a909e 100644 --- a/include/gsl/multi_span +++ b/include/gsl/multi_span @@ -37,7 +37,7 @@ #include // for enable_if_t, remove_cv_t, is_same, is_co... #include -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) // turn off some warnings that are noisy about our Expects statements #pragma warning(push) @@ -62,7 +62,7 @@ // compiletime, so the compiler wouldn't have to warn indiscriminently, but // could check if the source value actually doesn't fit into the target type // and only warn in those cases. -#if __GNUC__ > 6 +#if defined(__GNUC__) && __GNUC__ > 6 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" #endif @@ -596,7 +596,6 @@ public: using sliced_type = static_bounds; using mapping_type = contiguous_mapping_tag; - constexpr static_bounds(const static_bounds&) noexcept = default; constexpr static_bounds() /*noexcept*/ = default; template @@ -1887,6 +1886,8 @@ public: auto d = narrow_cast(sizeof(OtherValueType) / sizeof(value_type)); const size_type size = this->bounds().total_size() / d; + + GSL_SUPPRESS(type.3) // NO-FORMAT: attribute return {const_cast(reinterpret_cast(this->data())), size, bounds_type{resize_extent(this->bounds().index_bounds(), d), @@ -2274,7 +2275,7 @@ general_span_iterator operator+(typename general_span_iterator::diff } // namespace gsl -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #if _MSC_VER < 1910 #undef constexpr @@ -2285,7 +2286,7 @@ general_span_iterator operator+(typename general_span_iterator::diff #endif // _MSC_VER -#if __GNUC__ > 6 +#if defined(__GNUC__) && __GNUC__ > 6 #pragma GCC diagnostic pop #endif // __GNUC__ > 6 diff --git a/include/gsl/pointers b/include/gsl/pointers index 52c2bfd..0f2987a 100644 --- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -25,7 +25,7 @@ #include // for hash #include // for enable_if_t, is_convertible, is_assignable -#if defined(_MSC_VER) && _MSC_VER < 1910 +#if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__) #pragma push_macro("constexpr") #define constexpr /*constexpr*/ @@ -283,10 +283,12 @@ struct hash> }; } // namespace std -#if defined(_MSC_VER) && _MSC_VER < 1910 + +#if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__) + #undef constexpr #pragma pop_macro("constexpr") -#endif // defined(_MSC_VER) && _MSC_VER < 1910 +#endif // defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__) #endif // GSL_POINTERS_H diff --git a/include/gsl/span b/include/gsl/span index fae1522..b4da532 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -31,7 +31,7 @@ #include #include // for std::addressof -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) // turn off some warnings that are noisy about our Expects statements @@ -61,7 +61,7 @@ // compiletime, so the compiler wouldn't have to warn indiscriminently, but // could check if the source value actually doesn't fit into the target type // and only warn in those cases. -#if __GNUC__ > 6 +#if defined(__GNUC__) && __GNUC__ > 6 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" #endif @@ -776,7 +776,7 @@ constexpr ElementType& at(span s, index i) } // namespace gsl -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #if _MSC_VER < 1910 #undef constexpr #pragma pop_macro("constexpr") @@ -786,7 +786,7 @@ constexpr ElementType& at(span s, index i) #pragma warning(pop) #endif // _MSC_VER -#if __GNUC__ > 6 +#if defined(__GNUC__) && __GNUC__ > 6 #pragma GCC diagnostic pop #endif // __GNUC__ > 6 diff --git a/include/gsl/string_span b/include/gsl/string_span index d298039..b5dfd18 100644 --- a/include/gsl/string_span +++ b/include/gsl/string_span @@ -30,7 +30,7 @@ #include // for basic_string, allocator, char_traits #include // for declval, is_convertible, enable_if_t, add_... -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #pragma warning(push) // Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool. @@ -706,7 +706,7 @@ bool operator>=(const T& one, gsl::basic_string_span other) #endif } // namespace gsl -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #pragma warning(pop) #if _MSC_VER < 1910 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6edb8a0..832513f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 3.0.2) project(GSLTests CXX) @@ -33,14 +33,24 @@ endif() # this interface adds compile options to how the tests are run # please try to keep entries ordered =) add_library(gsl_tests_config INTERFACE) -target_compile_options(gsl_tests_config INTERFACE - $<$: +if(MSVC) # MSVC or simulating MSVC + target_compile_options(gsl_tests_config INTERFACE + ${GSL_CPLUSPLUS_OPT} /EHsc /W4 /WX - > - ${GSL_CPLUSPLUS_OPT} - $<$>: + $<$: + -Weverything + -Wno-c++98-compat + -Wno-c++98-compat-pedantic + -Wno-missing-braces + -Wno-missing-prototypes + -Wno-unknown-attributes + $<$:-Wno-unused-member-function> + > + ) +else() + target_compile_options(gsl_tests_config INTERFACE -fno-strict-aliasing -Wall -Wcast-align @@ -48,16 +58,25 @@ target_compile_options(gsl_tests_config INTERFACE -Wctor-dtor-privacy -Werror -Wextra - -Wno-missing-braces - -Wno-unknown-attributes - -Wnon-virtual-dtor - -Wold-style-cast - -Woverloaded-virtual -Wpedantic -Wshadow -Wsign-conversion - > -) + $<$,$>: + -Weverything + -Wno-c++98-compat + -Wno-c++98-compat-pedantic + -Wno-missing-braces + -Wno-missing-prototypes + -Wno-padded + -Wno-unknown-attributes + $<$:-Wno-unused-member-function> + -Wno-weak-vtables + > + $<$: + $<$:-Wno-undefined-func-template> + > + ) +endif(MSVC) # for tests to find the catch header target_include_directories(gsl_tests_config INTERFACE @@ -121,34 +140,49 @@ endforeach(flag_var) # this interface adds compile options to how the tests are run # please try to keep entries ordered =) add_library(gsl_tests_config_noexcept INTERFACE) -target_compile_options(gsl_tests_config_noexcept INTERFACE - $<$: - /D_HAS_EXCEPTIONS=0 - /wd4702 - /wd4577 +if(MSVC) # MSVC or simulating MSVC + target_compile_definitions(gsl_tests_config_noexcept INTERFACE + _HAS_EXCEPTIONS=0 + ) + target_compile_options(gsl_tests_config_noexcept INTERFACE + ${GSL_CPLUSPLUS_OPT} /W4 /WX - > - ${GSL_CPLUSPLUS_OPT} - $<$>: - -fno-strict-aliasing + $<$: + /wd4577 + /wd4702 + > + $<$: + -Weverything + -Wno-c++98-compat + -Wno-c++98-compat-pedantic + -Wno-missing-prototypes + -Wno-unknown-attributes + > + ) +else() + target_compile_options(gsl_tests_config_noexcept INTERFACE -fno-exceptions + -fno-strict-aliasing -Wall -Wcast-align -Wconversion -Wctor-dtor-privacy -Werror -Wextra - -Wno-missing-braces - -Wno-unknown-attributes - -Wnon-virtual-dtor - -Wold-style-cast - -Woverloaded-virtual -Wpedantic -Wshadow -Wsign-conversion - > -) + $<$,$>: + -Weverything + -Wno-c++98-compat + -Wno-c++98-compat-pedantic + -Wno-missing-prototypes + -Wno-unknown-attributes + -Wno-weak-vtables + > + ) +endif(MSVC) # set definitions for tests target_compile_definitions(gsl_tests_config_noexcept INTERFACE diff --git a/tests/multi_span_tests.cpp b/tests/multi_span_tests.cpp index 9c05cb4..7e3ec89 100644 --- a/tests/multi_span_tests.cpp +++ b/tests/multi_span_tests.cpp @@ -1782,4 +1782,4 @@ TEST_CASE("iterator") #ifdef CONFIRM_COMPILATION_ERRORS copy(src_span_static, dst_span_static); -#endif \ No newline at end of file +#endif diff --git a/tests/no_exception_ensure_tests.cpp b/tests/no_exception_ensure_tests.cpp index 3a7f007..b1ae15b 100644 --- a/tests/no_exception_ensure_tests.cpp +++ b/tests/no_exception_ensure_tests.cpp @@ -14,21 +14,17 @@ // /////////////////////////////////////////////////////////////////////////////// -#include // for std::exit -#include // for span +#include // for std::exit +#include // for span int operator_subscript_no_throw() noexcept { - int arr[10]; - const gsl::span sp { arr }; + int arr[10]; + const gsl::span sp{arr}; return sp[11]; } - -void test_terminate() -{ - std::exit(0); -} +[[noreturn]] void test_terminate() { std::exit(0); } void setup_termination_handler() noexcept { @@ -44,7 +40,6 @@ void setup_termination_handler() noexcept #endif } - int main() noexcept { setup_termination_handler(); diff --git a/tests/no_exception_throw_tests.cpp b/tests/no_exception_throw_tests.cpp index e9f4dac..b28ad00 100644 --- a/tests/no_exception_throw_tests.cpp +++ b/tests/no_exception_throw_tests.cpp @@ -14,20 +14,17 @@ // /////////////////////////////////////////////////////////////////////////////// -#include // for std::exit -#include // for narrow +#include // for std::exit #include // for get_terminate +#include // for narrow int narrow_no_throw() { const long long bigNumber = 0x0fffffffffffffff; - return gsl::narrow(bigNumber); + return gsl::narrow(bigNumber); } -void test_terminate() -{ - std::exit(0); -} +[[noreturn]] void test_terminate() { std::exit(0); } void setup_termination_handler() noexcept { @@ -43,7 +40,6 @@ void setup_termination_handler() noexcept #endif } - int main() { setup_termination_handler(); diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index ef767c6..ce5a123 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -251,7 +251,7 @@ TEST_CASE("TestNotNullostream") { ostream_helper(17); ostream_helper(21.5f); - ostream_helper(3.4566e-7f); + ostream_helper(3.4566e-7); ostream_helper('c'); ostream_helper(0x0123u); ostream_helper("cstring"); diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 9637a0e..d22dc08 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -37,9 +37,10 @@ #include // for integral_constant<>::value, is_default_co... #include // for vector -namespace gsl { +namespace gsl +{ struct fail_fast; -} // namespace gsl +} // namespace gsl using namespace std; using namespace gsl; @@ -54,9 +55,12 @@ struct DerivedClass : BaseClass }; struct AddressOverloaded { +#if (__cplusplus > 201402L) + [[maybe_unused]] +#endif AddressOverloaded operator&() const { return {}; } }; -} +} // namespace GSL_SUPPRESS(con.4) // NO-FORMAT: attribute TEST_CASE("default_constructor") @@ -513,8 +517,8 @@ TEST_CASE("from_std_array_constructor") static span s2; s2 = s1; - #if __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && __GNUC_PATCHLEVEL__ == 0 && \ - defined(__OPTIMIZE__) + #if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \ + __GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__) // Known to be broken in gcc 6.4 and 6.5 with optimizations // Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116 CHECK(s1.size() == 4); diff --git a/tests/strided_span_tests.cpp b/tests/strided_span_tests.cpp index 2310f5b..1563d90 100644 --- a/tests/strided_span_tests.cpp +++ b/tests/strided_span_tests.cpp @@ -117,7 +117,7 @@ TEST_CASE("strided_span_constructors") CHECK(sav.bounds().strides() == multi_span_index<1>{1}); CHECK(sav[1] == 2); -#if _MSC_VER > 1800 +#if defined(_MSC_VER) && _MSC_VER > 1800 // strided_span sav_c{ {src}, {2, 1} }; strided_span sav_c{multi_span{src}, strided_bounds<1>{2, 1}}; @@ -129,7 +129,7 @@ TEST_CASE("strided_span_constructors") CHECK(sav_c.bounds().strides() == multi_span_index<1>{1}); CHECK(sav_c[1] == 2); -#if _MSC_VER > 1800 +#if defined(_MSC_VER) && _MSC_VER > 1800 strided_span sav_v{src, {2, 1}}; #else strided_span sav_v{multi_span{src}, @@ -139,7 +139,7 @@ TEST_CASE("strided_span_constructors") CHECK(sav_v.bounds().strides() == multi_span_index<1>{1}); CHECK(sav_v[1] == 2); -#if _MSC_VER > 1800 +#if defined(_MSC_VER) && _MSC_VER > 1800 strided_span sav_cv{src, {2, 1}}; #else strided_span sav_cv{multi_span{src}, @@ -159,7 +159,7 @@ TEST_CASE("strided_span_constructors") CHECK(sav_c.bounds().strides() == multi_span_index<1>{1}); CHECK(sav_c[1] == 2); -#if _MSC_VER > 1800 +#if defined(_MSC_VER) && _MSC_VER > 1800 strided_span sav_cv{src, {2, 1}}; #else strided_span sav_cv{multi_span{src}, @@ -180,7 +180,7 @@ TEST_CASE("strided_span_constructors") CHECK(sav_v.bounds().strides() == multi_span_index<1>{1}); CHECK(sav_v[1] == 2); -#if _MSC_VER > 1800 +#if defined(_MSC_VER) && _MSC_VER > 1800 strided_span sav_cv{src, {2, 1}}; #else strided_span sav_cv{multi_span{src}, @@ -598,7 +598,7 @@ void iterate_every_other_element(multi_span av) // pick every other element auto length = av.size() / 2; -#if _MSC_VER > 1800 +#if defined(_MSC_VER) && _MSC_VER > 1800 auto bounds = strided_bounds<1>({length}, {2}); #else auto bounds = strided_bounds<1>(multi_span_index<1>{length}, multi_span_index<1>{2}); diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index 5cacd97..3d54ce6 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -80,7 +80,7 @@ TEST_CASE("finally_function_with_bind") CHECK(i == 1); } -int j = 0; +static int j = 0; void g() { j += 1; } TEST_CASE("finally_function_ptr") { From 7d78b743e43ecba06ca47426d03d9d16076dec16 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Wed, 16 Jan 2019 19:58:38 -0800 Subject: [PATCH 6/6] added clang7.0 to Travis configuration and README (#763) --- .travis.yml | 22 ++++++++++++++++++++++ README.md | 6 +++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d583eb9..f3dbaab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -163,6 +163,28 @@ matrix: - env: COMPILER=clang++-6.0 BUILD_TYPE=Release GSL_CXX_STANDARD=17 addons: *clang60 + # Clang 7.0 + - env: COMPILER=clang++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14 + addons: &clang70 + apt: + packages: + - clang-7 + - g++-7 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-7 + + + - env: COMPILER=clang++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=14 + addons: *clang70 + + # Clang 7.0 c++17 + - env: COMPILER=clang++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=17 + addons: *clang70 + + - env: COMPILER=clang++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=17 + addons: *clang70 + ########################################################################## # GCC on Linux ########################################################################## diff --git a/README.md b/README.md index db7d406..183553f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,11 @@ The test suite that exercises GSL has been built and passes successfully on the * Windows using Clang/LLVM 7.0.0 * Windows using GCC 5.1 * Windows using Intel C++ Compiler 18.0 -* GNU/Linux using Clang/LLVM 3.6 +* GNU/Linux using Clang/LLVM 3.6-3.9 +* GNU/Linux using Clang/LLVM 4.0 +* GNU/Linux using Clang/LLVM 5.0 +* GNU/Linux using Clang/LLVM 6.0 +* GNU/Linux using Clang/LLVM 7.0 * GNU/Linux using GCC 5.1 * OS X Yosemite using Xcode with Apple Clang 7.0.0.7000072 * OS X Yosemite using GCC-5.2.0