diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index dddce1e6518..1ae4e13eda5 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1964,26 +1964,28 @@ void CppCheck::analyseClangTidy(const FileSettings &fileSettings) const std::string errorString = line.substr(endErrorPos, line.length()); std::string fixedpath = Path::simplifyPath(line.substr(0, endNamePos)); + fixedpath = Path::toNativeSeparators(std::move(fixedpath)); const auto lineNumber = strToInt(lineNumString); const auto column = strToInt(columnNumString); - fixedpath = Path::toNativeSeparators(std::move(fixedpath)); ErrorMessage errmsg; errmsg.callStack.emplace_back(fixedpath, lineNumber, column); - - errmsg.id = "clang-tidy-" + errorString.substr(1, errorString.length() - 2); - if (errmsg.id.find("performance") != std::string::npos) - errmsg.severity = Severity::performance; - else if (errmsg.id.find("portability") != std::string::npos) - errmsg.severity = Severity::portability; - else if (errmsg.id.find("cert") != std::string::npos || errmsg.id.find("misc") != std::string::npos || errmsg.id.find("unused") != std::string::npos) - errmsg.severity = Severity::warning; - else - errmsg.severity = Severity::style; - errmsg.file0 = std::move(fixedpath); errmsg.setmsg(trim(messageString)); - mErrorLogger.reportErr(errmsg); + + for (const auto& id : splitString(errorString.substr(1, errorString.length() - 2), ',')) { + errmsg.id = "clang-tidy-" + id; + if (errmsg.id.find("performance") != std::string::npos) + errmsg.severity = Severity::performance; + else if (errmsg.id.find("portability") != std::string::npos) + errmsg.severity = Severity::portability; + else if (errmsg.id.find("cert") != std::string::npos || errmsg.id.find("misc") != std::string::npos || errmsg.id.find("unused") != std::string::npos) + errmsg.severity = Severity::warning; + else + errmsg.severity = Severity::style; + + mErrorLogger.reportErr(errmsg); + } } } diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 78d4c1ca679..31b1e27b97c 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -3463,6 +3463,44 @@ def test_clang_tidy_project(tmpdir): __test_clang_tidy(tmpdir, True) +@pytest.mark.skipif(not has_clang_tidy, reason='clang-tidy is not available') +def test_clang_tidy_error_exit(tmp_path): # #13828 + test_file = tmp_path / 'test.cpp' + with open(test_file, 'wt') as f: + f.write( +"""#include +#include + +// cppcheck-suppress clang-tidy-modernize-use-trailing-return-type +static bool f() // NOLINT(misc-use-anonymous-namespace) +{ + std::string str; + const std::string str1 = std::move(str); + (void)str1; + return str.empty(); +}""") + + # TODO: remove project file usage when --clang-tidy works with non-project files + project_file = __write_compdb(tmp_path, str(test_file)) + + args = [ + '-q', + '--template=simple', + '--inline-suppr', + '--std=c++11', + '--clang-tidy', + '--project={}'.format(project_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert stdout.splitlines() == [] + assert stderr.splitlines() == [ + "{}:10:12: style: 'str' used after it was moved [clang-tidy-bugprone-use-after-move]".format(test_file), + "{}:10:12: style: 'str' used after it was moved [clang-tidy-hicpp-invalid-access-moved]".format(test_file) + ] + assert exitcode == 0, stdout + + def test_suppress_unmatched_wildcard(tmp_path): # #13660 test_file = tmp_path / 'test.c' with open(test_file, 'wt') as f: