diff --git a/cfg/std.cfg b/cfg/std.cfg index c0d1ead2f..05a060377 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -8486,6 +8486,37 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + + + + false + + + 0: + + + + + + false + + + 0: + + + + + + false + + + 0: + + + + 0: + + malloc calloc @@ -8700,6 +8731,13 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + + + + + + + @@ -8747,6 +8785,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init std::ios_base::failure std::filesystem::filesystem_error std::bad_variant_access + std::span std::mutex diff --git a/test/cfg/runtests.sh b/test/cfg/runtests.sh index 6ffc4a521..887e29a57 100755 --- a/test/cfg/runtests.sh +++ b/test/cfg/runtests.sh @@ -27,7 +27,7 @@ CPPCHECK_OPT='--check-library --platform=unix64 --enable=style --error-exitcode= # Compiler settings CXX=g++ -CXX_OPT='-fsyntax-only -std=c++17 -Wno-format -Wno-format-security -Wno-deprecated-declarations' +CXX_OPT='-fsyntax-only -std=c++2a -Wno-format -Wno-format-security -Wno-deprecated-declarations' CC=gcc CC_OPT='-Wno-format -Wno-stringop-overread -Wno-nonnull -Wno-implicit-function-declaration -Wno-deprecated-declarations -Wno-format-security -Wno-nonnull -fsyntax-only' diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp index 3afe3d80c..64788f85d 100644 --- a/test/cfg/std.cpp +++ b/test/cfg/std.cpp @@ -39,6 +39,10 @@ #include #include #include +#include +#ifdef __cpp_lib_span +#include +#endif int zerodiv_ldexp() { @@ -4562,4 +4566,43 @@ void string_view_unused(std::string_view v) { // cppcheck-suppress ignoredReturnValue v.substr(1, 3); +} + +void stdspan() +{ +#ifndef __cpp_lib_span +#warning "This compiler does not support std::span" +#else + std::vector vec{1,2,3,4}; + std::span spn{vec}; + // cppcheck-suppress unreadVariable + std::span spn2 = spn; + + spn.begin(); + spn.end(); + spn.rbegin(); + spn.end(); + + spn.front(); + spn.back(); + //cppcheck-suppress constStatement + spn[0]; + spn.data(); + spn.size(); + spn.size_bytes(); + spn.empty(); + //cppcheck-suppress ignoredReturnValue + spn.first(2); + //cppcheck-suppress ignoredReturnValue + spn.last(2); + //cppcheck-suppress ignoredReturnValue + spn.subspan(1, 2); + spn.subspan<1>(); + + static constexpr std::array arr{1, 2}; + constexpr std::span spn3{arr}; + spn3.first<1>(); + spn3.last<1>(); + spn3.subspan<1, 1>(); + #endif } \ No newline at end of file diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index b4d3fad8b..a76d4e3b0 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2799,6 +2799,91 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2] -> [test.cpp:3]: (error) Using object that is a temporary.\n", errout.str()); + + check("std::span f() {\n" + " std::vector v{};\n" + " return v;\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning object that points to local variable 'v' that will be invalid when returning.\n", + errout.str()); + + check("std::span f() {\n" + " std::vector v;\n" + " std::span sp = v;\n" + " return sp;\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (error) Returning object that points to local variable 'v' that will be invalid when returning.\n", + errout.str()); + + check("std::span f() {\n" + " std::vector v;\n" + " return std::span{v};\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:3] -> [test.cpp:2] -> [test.cpp:3]: (error) Returning object that points to local variable 'v' that will be invalid when returning.\n", + errout.str()); + + check("int f() {\n" + " std::span s;\n" + " {\n" + " std::vector v(1);" + " s = v;\n" + " }\n" + "return s.back()\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4] -> [test.cpp:4] -> [test.cpp:6]: (error) Using object that points to local variable 'v' that is out of scope.\n", + errout.str()); + + check("int f() {\n" + " std::span s;\n" + " {\n" + " std::vector v(1);" + " s = v;\n" + " }\n" + "return s.back()\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4] -> [test.cpp:4] -> [test.cpp:6]: (error) Using object that points to local variable 'v' that is out of scope.\n", + errout.str()); + + check("int f() {\n" + " std::span s;\n" + " {\n" + " std::vector v(1);" + " s = v;\n" + " }\n" + "return s.front()\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4] -> [test.cpp:4] -> [test.cpp:6]: (error) Using object that points to local variable 'v' that is out of scope.\n", + errout.str()); + + check("int f() {\n" + " std::span s;\n" + " {\n" + " std::vector v(1);" + " s = v;\n" + " }\n" + "return s.last(1)\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4] -> [test.cpp:4] -> [test.cpp:6]: (error) Using object that points to local variable 'v' that is out of scope.\n", + errout.str()); + + check("int f() {\n" + " std::span s;\n" + " {\n" + " std::vector v(1);" + " s = v;\n" + " }\n" + "return s.first(1)\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:4] -> [test.cpp:4] -> [test.cpp:6]: (error) Using object that points to local variable 'v' that is out of scope.\n", + errout.str()); } void danglingLifetimeUniquePtr()