diff options
author | Brad King <brad.king@kitware.com> | 2022-11-07 13:53:28 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2022-11-07 13:53:45 (GMT) |
commit | e232e1bed3143c132f707bfe9efaa9c62cca2f04 (patch) | |
tree | 4aa362576543300bc5dcd809c36a8188e60e552b | |
parent | 4e047870bc5ec2564e8b76d5565ecb6b17929bc3 (diff) | |
parent | ffa970559ca7db3d069a9f31375d216ac7e19774 (diff) | |
download | CMake-e232e1bed3143c132f707bfe9efaa9c62cca2f04.zip CMake-e232e1bed3143c132f707bfe9efaa9c62cca2f04.tar.gz CMake-e232e1bed3143c132f707bfe9efaa9c62cca2f04.tar.bz2 |
Merge topic 'clang-tidy-module-cmsys-fstream-check'
ffa970559c clang-tidy module: add tests for cmsys::fstream check
d520853682 clang-tidy module: add check for cmsys::fstream
c67b91a7a6 Source: silence false positives for cmsys::fstream check
01d8308406 Tests: remove stderr from clang-tidy module tests
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !7869
-rw-r--r-- | Source/cmGeneratedFileStream.cxx | 11 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/Module.cxx | 3 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/Tests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/Tests/RunClangTidy.cmake | 28 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt | 2 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-fixit.cxx | 81 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-stdout.txt | 155 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream.cxx | 81 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/UseCmsysFstreamCheck.cxx | 101 | ||||
-rw-r--r-- | Utilities/ClangTidyModule/UseCmsysFstreamCheck.h | 24 |
11 files changed, 466 insertions, 23 deletions
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index c72d6a7..133bf5f 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -27,7 +27,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding) cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name, bool quiet, Encoding encoding) : cmGeneratedFileStreamBase(name) - , Stream(this->TempName.c_str()) + , Stream(this->TempName.c_str()) // NOLINT(cmake-use-cmsys-fstream) { // Check if the file opened. if (!*this && !quiet) { @@ -67,10 +67,11 @@ cmGeneratedFileStream& cmGeneratedFileStream::Open(std::string const& name, // Open the temporary output file. if (binaryFlag) { - this->Stream::open(this->TempName.c_str(), - std::ios::out | std::ios::binary); + this->Stream::open( // NOLINT(cmake-use-cmsys-fstream) + this->TempName.c_str(), std::ios::out | std::ios::binary); } else { - this->Stream::open(this->TempName.c_str()); + this->Stream::open( // NOLINT(cmake-use-cmsys-fstream) + this->TempName.c_str()); } // Check if the file opened. @@ -87,7 +88,7 @@ bool cmGeneratedFileStream::Close() this->Okay = !this->fail(); // Close the temporary output file. - this->Stream::close(); + this->Stream::close(); // NOLINT(cmake-use-cmsys-fstream) // Remove the temporary file (possibly by renaming to the real file). return this->cmGeneratedFileStreamBase::Close(); diff --git a/Utilities/ClangTidyModule/CMakeLists.txt b/Utilities/ClangTidyModule/CMakeLists.txt index 6be13d6..51603aa 100644 --- a/Utilities/ClangTidyModule/CMakeLists.txt +++ b/Utilities/ClangTidyModule/CMakeLists.txt @@ -16,6 +16,8 @@ add_library(cmake-clang-tidy-module MODULE UseCmstrlenCheck.cxx UseCmstrlenCheck.h + UseCmsysFstreamCheck.cxx + UseCmsysFstreamCheck.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 a35c336..a9d344f 100644 --- a/Utilities/ClangTidyModule/Module.cxx +++ b/Utilities/ClangTidyModule/Module.cxx @@ -4,6 +4,7 @@ #include <clang-tidy/ClangTidyModuleRegistry.h> #include "UseCmstrlenCheck.h" +#include "UseCmsysFstreamCheck.h" namespace clang { namespace tidy { @@ -14,6 +15,8 @@ public: void addCheckFactories(ClangTidyCheckFactories& CheckFactories) override { CheckFactories.registerCheck<UseCmstrlenCheck>("cmake-use-cmstrlen"); + CheckFactories.registerCheck<UseCmsysFstreamCheck>( + "cmake-use-cmsys-fstream"); } }; diff --git a/Utilities/ClangTidyModule/Tests/CMakeLists.txt b/Utilities/ClangTidyModule/Tests/CMakeLists.txt index 42027ed..a66eaa8 100644 --- a/Utilities/ClangTidyModule/Tests/CMakeLists.txt +++ b/Utilities/ClangTidyModule/Tests/CMakeLists.txt @@ -11,3 +11,4 @@ function(add_run_clang_tidy_test check_name) endfunction() add_run_clang_tidy_test(cmake-use-cmstrlen) +add_run_clang_tidy_test(cmake-use-cmsys-fstream) diff --git a/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake b/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake index 486d592..7fd7cdd 100644 --- a/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake +++ b/Utilities/ClangTidyModule/Tests/RunClangTidy.cmake @@ -3,14 +3,12 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.clang-tidy") set(config_arg "--config-file=${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.clang-tidy") endif() -foreach(o out err) - if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-std${o}.txt") - file(READ "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-std${o}.txt" expect_std${o}) - string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}") - else() - set(expect_std${o} "") - endif() -endforeach() +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-stdout.txt") + file(READ "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-stdout.txt" expect_stdout) + string(REGEX REPLACE "\n+$" "" expect_stdout "${expect_stdout}") +else() + set(expect_stdout "") +endif() set(source_file "${RunClangTidy_BINARY_DIR}/${CHECK_NAME}.cxx") configure_file("${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}.cxx" "${source_file}" COPYONLY) @@ -39,14 +37,12 @@ if(NOT result EQUAL 0) string(APPEND RunClangTidy_TEST_FAILED "Expected result: 0, actual result: ${result}\n") endif() -foreach(o out err) - string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}") - if(NOT actual_std${o} STREQUAL expect_std${o}) - string(REPLACE "\n" "\n " expect_std${o}_formatted " ${expect_std${o}}") - string(REPLACE "\n" "\n " actual_std${o}_formatted " ${actual_std${o}}") - string(APPEND RunClangTidy_TEST_FAILED "Expected std${o}:\n${expect_std${o}_formatted}\nActual std${o}:\n${actual_std${o}_formatted}\n") - endif() -endforeach() +string(REGEX REPLACE "\n+$" "" actual_stdout "${actual_stdout}") +if(NOT actual_stdout STREQUAL expect_stdout) + string(REPLACE "\n" "\n " expect_stdout_formatted " ${expect_stdout}") + string(REPLACE "\n" "\n " actual_stdout_formatted " ${actual_stdout}") + string(APPEND RunClangTidy_TEST_FAILED "Expected stdout:\n${expect_stdout_formatted}\nActual stdout:\n${actual_stdout_formatted}\n") +endif() if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-fixit.cxx") set(expect_fixit_file "${CMAKE_CURRENT_LIST_DIR}/${CHECK_NAME}-fixit.cxx") diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt deleted file mode 100644 index 9d9d2ed..0000000 --- a/Utilities/ClangTidyModule/Tests/cmake-use-cmstrlen-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -4 warnings generated. -clang-tidy applied 4 of 4 suggested fixes. diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-fixit.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-fixit.cxx new file mode 100644 index 0000000..5c7c123 --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-fixit.cxx @@ -0,0 +1,81 @@ +#include <fstream> +#include <vector> + +namespace cmsys { +using std::ifstream; +using std::ofstream; +using std::fstream; +} + +namespace ns { +using std::ifstream; +using std::ofstream; +using std::fstream; + +namespace ns { +using std::ifstream; +using std::ofstream; +using std::fstream; +} + +class cl +{ +public: + using ifstream = cmsys::ifstream; + using ofstream = cmsys::ofstream; + using fstream = cmsys::fstream; +}; + +using ifs = cmsys::ifstream; +using ofs = cmsys::ofstream; +using fs = cmsys::fstream; +} + +int main() +{ + using std::ifstream; + using std::ofstream; + using std::fstream; + + // Correction needed + cmsys::ifstream ifsUnqual; + cmsys::ifstream ifsQual; + cmsys::ifstream ifsNS; + cmsys::ifstream ifsNested; + cmsys::ifstream ifsClass; + cmsys::ifstream ifsRenamed; + + cmsys::ofstream ofsUnqual; + cmsys::ofstream ofsQual; + cmsys::ofstream ofsNS; + cmsys::ofstream ofsNested; + cmsys::ofstream ofsClass; + cmsys::ofstream ofsRenamed; + + cmsys::fstream fsUnqual; + cmsys::fstream fsQual; + cmsys::fstream fsNS; + cmsys::fstream fsNested; + cmsys::fstream fsClass; + cmsys::fstream fsRenamed; + + cmsys::ifstream::off_type offsetQual = 0; + cmsys::ifstream::off_type offsetUnqual = 0; + cmsys::ifstream::off_type offsetNS = 0; + cmsys::ifstream::off_type offsetNested = 0; + cmsys::ifstream::traits_type::off_type offsetTraitsNested = 0; + cmsys::ifstream::traits_type::off_type offsetTraitsClass = 0; + + std::vector<cmsys::ifstream> ifsVectorUnqual; + + // No correction needed + cmsys::ifstream ifsCmsys; + cmsys::ofstream ofsCmsys; + cmsys::fstream fsCmsys; + cmsys::ifstream::off_type offsetCmsys = 0; + cmsys::ifstream::traits_type::off_type offsetTraitsCmsys = 0; + std::vector<cmsys::ifstream> ifsVectorCmsys; + std::basic_ifstream<wchar_t> ifsWchar; + + return 0; +} diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-stdout.txt b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-stdout.txt new file mode 100644 index 0000000..d2c45f2 --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream-stdout.txt @@ -0,0 +1,155 @@ +cmake-use-cmsys-fstream.cxx:24:20: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + using ifstream = std::ifstream; + ^~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:24:20: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:25:20: warning: use cmsys::ofstream [cmake-use-cmsys-fstream] + using ofstream = std::ofstream; + ^~~~~~~~~~~~~ + cmsys::ofstream +cmake-use-cmsys-fstream.cxx:25:20: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:26:19: warning: use cmsys::fstream [cmake-use-cmsys-fstream] + using fstream = std::fstream; + ^~~~~~~~~~~~ + cmsys::fstream +cmake-use-cmsys-fstream.cxx:26:19: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:29:13: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] +using ifs = std::ifstream; + ^~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:29:13: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:30:13: warning: use cmsys::ofstream [cmake-use-cmsys-fstream] +using ofs = std::ofstream; + ^~~~~~~~~~~~~ + cmsys::ofstream +cmake-use-cmsys-fstream.cxx:30:13: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:31:12: warning: use cmsys::fstream [cmake-use-cmsys-fstream] +using fs = std::fstream; + ^~~~~~~~~~~~ + cmsys::fstream +cmake-use-cmsys-fstream.cxx:31:12: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:41:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ifstream ifsUnqual; + ^~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:41:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:42:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + std::ifstream ifsQual; + ^~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:42:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:43:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ns::ifstream ifsNS; + ^~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:43:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:44:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ns::ns::ifstream ifsNested; + ^~~~~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:44:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:45:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ns::cl::ifstream ifsClass; + ^~~~~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:45:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:46:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ns::ifs ifsRenamed; + ^~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:46:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:48:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream] + ofstream ofsUnqual; + ^~~~~~~~ + cmsys::ofstream +cmake-use-cmsys-fstream.cxx:48:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:49:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream] + std::ofstream ofsQual; + ^~~~~~~~~~~~~ + cmsys::ofstream +cmake-use-cmsys-fstream.cxx:49:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:50:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream] + ns::ofstream ofsNS; + ^~~~~~~~~~~~ + cmsys::ofstream +cmake-use-cmsys-fstream.cxx:50:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:51:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream] + ns::ns::ofstream ofsNested; + ^~~~~~~~~~~~~~~~ + cmsys::ofstream +cmake-use-cmsys-fstream.cxx:51:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:52:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream] + ns::cl::ofstream ofsClass; + ^~~~~~~~~~~~~~~~ + cmsys::ofstream +cmake-use-cmsys-fstream.cxx:52:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:53:3: warning: use cmsys::ofstream [cmake-use-cmsys-fstream] + ns::ofs ofsRenamed; + ^~~~~~~ + cmsys::ofstream +cmake-use-cmsys-fstream.cxx:53:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:55:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream] + fstream fsUnqual; + ^~~~~~~ + cmsys::fstream +cmake-use-cmsys-fstream.cxx:55:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:56:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream] + std::fstream fsQual; + ^~~~~~~~~~~~ + cmsys::fstream +cmake-use-cmsys-fstream.cxx:56:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:57:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream] + ns::fstream fsNS; + ^~~~~~~~~~~ + cmsys::fstream +cmake-use-cmsys-fstream.cxx:57:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:58:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream] + ns::ns::fstream fsNested; + ^~~~~~~~~~~~~~~ + cmsys::fstream +cmake-use-cmsys-fstream.cxx:58:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:59:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream] + ns::ns::fstream fsClass; + ^~~~~~~~~~~~~~~ + cmsys::fstream +cmake-use-cmsys-fstream.cxx:59:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:60:3: warning: use cmsys::fstream [cmake-use-cmsys-fstream] + ns::fs fsRenamed; + ^~~~~~ + cmsys::fstream +cmake-use-cmsys-fstream.cxx:60:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:62:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + std::ifstream::off_type offsetQual = 0; + ^~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:62:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:63:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ifstream::off_type offsetUnqual = 0; + ^~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:63:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:64:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ns::ifstream::off_type offsetNS = 0; + ^~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:64:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:65:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ns::ns::ifstream::off_type offsetNested = 0; + ^~~~~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:65:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:66:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ns::ns::ifstream::traits_type::off_type offsetTraitsNested = 0; + ^~~~~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:66:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:67:3: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + ns::cl::ifstream::traits_type::off_type offsetTraitsClass = 0; + ^~~~~~~~~~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:67:3: note: FIX-IT applied suggested code changes +cmake-use-cmsys-fstream.cxx:69:15: warning: use cmsys::ifstream [cmake-use-cmsys-fstream] + std::vector<ifstream> ifsVectorUnqual; + ^~~~~~~~ + cmsys::ifstream +cmake-use-cmsys-fstream.cxx:69:15: note: FIX-IT applied suggested code changes diff --git a/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream.cxx b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream.cxx new file mode 100644 index 0000000..56a7611 --- /dev/null +++ b/Utilities/ClangTidyModule/Tests/cmake-use-cmsys-fstream.cxx @@ -0,0 +1,81 @@ +#include <fstream> +#include <vector> + +namespace cmsys { +using std::ifstream; +using std::ofstream; +using std::fstream; +} + +namespace ns { +using std::ifstream; +using std::ofstream; +using std::fstream; + +namespace ns { +using std::ifstream; +using std::ofstream; +using std::fstream; +} + +class cl +{ +public: + using ifstream = std::ifstream; + using ofstream = std::ofstream; + using fstream = std::fstream; +}; + +using ifs = std::ifstream; +using ofs = std::ofstream; +using fs = std::fstream; +} + +int main() +{ + using std::ifstream; + using std::ofstream; + using std::fstream; + + // Correction needed + ifstream ifsUnqual; + std::ifstream ifsQual; + ns::ifstream ifsNS; + ns::ns::ifstream ifsNested; + ns::cl::ifstream ifsClass; + ns::ifs ifsRenamed; + + ofstream ofsUnqual; + std::ofstream ofsQual; + ns::ofstream ofsNS; + ns::ns::ofstream ofsNested; + ns::cl::ofstream ofsClass; + ns::ofs ofsRenamed; + + fstream fsUnqual; + std::fstream fsQual; + ns::fstream fsNS; + ns::ns::fstream fsNested; + ns::ns::fstream fsClass; + ns::fs fsRenamed; + + std::ifstream::off_type offsetQual = 0; + ifstream::off_type offsetUnqual = 0; + ns::ifstream::off_type offsetNS = 0; + ns::ns::ifstream::off_type offsetNested = 0; + ns::ns::ifstream::traits_type::off_type offsetTraitsNested = 0; + ns::cl::ifstream::traits_type::off_type offsetTraitsClass = 0; + + std::vector<ifstream> ifsVectorUnqual; + + // No correction needed + cmsys::ifstream ifsCmsys; + cmsys::ofstream ofsCmsys; + cmsys::fstream fsCmsys; + cmsys::ifstream::off_type offsetCmsys = 0; + cmsys::ifstream::traits_type::off_type offsetTraitsCmsys = 0; + std::vector<cmsys::ifstream> ifsVectorCmsys; + std::basic_ifstream<wchar_t> ifsWchar; + + return 0; +} diff --git a/Utilities/ClangTidyModule/UseCmsysFstreamCheck.cxx b/Utilities/ClangTidyModule/UseCmsysFstreamCheck.cxx new file mode 100644 index 0000000..95a0a4d --- /dev/null +++ b/Utilities/ClangTidyModule/UseCmsysFstreamCheck.cxx @@ -0,0 +1,101 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "UseCmsysFstreamCheck.h" + +#include <clang/ASTMatchers/ASTMatchFinder.h> + +namespace clang { +namespace tidy { +namespace cmake { +using namespace ast_matchers; + +UseCmsysFstreamCheck::UseCmsysFstreamCheck(StringRef Name, + ClangTidyContext* Context) + : ClangTidyCheck(Name, Context) +{ +} + +void UseCmsysFstreamCheck::registerMatchers(MatchFinder* Finder) +{ + this->createMatcher("::std::basic_ifstream", "::cmsys::ifstream", Finder, + "ifstream"); + this->createMatcher("::std::basic_ofstream", "::cmsys::ofstream", Finder, + "ofstream"); + this->createMatcher("::std::basic_fstream", "::cmsys::fstream", Finder, + "fstream"); +} + +void UseCmsysFstreamCheck::check(const MatchFinder::MatchResult& Result) +{ + const TypeLoc* ParentTypeNode = + Result.Nodes.getNodeAs<TypeLoc>("parentType"); + const NestedNameSpecifierLoc* ParentNameNode = + Result.Nodes.getNodeAs<NestedNameSpecifierLoc>("parentName"); + const TypeLoc* RootNode = nullptr; + StringRef BindName; + StringRef Warning; + + if ((RootNode = Result.Nodes.getNodeAs<TypeLoc>("ifstream")) != nullptr) { + BindName = "cmsys::ifstream"; + Warning = "use cmsys::ifstream"; + } else if ((RootNode = Result.Nodes.getNodeAs<TypeLoc>("ofstream")) != + nullptr) { + BindName = "cmsys::ofstream"; + Warning = "use cmsys::ofstream"; + } else if ((RootNode = Result.Nodes.getNodeAs<TypeLoc>("fstream")) != + nullptr) { + BindName = "cmsys::fstream"; + Warning = "use cmsys::fstream"; + } + + if (ParentTypeNode != nullptr) { + if (ParentTypeNode->getBeginLoc().isValid()) { + this->diag(ParentTypeNode->getBeginLoc(), Warning) + << FixItHint::CreateReplacement(ParentTypeNode->getSourceRange(), + BindName); + } + } else if (ParentNameNode != nullptr) { + if (ParentNameNode->getBeginLoc().isValid()) { + this->diag(ParentNameNode->getBeginLoc(), Warning) + << FixItHint::CreateReplacement( + SourceRange(ParentNameNode->getBeginLoc(), RootNode->getEndLoc()), + BindName); + } + } else if (RootNode != nullptr) { + if (RootNode->getBeginLoc().isValid()) { + this->diag(RootNode->getBeginLoc(), Warning) + << FixItHint::CreateReplacement(RootNode->getSourceRange(), BindName); + } + } +} + +void UseCmsysFstreamCheck::createMatcher(StringRef StdName, + StringRef CmsysName, + ast_matchers::MatchFinder* Finder, + StringRef Bind) +{ + TypeLocMatcher IsStd = loc(qualType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName(StdName), + hasTemplateArgument( + 0, templateArgument(refersToType(asString("char")))))))))); + + // TODO This only checks to see if the type directly refers to + // cmsys::fstream. There are some corner cases involving template parameters + // that refer to cmsys::fstream that are missed by this matcher, resulting in + // a false positive. Figure out how to find these indirect references to + // cmsys::fstream and filter them out. In the meantime, such false positives + // can be silenced with NOLINT(cmake-use-cmsys-fstream). + TypeLocMatcher IsCmsys = + loc(usingType(throughUsingDecl(namedDecl(hasName(CmsysName))))); + + Finder->addMatcher( + typeLoc(IsStd, unless(IsCmsys), unless(elaboratedTypeLoc()), + optionally(hasParent(elaboratedTypeLoc().bind("parentType"))), + optionally(hasParent(nestedNameSpecifierLoc().bind("parentName")))) + .bind(Bind), + this); +} +} +} +} diff --git a/Utilities/ClangTidyModule/UseCmsysFstreamCheck.h b/Utilities/ClangTidyModule/UseCmsysFstreamCheck.h new file mode 100644 index 0000000..782123c --- /dev/null +++ b/Utilities/ClangTidyModule/UseCmsysFstreamCheck.h @@ -0,0 +1,24 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include <clang-tidy/ClangTidyCheck.h> +#include <clang/ASTMatchers/ASTMatchFinder.h> + +namespace clang { +namespace tidy { +namespace cmake { +class UseCmsysFstreamCheck : public ClangTidyCheck +{ +public: + UseCmsysFstreamCheck(StringRef Name, ClangTidyContext* Context); + void registerMatchers(ast_matchers::MatchFinder* Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult& Result) override; + +private: + void createMatcher(StringRef name, StringRef CmsysName, + ast_matchers::MatchFinder* Finder, StringRef bind); +}; +} +} +} |