[clang-tools-extra] r277523 - [clang-tidy] Fix segfault in cppcore-guidelines-special-member-functions check

Jonathan Coe via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 2 14:18:38 PDT 2016


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;




More information about the cfe-commits mailing list