[clang-tools-extra] r311651 - [clang-tidy] bugprone-undefined-memory-manipulation: include type into the message

Alexander Kornienko via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 24 05:11:05 PDT 2017


Author: alexfh
Date: Thu Aug 24 05:11:05 2017
New Revision: 311651

URL: http://llvm.org/viewvc/llvm-project?rev=311651&view=rev
Log:
[clang-tidy] bugprone-undefined-memory-manipulation: include type into the message

Having the actual type in the message helps a lot understanding warnings in templates ;)

+ fix a false negative for type aliases.

Modified:
    clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
    clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp

Modified: clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp?rev=311651&r1=311650&r2=311651&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp Thu Aug 24 05:11:05 2017
@@ -26,7 +26,8 @@ AST_MATCHER(CXXRecordDecl, isNotTriviall
 
 void UndefinedMemoryManipulationCheck::registerMatchers(MatchFinder *Finder) {
   const auto NotTriviallyCopyableObject =
-      hasType(pointsTo(cxxRecordDecl(isNotTriviallyCopyable())));
+      hasType(ast_matchers::hasCanonicalType(
+          pointsTo(cxxRecordDecl(isNotTriviallyCopyable()))));
 
   // Check whether destination object is not TriviallyCopyable.
   // Applicable to all three memory manipulation functions.
@@ -47,13 +48,21 @@ void UndefinedMemoryManipulationCheck::r
 
 void UndefinedMemoryManipulationCheck::check(
     const MatchFinder::MatchResult &Result) {
-  if (const auto *Destination = Result.Nodes.getNodeAs<CallExpr>("dest")) {
-    diag(Destination->getLocStart(), "undefined behavior, destination "
-                                     "object is not TriviallyCopyable");
+  if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("dest")) {
+    QualType DestType = Call->getArg(0)->IgnoreImplicit()->getType();
+    if (!DestType->getPointeeType().isNull())
+      DestType = DestType->getPointeeType();
+    diag(Call->getLocStart(), "undefined behavior, destination object type %0 "
+                              "is not TriviallyCopyable")
+        << DestType;
   }
-  if (const auto *Source = Result.Nodes.getNodeAs<CallExpr>("src")) {
-    diag(Source->getLocStart(), "undefined behavior, source object is not "
-                                "TriviallyCopyable");
+  if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("src")) {
+    QualType SourceType = Call->getArg(1)->IgnoreImplicit()->getType();
+    if (!SourceType->getPointeeType().isNull())
+      SourceType = SourceType->getPointeeType();
+    diag(Call->getLocStart(),
+         "undefined behavior, source object type %0 is not TriviallyCopyable")
+        << SourceType;
   }
 }
 

Modified: clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp?rev=311651&r1=311650&r2=311651&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/bugprone-undefined-memory-manipulation.cpp Thu Aug 24 05:11:05 2017
@@ -10,6 +10,7 @@ using ::memmove;
 using ::memset;
 }
 
+namespace types {
 // TriviallyCopyable types:
 struct Plain {
   int n;
@@ -55,88 +56,115 @@ struct VirtualBase : virtual Base {
 // Incomplete type, assume it is TriviallyCopyable.
 struct NoDef;
 
-void f(NoDef *s) {
+} // end namespace types
+
+void f(types::NoDef *s) {
   memset(s, 0, 5);
 }
 
 template <typename T>
 void memset_temp(T *b) {
   memset(b, 0, sizeof(T));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc' is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
 }
 
 template <typename S, typename T>
 void memcpy_temp(S *a, T *b) {
   memcpy(a, b, sizeof(T));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
 }
 
 template <typename S, typename T>
 void memmove_temp(S *a, T *b) {
   memmove(a, b, sizeof(T));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
+}
+
+namespace aliases {
+using Copy2 = types::Copy;
+typedef types::Move Move2;
 }
 
 void notTriviallyCopyable() {
-  Plain p; // TriviallyCopyable for variety
-  Destruct d;
-  Copy c;
-  Move m;
-  VirtualFunc vf;
-  VirtualBase vb;
+  types::Plain p; // TriviallyCopyable for variety
+  types::Destruct d;
+  types::Copy c;
+  types::Move m;
+  types::VirtualFunc vf;
+  types::VirtualBase vb;
 
   memset(&vf, 0, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
   memset(&d, 0, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
   memset(&c, 0, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'
   std::memset(&m, 0, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'
   ::memset(&vb, 0, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'
 
   memcpy(&p, &vf, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
   memcpy(&p, &d, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Destruct'
   memcpy(&c, &p, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'
   std::memcpy(&m, &p, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'
   ::memcpy(&vb, &p, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'
 
   memmove(&vf, &p, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
   memmove(&d, &p, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
   memmove(&p, &c, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'
   std::memmove(&p, &m, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Move'
   ::memmove(&p, &vb, sizeof(int));
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualBase'
 
 #define MEMSET memset(&vf, 0, sizeof(int));
   MEMSET
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
 #define MEMCPY memcpy(&d, &p, sizeof(int));
   MEMCPY
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
 #define MEMMOVE memmove(&p, &c, sizeof(int));
   MEMMOVE
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'
 
-  memset_temp<VirtualFunc>(&vf);
-  memcpy_temp<Plain, VirtualFunc>(&p, &vf);
-  memmove_temp<Plain, VirtualFunc>(&p, &vf);
+  memset_temp<types::VirtualFunc>(&vf);
+  memcpy_temp<types::Plain, types::VirtualFunc>(&p, &vf);
+  memmove_temp<types::Plain, types::VirtualFunc>(&p, &vf);
+
+  aliases::Copy2 c2;
+  aliases::Move2 m2;
+  memset(&c2, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'
+  memset(&m2, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Move2'
+
+  typedef aliases::Copy2 Copy3;
+  typedef aliases::Copy2 *PCopy2;
+  typedef Copy3 *PCopy3;
+  Copy3 c3;
+  PCopy2 pc2;
+  PCopy3 pc3;
+  memset(&c3, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'
+  memset(pc2, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'
+  memset(pc3, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'
 }
 
 void triviallyCopyable() {
-  Plain p;
-  Base base;
-  Derived derived;
+  types::Plain p;
+  types::Base base;
+  types::Derived derived;
 
   int i = 5;
   int ia[3] = {1, 2, 3};
@@ -144,7 +172,7 @@ void triviallyCopyable() {
   float fa[3] = {1.1, 2.2, 3.3};
   bool b = false;
   bool ba[2] = {true, false};
-  E e = X;
+  types::E e = types::X;
   p.n = 2;
 
   memset(&p, 0, sizeof(int));




More information about the cfe-commits mailing list