Author: jbcoe Date: Tue Aug 2 16:18:37 2016 New Revision: 277523 URL: http://llvm.org/viewvc/llvm-project?rev=277523&view=rev Log: [clang-tidy] Fix segfault in cppcore-guidelines-special-member-functions check
Summary: Use a set rather than a vector of defined special member functions so that multiple declarations of the same function are only counted once. Move some private static member functions into the cpp file. Run clang-format on header. Reviewers: ericLemanissier, Prazek, aaron.ballman Subscribers: Prazek, cfe-commits, nemanjai Projects: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D23008 Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-special-member-functions.cpp Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp?rev=277523&r1=277522&r2=277523&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp Tue Aug 2 16:18:37 2016 @@ -43,25 +43,26 @@ void SpecialMemberFunctionsCheck::regist this); } -llvm::StringRef SpecialMemberFunctionsCheck::toString( - SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K) { +static llvm::StringRef +toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K) { switch (K) { - case SpecialMemberFunctionKind::Destructor: + case SpecialMemberFunctionsCheck::SpecialMemberFunctionKind::Destructor: return "a destructor"; - case SpecialMemberFunctionKind::CopyConstructor: + case SpecialMemberFunctionsCheck::SpecialMemberFunctionKind::CopyConstructor: return "a copy constructor"; - case SpecialMemberFunctionKind::CopyAssignment: + case SpecialMemberFunctionsCheck::SpecialMemberFunctionKind::CopyAssignment: return "a copy assignment operator"; - case SpecialMemberFunctionKind::MoveConstructor: + case SpecialMemberFunctionsCheck::SpecialMemberFunctionKind::MoveConstructor: return "a move constructor"; - case SpecialMemberFunctionKind::MoveAssignment: + case SpecialMemberFunctionsCheck::SpecialMemberFunctionKind::MoveAssignment: return "a move assignment operator"; } llvm_unreachable("Unhandled SpecialMemberFunctionKind"); } -std::string SpecialMemberFunctionsCheck::join( - llvm::ArrayRef<SpecialMemberFunctionKind> SMFS, llvm::StringRef AndOr) { +static std::string +join(ArrayRef<SpecialMemberFunctionsCheck::SpecialMemberFunctionKind> SMFS, + llvm::StringRef AndOr) { assert(!SMFS.empty() && "List of defined or undefined members should never be empty."); @@ -97,7 +98,7 @@ void SpecialMemberFunctionsCheck::check( for (const auto &KV : Matchers) if (Result.Nodes.getNodeAs<CXXMethodDecl>(KV.first)) - ClassWithSpecialMembers[ID].push_back(KV.second); + ClassWithSpecialMembers[ID].insert(KV.second); } void SpecialMemberFunctionsCheck::onEndOfTranslationUnit() { @@ -112,7 +113,7 @@ void SpecialMemberFunctionsCheck::onEndO } for (const auto &C : ClassWithSpecialMembers) { - ArrayRef<SpecialMemberFunctionKind> DefinedSpecialMembers = C.second; + const auto &DefinedSpecialMembers = C.second; if (DefinedSpecialMembers.size() == AllSpecialMembers.size()) continue; @@ -124,7 +125,7 @@ void SpecialMemberFunctionsCheck::onEndO std::back_inserter(UndefinedSpecialMembers)); diag(C.first.first, "class '%0' defines %1 but does not define %2") - << C.first.second << join(DefinedSpecialMembers, " and ") + << C.first.second << join(DefinedSpecialMembers.getArrayRef(), " and ") << join(UndefinedSpecialMembers, " or "); } } Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h?rev=277523&r1=277522&r2=277523&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h (original) +++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h Tue Aug 2 16:18:37 2016 @@ -1,4 +1,4 @@ -//===--- SpecialMemberFunctionsCheck.h - clang-tidy-------------------*- C++ -*-===// +//===--- SpecialMemberFunctionsCheck.h - clang-tidy--------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -41,15 +41,11 @@ public: using ClassDefId = std::pair<SourceLocation, std::string>; - using ClassDefiningSpecialMembersMap = llvm::DenseMap<ClassDefId, llvm::SmallVector<SpecialMemberFunctionKind, 5>>; + using ClassDefiningSpecialMembersMap = + llvm::DenseMap<ClassDefId, + llvm::SmallSetVector<SpecialMemberFunctionKind, 5>>; private: - - static llvm::StringRef toString(SpecialMemberFunctionKind K); - - static std::string join(llvm::ArrayRef<SpecialMemberFunctionKind> SMFS, - llvm::StringRef AndOr); - ClassDefiningSpecialMembersMap ClassWithSpecialMembers; }; @@ -65,7 +61,7 @@ template <> struct DenseMapInfo< clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId> { using ClassDefId = - clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId; + clang::tidy::cppcoreguidelines::SpecialMemberFunctionsCheck::ClassDefId; static inline ClassDefId getEmptyKey() { return ClassDefId( Modified: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-special-member-functions.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-special-member-functions.cpp?rev=277523&r1=277522&r2=277523&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-special-member-functions.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-special-member-functions.cpp Tue Aug 2 16:18:37 2016 @@ -50,3 +50,18 @@ class DeletesCopyDefaultsMove { DeletesCopyDefaultsMove &operator=(DeletesCopyDefaultsMove &&) = default; ~DeletesCopyDefaultsMove() = default; }; + +template <typename T> +struct TemplateClass { + TemplateClass() = default; + TemplateClass(const TemplateClass &); + TemplateClass &operator=(const TemplateClass &); + TemplateClass(TemplateClass &&); + TemplateClass &operator=(TemplateClass &&); + ~TemplateClass(); +}; + +// Multiple instantiations of a class template will trigger multiple matches for defined special members. +// This should not cause problems. +TemplateClass<int> InstantiationWithInt; +TemplateClass<double> InstantiationWithDouble; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits