hokein created this revision. hokein added a reviewer: alexfh. hokein added a subscriber: cfe-commits.
[clang-tidy] Don't warn implicit variables in peformance-unnecessary-copy-initialization. This will prevent the check warning the variables which have been implicitly added by compiler, like the following case (in for-range loop): the variable '__end' is copy-constructed from a const reference... https://reviews.llvm.org/D25911 Files: clang-move/ClangMove.cpp clang-tidy/performance/UnnecessaryCopyInitialization.cpp test/clang-tidy/performance-unnecessary-copy-initialization.cpp unittests/clang-move/ClangMoveTests.cpp Index: unittests/clang-move/ClangMoveTests.cpp =================================================================== --- unittests/clang-move/ClangMoveTests.cpp +++ unittests/clang-move/ClangMoveTests.cpp @@ -30,6 +30,7 @@ const char TestHeader[] = "namespace a {\n" "class C1; // test\n" + "template <typename T> class C2;\n" "namespace b {\n" "// This is a Foo class\n" "// which is used in\n" @@ -87,6 +88,7 @@ const char ExpectedTestHeader[] = "namespace a {\n" "class C1; // test\n" + "template <typename T> class C2;\n" "namespace b {\n" "\n" "class Foo2 {\n" @@ -127,6 +129,7 @@ "#define NEW_FOO_H\n" "namespace a {\n" "class C1; // test\n" + "template <typename T> class C2;\n" "namespace b {\n" "// This is a Foo class\n" "// which is used in\n" Index: test/clang-tidy/performance-unnecessary-copy-initialization.cpp =================================================================== --- test/clang-tidy/performance-unnecessary-copy-initialization.cpp +++ test/clang-tidy/performance-unnecessary-copy-initialization.cpp @@ -368,3 +368,22 @@ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy' of the variable 'orig' is never modified; consider avoiding the copy [performance-unnecessary-copy-initialization] // CHECK-FIXES: ExpensiveToCopyType copy = orig, copy2; } + +class Element {}; +class Container { +public: + class Iterator { + public: + void operator++(); + Element operator*(); + bool operator!=(const Iterator &); + WeirdCopyCtorType c; + }; + const Iterator &begin() const; + const Iterator &end() const; +}; + +void implicitVarFalsePositive() { + for (const Element &E : Container()) { + } +} Index: clang-tidy/performance/UnnecessaryCopyInitialization.cpp =================================================================== --- clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -57,6 +57,7 @@ declStmt( has(varDecl(hasLocalStorage(), hasType(matchers::isExpensiveToCopy()), + unless(isImplicit()), hasInitializer( cxxConstructExpr( hasDeclaration(cxxConstructorDecl( Index: clang-move/ClangMove.cpp =================================================================== --- clang-move/ClangMove.cpp +++ clang-move/ClangMove.cpp @@ -406,8 +406,13 @@ } else if (const auto *FWD = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("fwd_decl")) { // Skip all forwad declarations which appear after moved class declaration. - if (RemovedDecls.empty()) - MovedDecls.emplace_back(FWD, &Result.Context->getSourceManager()); + if (RemovedDecls.empty()) { + if (const auto *DCT = FWD->getDescribedClassTemplate()) { + MovedDecls.emplace_back(DCT, &Result.Context->getSourceManager()); + } else { + MovedDecls.emplace_back(FWD, &Result.Context->getSourceManager()); + } + } } else if (const auto *ANS = Result.Nodes.getNodeAs<clang::NamespaceDecl>( "anonymous_ns")) { MovedDecls.emplace_back(ANS, &Result.Context->getSourceManager());
Index: unittests/clang-move/ClangMoveTests.cpp =================================================================== --- unittests/clang-move/ClangMoveTests.cpp +++ unittests/clang-move/ClangMoveTests.cpp @@ -30,6 +30,7 @@ const char TestHeader[] = "namespace a {\n" "class C1; // test\n" + "template <typename T> class C2;\n" "namespace b {\n" "// This is a Foo class\n" "// which is used in\n" @@ -87,6 +88,7 @@ const char ExpectedTestHeader[] = "namespace a {\n" "class C1; // test\n" + "template <typename T> class C2;\n" "namespace b {\n" "\n" "class Foo2 {\n" @@ -127,6 +129,7 @@ "#define NEW_FOO_H\n" "namespace a {\n" "class C1; // test\n" + "template <typename T> class C2;\n" "namespace b {\n" "// This is a Foo class\n" "// which is used in\n" Index: test/clang-tidy/performance-unnecessary-copy-initialization.cpp =================================================================== --- test/clang-tidy/performance-unnecessary-copy-initialization.cpp +++ test/clang-tidy/performance-unnecessary-copy-initialization.cpp @@ -368,3 +368,22 @@ // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy' of the variable 'orig' is never modified; consider avoiding the copy [performance-unnecessary-copy-initialization] // CHECK-FIXES: ExpensiveToCopyType copy = orig, copy2; } + +class Element {}; +class Container { +public: + class Iterator { + public: + void operator++(); + Element operator*(); + bool operator!=(const Iterator &); + WeirdCopyCtorType c; + }; + const Iterator &begin() const; + const Iterator &end() const; +}; + +void implicitVarFalsePositive() { + for (const Element &E : Container()) { + } +} Index: clang-tidy/performance/UnnecessaryCopyInitialization.cpp =================================================================== --- clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -57,6 +57,7 @@ declStmt( has(varDecl(hasLocalStorage(), hasType(matchers::isExpensiveToCopy()), + unless(isImplicit()), hasInitializer( cxxConstructExpr( hasDeclaration(cxxConstructorDecl( Index: clang-move/ClangMove.cpp =================================================================== --- clang-move/ClangMove.cpp +++ clang-move/ClangMove.cpp @@ -406,8 +406,13 @@ } else if (const auto *FWD = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("fwd_decl")) { // Skip all forwad declarations which appear after moved class declaration. - if (RemovedDecls.empty()) - MovedDecls.emplace_back(FWD, &Result.Context->getSourceManager()); + if (RemovedDecls.empty()) { + if (const auto *DCT = FWD->getDescribedClassTemplate()) { + MovedDecls.emplace_back(DCT, &Result.Context->getSourceManager()); + } else { + MovedDecls.emplace_back(FWD, &Result.Context->getSourceManager()); + } + } } else if (const auto *ANS = Result.Nodes.getNodeAs<clang::NamespaceDecl>( "anonymous_ns")) { MovedDecls.emplace_back(ANS, &Result.Context->getSourceManager());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits