diff --git a/.clang-tidy b/.clang-tidy index 9df0b48a0..6be676c21 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -9,6 +9,7 @@ Checks: > cppcoreguidelines-*, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-owning-memory, -cppcoreguidelines-pro-bounds-array-to-pointer-decay, -cppcoreguidelines-pro-bounds-constant-array-index, -cppcoreguidelines-pro-bounds-pointer-arithmetic, diff --git a/.github/workflows/sonarcloud.yaml b/.github/workflows/sonarcloud.yaml index 6572fc0e6..c81078dd7 100644 --- a/.github/workflows/sonarcloud.yaml +++ b/.github/workflows/sonarcloud.yaml @@ -44,7 +44,7 @@ jobs: for f in build/tests/individual/*; do echo "Testing $f"; ./$f; done - name: Collect coverage into one XML report - run: gcovr --sonarqube > coverage.xml + run: gcovr --exclude-unreachable-branches --exclude-noncode-lines --sonarqube > coverage.xml - name: Run sonar-scanner env: diff --git a/src/util/demangle.cpp b/src/util/demangle.cpp index 2d54e3c6f..fd6ed6480 100644 --- a/src/util/demangle.cpp +++ b/src/util/demangle.cpp @@ -112,10 +112,19 @@ namespace util { */ std::string demangle(const char* symbol) { + if (symbol == nullptr) { + return {}; + } + int status = -1; - const std::unique_ptr res{abi::__cxa_demangle(symbol, nullptr, nullptr, &status), - std::free}; - if (status == 0) { + const std::unique_ptr res{abi::__cxa_demangle(symbol, nullptr, nullptr, &status), + [](char* ptr) { + // The API for __cxa_demangle REQUIRES us to call free + // No choice here so suppress the linter + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + std::free(ptr); // NOSONAR + }}; + if (res != nullptr) { std::string demangled = res.get(); demangled = std::regex_replace(demangled, std::regex(R"(\s+)"), ""); return demangled; diff --git a/tests/util/demangle.cpp b/tests/util/demangle.cpp index 3c3a897eb..955f63ad0 100644 --- a/tests/util/demangle.cpp +++ b/tests/util/demangle.cpp @@ -72,6 +72,18 @@ SCENARIO("Test the demangle function correctly demangles symbols", "[util][deman } } + GIVEN("A nullptr as the symbol") { + const char* symbol = nullptr; + + WHEN("Demangle is called") { + std::string result = NUClear::util::demangle(symbol); + + THEN("It should return an empty string") { + REQUIRE(result.empty()); + } + } + } + GIVEN("A symbol from a struct") { const char* symbol = typeid(TestSymbol).name(); const std::string expected = "TestSymbol";