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)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits