diff --git a/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp index c2631ce9b4b0a..4f6bc18151789 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp @@ -22,9 +22,14 @@ AST_MATCHER(CXXRecordDecl, isNotTriviallyCopyable) { } // namespace void UndefinedMemoryManipulationCheck::registerMatchers(MatchFinder *Finder) { - const auto NotTriviallyCopyableObject = - hasType(ast_matchers::hasCanonicalType( - pointsTo(cxxRecordDecl(isNotTriviallyCopyable())))); + const auto HasNotTriviallyCopyableDecl = + hasDeclaration(cxxRecordDecl(isNotTriviallyCopyable())); + const auto ArrayOfNotTriviallyCopyable = + arrayType(hasElementType(HasNotTriviallyCopyableDecl)); + const auto NotTriviallyCopyableObject = hasType(hasCanonicalType( + anyOf(pointsTo(qualType(anyOf(HasNotTriviallyCopyableDecl, + ArrayOfNotTriviallyCopyable))), + ArrayOfNotTriviallyCopyable))); // Check whether destination object is not TriviallyCopyable. // Applicable to all three memory manipulation functions. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/undefined-memory-manipulation.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/undefined-memory-manipulation.cpp index 805501096d8c3..d368c5f067fd7 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/undefined-memory-manipulation.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/undefined-memory-manipulation.cpp @@ -126,6 +126,12 @@ void notTriviallyCopyable() { ::memmove(&p, &vb, sizeof(int)); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualBase' + types::Copy ca[10]; + memset(ca, 0, sizeof(ca)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy[10]' + memset(&ca, 0, sizeof(ca)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy[10]' + #define MEMSET memset(&vf, 0, sizeof(int)); MEMSET // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc' @@ -159,6 +165,17 @@ void notTriviallyCopyable() { // 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' + using Copy3Arr = Copy3[5]; + Copy3Arr c3a; + memset(c3a, 0, sizeof(c3a)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3Arr' + memset(&c3a, 0, sizeof(c3a)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3Arr' + + typedef Copy3 Copy3Arr2[5]; + Copy3Arr2 c3a2; + memset(c3a2, 0, sizeof(c3a2)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3Arr2' } void triviallyCopyable() {