From 43a88b56afd9224d2810d9b6d22004e137dc02e6 Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Wed, 14 Sep 2022 14:24:16 -0400 Subject: clang-tidy module: add check for cmStrLen() Co-Authored-by: Joe Blaauboer --- Utilities/ClangTidyModule/CMakeLists.txt | 3 +++ Utilities/ClangTidyModule/Module.cxx | 4 ++- Utilities/ClangTidyModule/UseCmstrlenCheck.cxx | 34 ++++++++++++++++++++++++++ Utilities/ClangTidyModule/UseCmstrlenCheck.h | 21 ++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 Utilities/ClangTidyModule/UseCmstrlenCheck.cxx create mode 100644 Utilities/ClangTidyModule/UseCmstrlenCheck.h diff --git a/Utilities/ClangTidyModule/CMakeLists.txt b/Utilities/ClangTidyModule/CMakeLists.txt index 8443d9e..6be13d6 100644 --- a/Utilities/ClangTidyModule/CMakeLists.txt +++ b/Utilities/ClangTidyModule/CMakeLists.txt @@ -13,6 +13,9 @@ find_package(Clang REQUIRED) add_library(cmake-clang-tidy-module MODULE Module.cxx + + UseCmstrlenCheck.cxx + UseCmstrlenCheck.h ) target_include_directories(cmake-clang-tidy-module PRIVATE ${CLANG_INCLUDE_DIRS}) target_link_libraries(cmake-clang-tidy-module PRIVATE clang-tidy) diff --git a/Utilities/ClangTidyModule/Module.cxx b/Utilities/ClangTidyModule/Module.cxx index 4bb6dc0..a35c336 100644 --- a/Utilities/ClangTidyModule/Module.cxx +++ b/Utilities/ClangTidyModule/Module.cxx @@ -3,6 +3,8 @@ #include #include +#include "UseCmstrlenCheck.h" + namespace clang { namespace tidy { namespace cmake { @@ -11,7 +13,7 @@ class CMakeClangTidyModule : public ClangTidyModule public: void addCheckFactories(ClangTidyCheckFactories& CheckFactories) override { - // TODO + CheckFactories.registerCheck("cmake-use-cmstrlen"); } }; diff --git a/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx b/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx new file mode 100644 index 0000000..590d260 --- /dev/null +++ b/Utilities/ClangTidyModule/UseCmstrlenCheck.cxx @@ -0,0 +1,34 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "UseCmstrlenCheck.h" + +#include + +namespace clang { +namespace tidy { +namespace cmake { +using namespace ast_matchers; + +UseCmstrlenCheck::UseCmstrlenCheck(StringRef Name, ClangTidyContext* Context) + : ClangTidyCheck(Name, Context) +{ +} + +void UseCmstrlenCheck::registerMatchers(MatchFinder* Finder) +{ + Finder->addMatcher(callExpr(callee(functionDecl(hasName("::strlen"))), + callee(expr().bind("callee")), + hasArgument(0, stringLiteral())), + this); +} + +void UseCmstrlenCheck::check(const MatchFinder::MatchResult& Result) +{ + const Expr* Node = Result.Nodes.getNodeAs("callee"); + + this->diag(Node->getBeginLoc(), "use cmStrLen() for string literals") + << FixItHint::CreateReplacement(Node->getSourceRange(), "cmStrLen"); +} +} +} +} diff --git a/Utilities/ClangTidyModule/UseCmstrlenCheck.h b/Utilities/ClangTidyModule/UseCmstrlenCheck.h new file mode 100644 index 0000000..08f77c2 --- /dev/null +++ b/Utilities/ClangTidyModule/UseCmstrlenCheck.h @@ -0,0 +1,21 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include +#include + +namespace clang { +namespace tidy { +namespace cmake { +class UseCmstrlenCheck : public ClangTidyCheck +{ +public: + UseCmstrlenCheck(StringRef Name, ClangTidyContext* Context); + void registerMatchers(ast_matchers::MatchFinder* Finder) override; + + void check(const ast_matchers::MatchFinder::MatchResult& Result) override; +}; +} +} +} -- cgit v0.12 From 43481a77f9eaffa4b15a24fa22e82201bf8cc210 Mon Sep 17 00:00:00 2001 From: Sean Orner Date: Wed, 19 Oct 2022 17:29:46 -0400 Subject: clang-tidy module: add test for cmStrLen() check --- Utilities/ClangTidyModule/Tests/CMakeLists.txt | 2 ++ .../Tests/cmake-use-cmstrlen-fixit.cxx | 37 ++++++++++++++++++++++ .../Tests/cmake-use-cmstrlen-stderr.txt | 2 ++ .../Tests/cmake-use-cmstrlen-stdout.txt | 20 ++++++++++++ .../ClangTidyModule/Tests/cmake-use-cmstrlen.cxx | 37 ++++++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx create mode 100644 Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt create mode 100644 Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt create mode 100644 Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx diff --git a/Utilities/ClangTidyModule/Tests/CMakeLists.txt b/Utilities/ClangTidyModule/Tests/CMakeLists.txt index 3700fb6..42027ed 100644 --- a/Utilities/ClangTidyModule/Tests/CMakeLists.txt +++ b/Utilities/ClangTidyModule/Tests/CMakeLists.txt @@ -9,3 +9,5 @@ function(add_run_clang_tidy_test check_name) -P "${CMAKE_CURRENT_SOURCE_DIR}/RunClangTidy.cmake" ) endfunction() + +add_run_clang_tidy_test(cmake-use-cmstrlen) diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx new file mode 100644 index 0000000..c93d557 --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-fixit.cxx @@ -0,0 +1,37 @@ +#include + +template +constexpr size_t cmStrLen(const char (&/*str*/)[N]) +{ + return N - 1; +} + +namespace ns1 { +using std::strlen; +} + +namespace ns2 { +std::size_t strlen(const char* str) +{ + return std::strlen(str); +} +} + +int main() +{ + // String variable used for calling strlen() on a variable + auto s0 = "howdy"; + + // Correction needed + (void)cmStrLen("Hello"); + (void)cmStrLen("Goodbye"); + (void)cmStrLen("Hola"); + (void)cmStrLen("Bonjour"); + + // No correction needed + (void)ns2::strlen("Salve"); + (void)cmStrLen("Konnichiwa"); + (void)strlen(s0); + + return 0; +} diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt new file mode 100644 index 0000000..9d9d2ed --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt @@ -0,0 +1,2 @@ +4 warnings generated. +clang-tidy applied 4 of 4 suggested fixes. diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt new file mode 100644 index 0000000..6c52ad5 --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stdout.txt @@ -0,0 +1,20 @@ +cmake-use-cmstrlen.cxx:26:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen] + (void)strlen("Hello"); + ^~~~~~ + cmStrLen +cmake-use-cmstrlen.cxx:26:9: note: FIX-IT applied suggested code changes +cmake-use-cmstrlen.cxx:27:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen] + (void)::strlen("Goodbye"); + ^~~~~~~~ + cmStrLen +cmake-use-cmstrlen.cxx:27:9: note: FIX-IT applied suggested code changes +cmake-use-cmstrlen.cxx:28:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen] + (void)std::strlen("Hola"); + ^~~~~~~~~~~ + cmStrLen +cmake-use-cmstrlen.cxx:28:9: note: FIX-IT applied suggested code changes +cmake-use-cmstrlen.cxx:29:9: warning: use cmStrLen() for string literals [cmake-use-cmstrlen] + (void)ns1::strlen("Bonjour"); + ^~~~~~~~~~~ + cmStrLen +cmake-use-cmstrlen.cxx:29:9: note: FIX-IT applied suggested code changes diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx new file mode 100644 index 0000000..f36262b --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen.cxx @@ -0,0 +1,37 @@ +#include + +template +constexpr size_t cmStrLen(const char (&/*str*/)[N]) +{ + return N - 1; +} + +namespace ns1 { +using std::strlen; +} + +namespace ns2 { +std::size_t strlen(const char* str) +{ + return std::strlen(str); +} +} + +int main() +{ + // String variable used for calling strlen() on a variable + auto s0 = "howdy"; + + // Correction needed + (void)strlen("Hello"); + (void)::strlen("Goodbye"); + (void)std::strlen("Hola"); + (void)ns1::strlen("Bonjour"); + + // No correction needed + (void)ns2::strlen("Salve"); + (void)cmStrLen("Konnichiwa"); + (void)strlen(s0); + + return 0; +} -- cgit v0.12 From b4e8ddbc2fb2c8f40b40502cc4a79c79bcec5386 Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Mon, 17 Oct 2022 14:28:48 -0400 Subject: clang-tidy: enable cmStrLen() check and fix violations --- .clang-tidy | 1 + Source/cmGeneratorTarget.cxx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index a86f39a..1e9b78a 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -33,6 +33,7 @@ readability-*,\ -readability-redundant-member-init,\ -readability-suspicious-call-argument,\ -readability-uppercase-literal-suffix,\ +cmake-*,\ " HeaderFilterRegex: 'Source/cm[^/]*\.(h|hxx|cxx)$' CheckOptions: diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 6195d1f..321122a 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5532,7 +5532,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const } else if (cmHasLiteralPrefix(*location, "Resources/")) { flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource; if (stripResources) { - flags.MacFolder += strlen("Resources/"); + flags.MacFolder += cmStrLen("Resources/"); } } else { flags.Type = cmGeneratorTarget::SourceFileTypeMacContent; -- cgit v0.12