diff options
author | dmitrykobets-msft <89153909+dmitrykobets-msft@users.noreply.github.com> | 2021-12-10 01:54:06 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-10 01:54:06 +0300 |
commit | bcf008ae5578fab638e6d30b7ca000f306b14d3b (patch) | |
tree | ca03dd9416ffe92aa6ef1511e3142c25fccb526f | |
parent | e0880931ae5885eb988d1a8a57acf8bc2b8dacda (diff) |
Fix/implement C++2020 compilation, tests, and CI (#1017)
* Fix C++20 bugs and tests
* Rework CI for C++2020 tests
* Update readme compiler versions
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | azure-pipelines.yml | 6 | ||||
-rw-r--r-- | include/gsl/util | 6 | ||||
-rw-r--r-- | pipelines/jobs.yml | 35 | ||||
-rw-r--r-- | pipelines/steps.yml | 6 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 11 | ||||
-rw-r--r-- | tests/algorithm_tests.cpp | 5 | ||||
-rw-r--r-- | tests/at_tests.cpp | 20 | ||||
-rw-r--r-- | tests/span_compatibility_tests.cpp | 6 | ||||
-rw-r--r-- | tests/span_ext_tests.cpp | 36 | ||||
-rw-r--r-- | tests/span_tests.cpp | 3 | ||||
-rw-r--r-- | tests/string_span_tests.cpp | 1 |
12 files changed, 80 insertions, 67 deletions
@@ -86,16 +86,14 @@ This is based on [CppCoreGuidelines semi-specification](https://github.com/isocp # Quick Start ## Supported Compilers -The GSL officially supports the current and previous major release of MSVC, GCC, Clang, and XCode's Apple-Clang. -See our latest test results for the most up-to-date list of supported configurations. +The GSL officially supports the following versions of MSVC, GCC, Clang, and XCode's Apple-Clang. Compiler |Toolset Versions Currently Tested :------- |--: - XCode |11.4 & 10.3 - GCC |9 & 8 - Clang |11 & 10 - Visual Studio with MSVC | VS2017 (15.9) & VS2019 (16.4) - Visual Studio with LLVM | VS2017 (Clang 9) & VS2019 (Clang 10) + XCode | 12.4 & 11.3 + GCC | 9.3.0 & 7.5.0 + Clang | 11.0.0 & 9.0.0 + Visual Studio with MSVC | VS2017 (15.9.21) & VS2019 (16.11.2) --- If you successfully port GSL to another platform, we would love to hear from you! diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0d1219a..8ab761e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,10 +18,12 @@ stages: parameters: jobName: 'Validate GCC latest' imageName: ubuntu-20.04 + CXXVersions: [ 14, 17 ] - template: ./pipelines/jobs.yml parameters: jobName: 'Validate GCC Previous' imageName: ubuntu-18.04 + CXXVersions: [ 14, 17 ] # Clang - stage: Clang @@ -40,6 +42,7 @@ stages: parameters: jobName: 'Validate Clang Previous' imageName: ubuntu-18.04 + CXXVersions: [ 14, 17 ] # MSVC - stage: MSVC @@ -53,6 +56,7 @@ stages: parameters: jobName: 'Validate MSVC Previous' imageName: vs2017-win2016 + CXXVersions: [ 14, 17 ] # Apple-Clang - stage: Apple_Clang @@ -62,7 +66,9 @@ stages: parameters: jobName: 'Validate Apple-Clang latest' imageName: macos-10.15 + CXXVersions: [ 14, 17 ] - template: ./pipelines/jobs.yml parameters: jobName: 'Validate Apple-Clang Previous' imageName: macos-10.14 + CXXVersions: [ 14, 17 ] diff --git a/include/gsl/util b/include/gsl/util index 330b996..a215bad 100644 --- a/include/gsl/util +++ b/include/gsl/util @@ -143,10 +143,10 @@ GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute #if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L template <class T, size_t extent = std::dynamic_extent> -constexpr auto at(std::span<T, extent> sp, const index i) +constexpr auto at(std::span<T, extent> sp, const index i) -> decltype(sp[sp.size()]) { - Expects(i >= 0 && i < narrow_cast<i>(sp.size())); - return sp[i]; + Expects(i >= 0 && i < narrow_cast<index>(sp.size())); + return sp[gsl::narrow_cast<size_t>(i)]; } #endif // __cpp_lib_span >= 202002L } // namespace gsl diff --git a/pipelines/jobs.yml b/pipelines/jobs.yml index dad2414..783c46d 100644 --- a/pipelines/jobs.yml +++ b/pipelines/jobs.yml @@ -1,26 +1,19 @@ parameters:
jobName: ''
imageName: ''
+ CXXVersions: [ 14, 17, 20 ]
+ buildTypes: [ 'Debug', 'Release' ]
jobs:
-- job:
- displayName: ${{ parameters.imageName }}
- pool:
- vmImage: ${{ parameters.imageName }}
- strategy:
- matrix:
- 14_debug:
- GSL_CXX_STANDARD: '14'
- BUILD_TYPE: 'Debug'
- 14_release:
- GSL_CXX_STANDARD: '14'
- BUILD_TYPE: 'Release'
- 17_debug:
- GSL_CXX_STANDARD: '17'
- BUILD_TYPE: 'Debug'
- 17_release:
- GSL_CXX_STANDARD: '17'
- BUILD_TYPE: 'Release'
- continueOnError: false
- steps:
- - template: ./steps.yml
+- ${{ each CXXVersion in parameters.CXXVersions }}:
+ - ${{ each buildType in parameters.buildTypes }}:
+ - job:
+ displayName: ${{ format('{0} {1} C++{2}', parameters.imageName, buildType, CXXVersion) }}
+ pool:
+ vmImage: ${{ parameters.imageName }}
+ continueOnError: false
+ steps:
+ - template: ./steps.yml
+ parameters:
+ buildType: ${{ buildType }}
+ CXXVersion: ${{ CXXVersion }}
diff --git a/pipelines/steps.yml b/pipelines/steps.yml index 41a7fca..2e80713 100644 --- a/pipelines/steps.yml +++ b/pipelines/steps.yml @@ -1,9 +1,13 @@ +parameters:
+ buildType: ''
+ CXXVersion: ''
+
steps:
- task: CMake@1
name: Configure
inputs:
workingDirectory: build
- cmakeArgs: '-DCMAKE_CXX_STANDARD=$(GSL_CXX_STANDARD) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -Werror=dev .. '
+ cmakeArgs: '-DGSL_CXX_STANDARD=${{ parameters.CXXVersion }} -DCMAKE_BUILD_TYPE=${{ parameters.buildType }} -DCI_TESTING:BOOL=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -Werror=dev .. '
- task: CMake@1
name: Build
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c05aaa7..dd71105 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,6 +9,10 @@ include(ExternalProject) # will make visual studio generated project group files set_property(GLOBAL PROPERTY USE_FOLDERS ON) +if(CI_TESTING AND GSL_CXX_STANDARD EQUAL 20) + add_compile_definitions(FORCE_STD_SPAN_TESTS=1) +endif() + if(IOS) add_compile_definitions(GTEST_HAS_DEATH_TEST=1 IOS_PROCESS_DELAY_WORKAROUND=1) endif() @@ -54,7 +58,7 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) find_package(Microsoft.GSL REQUIRED) endif() -if (MSVC AND (GSL_CXX_STANDARD EQUAL 17)) +if (MSVC AND (GSL_CXX_STANDARD GREATER_EQUAL 17)) set(GSL_CPLUSPLUS_OPT -Zc:__cplusplus -permissive-) endif() @@ -135,6 +139,11 @@ else() $<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>: $<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template> > + $<$<AND:$<EQUAL:${GSL_CXX_STANDARD},20>,$<CXX_COMPILER_VERSION:11.0.0>>: + -Wno-zero-as-null-pointer-constant # failing Clang Ubuntu 20.04 tests, seems to be a bug with clang 11.0.0 + # (operator< is being re-written by the compiler as operator<=> and + # raising the warning) + > > $<$<CXX_COMPILER_ID:AppleClang>: $<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,9.1>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,10>>: diff --git a/tests/algorithm_tests.cpp b/tests/algorithm_tests.cpp index 16746b4..e369be0 100644 --- a/tests/algorithm_tests.cpp +++ b/tests/algorithm_tests.cpp @@ -27,7 +27,6 @@ namespace gsl struct fail_fast; } // namespace gsl -using namespace std; using namespace gsl; TEST(algorithm_tests, same_type) @@ -73,8 +72,8 @@ TEST(algorithm_tests, same_type) std::array<int, 5> src{1, 2, 3, 4, 5}; std::array<int, 10> dst{}; - const span<int> src_span(src); - const span<int, 10> dst_span(dst); + const gsl::span<int> src_span(src); + const gsl::span<int, 10> dst_span(dst); copy(src_span, dst_span); copy(src_span, dst_span.subspan(src_span.size())); diff --git a/tests/at_tests.cpp b/tests/at_tests.cpp index 92a8e4d..93e6b7b 100644 --- a/tests/at_tests.cpp +++ b/tests/at_tests.cpp @@ -119,7 +119,7 @@ TEST(at_tests, InitializerList) EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), expected); } -#if defined(__cplusplus) && __cplusplus >= 202002L +#if defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L TEST(at_tests, std_span) { std::vector<int> vec{1, 2, 3, 4, 5}; @@ -128,18 +128,24 @@ TEST(at_tests, std_span) std::vector<int> cvec{1, 2, 3, 4, 5}; std::span csp{cvec}; - for (size_t i = 0, i < vec.size(); ++i) + for (gsl::index i = 0; i < gsl::narrow_cast<gsl::index>(vec.size()); ++i) { - EXPECT_TRUE(&gsl::at(sp, i) == &vec[i]); - EXPECT_TRUE(&gsl::at(csp, i) == &cvec[i]); + EXPECT_TRUE(&gsl::at(sp, i) == &vec[gsl::narrow_cast<size_t>(i)]); + EXPECT_TRUE(&gsl::at(csp, i) == &cvec[gsl::narrow_cast<size_t>(i)]); } + const auto terminateHandler = std::set_terminate([] { + std::cerr << "Expected Death. std_span"; + std::abort(); + }); + const auto expected = GetExpectedDeathString(terminateHandler); + EXPECT_DEATH(gsl::at(sp, -1), expected); - EXPECT_DEATH(gsl::at(sp, sp.size()), expected); + EXPECT_DEATH(gsl::at(sp, gsl::narrow_cast<gsl::index>(sp.size())), expected); EXPECT_DEATH(gsl::at(csp, -1), expected); - EXPECT_DEATH(gsl::at(csp, sp.size()), expected); + EXPECT_DEATH(gsl::at(csp, gsl::narrow_cast<gsl::index>(sp.size())), expected); } -#endif // __cplusplus >= 202002L +#endif // defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L #if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910 static constexpr bool test_constexpr() diff --git a/tests/span_compatibility_tests.cpp b/tests/span_compatibility_tests.cpp index 56bd385..95d8223 100644 --- a/tests/span_compatibility_tests.cpp +++ b/tests/span_compatibility_tests.cpp @@ -55,14 +55,14 @@ void ArrayConvertibilityCheck() EXPECT_TRUE(sp_const_nullptr_1.data() == stl_nullptr.data()); EXPECT_TRUE(sp_const_nullptr_1.size() == 3); - span<const T* const> sp_const_nullptr_2{std::as_const(stl_nullptr)}; + gsl::span<const T* const> sp_const_nullptr_2{std::as_const(stl_nullptr)}; EXPECT_TRUE(sp_const_nullptr_2.data() == stl_nullptr.data()); EXPECT_TRUE(sp_const_nullptr_2.size() == 3); - static_assert(std::is_same<decltype(span{stl_nullptr}), span<T*, 3>>::value, + static_assert(std::is_same<decltype(gsl::span{stl_nullptr}), gsl::span<T*, 3>>::value, "std::is_same< decltype(span{stl_nullptr}), span<T*, 3>>::value"); static_assert( - std::is_same<decltype(span{std::as_const(stl_nullptr)}), span<T* const, 3>>::value, + std::is_same<decltype(gsl::span{std::as_const(stl_nullptr)}), gsl::span<T* const, 3>>::value, "std::is_same< decltype(span{std::as_const(stl_nullptr)}), span<T* const, " "3>>::value"); } diff --git a/tests/span_ext_tests.cpp b/tests/span_ext_tests.cpp index 7ce4e51..3d35f8f 100644 --- a/tests/span_ext_tests.cpp +++ b/tests/span_ext_tests.cpp @@ -48,7 +48,7 @@ TEST(span_ext_test, make_span_from_pointer_length_constructor) {
int* p = nullptr;
- auto s = make_span(p, narrow_cast<span<int>::size_type>(0));
+ auto s = make_span(p, narrow_cast<gsl::span<int>::size_type>(0));
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
}
@@ -136,9 +136,9 @@ TEST(span_ext_test, make_span_from_std_array_constructor) // This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590
{
- span<int> s1 = make_span(arr);
+ gsl::span<int> s1 = make_span(arr);
- static span<int> s2;
+ static gsl::span<int> s2;
s2 = s1;
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
@@ -194,7 +194,7 @@ TEST(span_ext_test, make_span_from_container_constructor) TEST(span_test, interop_with_gsl_at)
{
int arr[5] = {1, 2, 3, 4, 5};
- span<int> s{arr};
+ gsl::span<int> s{arr};
EXPECT_TRUE(at(s, 0) == 1);
EXPECT_TRUE(at(s, 1) == 2);
}
@@ -202,7 +202,7 @@ TEST(span_test, interop_with_gsl_at) TEST(span_ext_test, iterator_free_functions)
{
int a[] = {1, 2, 3, 4};
- span<int> s{a};
+ gsl::span<int> s{a};
EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value));
@@ -232,7 +232,7 @@ TEST(span_ext_test, iterator_free_functions) TEST(span_ext_test, ssize_free_function)
{
int a[] = {1, 2, 3, 4};
- span<int> s{a};
+ gsl::span<int> s{a};
EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s)));
@@ -242,8 +242,8 @@ TEST(span_ext_test, ssize_free_function) TEST(span_ext_test, comparison_operators)
{
{
- span<int> s1;
- span<int> s2;
+ gsl::span<int> s1;
+ gsl::span<int> s2;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
@@ -260,8 +260,8 @@ TEST(span_ext_test, comparison_operators) {
int arr[] = {2, 1};
- span<int> s1 = arr;
- span<int> s2 = arr;
+ gsl::span<int> s1 = arr;
+ gsl::span<int> s2 = arr;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
@@ -280,8 +280,8 @@ TEST(span_ext_test, comparison_operators) {
int arr[] = {2, 1}; // bigger
- span<int> s1;
- span<int> s2 = arr;
+ gsl::span<int> s1;
+ gsl::span<int> s2 = arr;
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
@@ -300,8 +300,8 @@ TEST(span_ext_test, comparison_operators) {
int arr1[] = {1, 2};
int arr2[] = {1, 2};
- span<int> s1 = arr1;
- span<int> s2 = arr2;
+ gsl::span<int> s1 = arr1;
+ gsl::span<int> s2 = arr2;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
@@ -320,8 +320,8 @@ TEST(span_ext_test, comparison_operators) {
int arr[] = {1, 2, 3};
- span<int> s1 = {&arr[0], 2}; // shorter
- span<int> s2 = arr; // longer
+ gsl::span<int> s1 = {&arr[0], 2}; // shorter
+ gsl::span<int> s2 = arr; // longer
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
@@ -341,8 +341,8 @@ TEST(span_ext_test, comparison_operators) int arr1[] = {1, 2}; // smaller
int arr2[] = {2, 1}; // bigger
- span<int> s1 = arr1;
- span<int> s2 = arr2;
+ gsl::span<int> s1 = arr1;
+ gsl::span<int> s2 = arr2;
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 1e0222e..33ccf56 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -43,7 +43,6 @@ #include "deathTestCommon.h" -using namespace std; using namespace gsl; namespace @@ -1085,7 +1084,7 @@ TEST(span_test, as_bytes) int b[5] = {1, 2, 3, 4, 5}; { - span<int> sp(begin(b), static_cast<size_t>(-2)); + span<int> sp(std::begin(b), static_cast<size_t>(-2)); EXPECT_DEATH((void) sp.size_bytes(), expected); } } diff --git a/tests/string_span_tests.cpp b/tests/string_span_tests.cpp index ed42b38..45a67d9 100644 --- a/tests/string_span_tests.cpp +++ b/tests/string_span_tests.cpp @@ -30,7 +30,6 @@ #include "deathTestCommon.h" -using namespace std; using namespace gsl; // Generic string functions |