1// RUN: %check_clang_tidy %s cert-oop57-cpp %t -- \
2// RUN: -config='{CheckOptions: \
3// RUN: {cert-oop57-cpp.MemSetNames: mymemset, \
4// RUN: cert-oop57-cpp.MemCpyNames: mymemcpy, \
5// RUN: cert-oop57-cpp.MemCmpNames: mymemcmp}}' \
6// RUN: --
7
8void mymemset(void *, unsigned char, decltype(sizeof(int)));
9void mymemcpy(void *, const void *, decltype(sizeof(int)));
10int mymemcmp(const void *, const void *, decltype(sizeof(int)));
11
12namespace std {
13void memset(void *, unsigned char, decltype(sizeof(int)));
14void memcpy(void *, const void *, decltype(sizeof(int)));
15void memmove(void *, const void *, decltype(sizeof(int)));
16void strcpy(void *, const void *, decltype(sizeof(int)));
17int memcmp(const void *, const void *, decltype(sizeof(int)));
18int strcmp(const void *, const void *, decltype(sizeof(int)));
19} // namespace std
20
21struct Trivial {
22 int I;
23 int J;
24};
25
26struct NonTrivial {
27 int I;
28 int J;
29
30 NonTrivial() : I(0), J(0) {}
31 NonTrivial &operator=(const NonTrivial &Other) {
32 I = Other.I;
33 J = Other.J;
34 return *this;
35 }
36
37 bool operator==(const Trivial &Other) const {
38 return I == Other.I && J == Other.J;
39 }
40 bool operator!=(const Trivial &Other) const {
41 return !(*this == Other);
42 }
43};
44
45void foo(const Trivial &Other) {
46 Trivial Data;
47 std::memset(&Data, 0, sizeof(Data));
48 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: calling 'memset' on a non-trivially default constructible class is undefined
49 std::memset(&Data, 0, sizeof(Trivial));
50 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: calling 'memset' on a non-trivially default constructible class is undefined
51 std::memcpy(&Data, &Other, sizeof(Data));
52 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: calling 'memcpy' on a non-trivially copyable class is undefined
53 std::memmove(&Data, &Other, sizeof(Data));
54 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: calling 'memmove' on a non-trivially copyable class is undefined
55 std::strcpy(&Data, &Other, sizeof(Data));
56 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: calling 'strcpy' on a non-trivially copyable class is undefined
57 std::memcmp(&Data, &Other, sizeof(Data));
58 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: consider using comparison operators instead of calling 'memcmp'
59 std::strcmp(&Data, &Other, sizeof(Data));
60 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: consider using comparison operators instead of calling 'strcmp'
61}
62
63void bar(const NonTrivial &Other) {
64 NonTrivial Data;
65 std::memset(&Data, 0, sizeof(Data));
66 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'memset' on a non-trivially default constructible class is undefined
67 // Check it detects sizeof(Type) as well as sizeof(Instantiation)
68 std::memset(&Data, 0, sizeof(NonTrivial));
69 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'memset' on a non-trivially default constructible class is undefined
70 std::memcpy(&Data, &Other, sizeof(Data));
71 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'memcpy' on a non-trivially copyable class is undefined
72 std::memmove(&Data, &Other, sizeof(Data));
73 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'memmove' on a non-trivially copyable class is undefined
74 std::strcpy(&Data, &Other, sizeof(Data));
75 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'strcpy' on a non-trivially copyable class is undefined
76 std::memcmp(&Data, &Other, sizeof(Data));
77 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: consider using comparison operators instead of calling 'memcmp'
78 std::strcmp(&Data, &Other, sizeof(Data));
79 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: consider using comparison operators instead of calling 'strcmp'
80}
81
82void baz(const NonTrivial &Other) {
83 NonTrivial Data;
84 mymemset(&Data, 0, sizeof(Data));
85 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'mymemset' on a non-trivially default constructible class is undefined
86 mymemcpy(&Data, &Other, sizeof(Data));
87 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'mymemcpy' on a non-trivially copyable class is undefined
88 mymemcmp(&Data, &Other, sizeof(Data));
89 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: consider using comparison operators instead of calling 'mymemcmp'
90}
91
92void nonNullSetValue() {
93 NonTrivial Data;
94 // Check non-null-valued second argument.
95 std::memset(&Data, 1, sizeof(Data));
96 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'memset' on a non-trivially default constructible class is undefined
97}
98
99void nonLiteralSetValue(char C) {
100 NonTrivial Data;
101 // Check non-literal second argument.
102 std::memset(&Data, C, sizeof(Data));
103 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'memset' on a non-trivially default constructible class is undefined
104}
105

source code of clang-tools-extra/test/clang-tidy/checkers/cert/oop57-cpp.cpp