234 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-suspicious-memory-comparison %t \2// RUN: -- -- -target x86_64-unknown-unknown3 4namespace std {5typedef __SIZE_TYPE__ size_t;6int memcmp(const void *lhs, const void *rhs, size_t count);7} // namespace std8 9namespace sei_cert_example_oop57_cpp {10class C {11 int i;12 13public:14 virtual void f();15};16 17void f(C &c1, C &c2) {18 if (!std::memcmp(&c1, &c2, sizeof(C))) {19 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: comparing object representation of non-standard-layout type 'C'; consider using a comparison operator instead20 }21}22} // namespace sei_cert_example_oop57_cpp23 24namespace inner_padding_64bit_only {25struct S {26 int x;27 int *y;28};29 30void test() {31 S a, b;32 std::memcmp(&a, &b, sizeof(S));33 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'S' which does not have a unique object representation; consider comparing the members of the object manually34}35} // namespace inner_padding_64bit_only36 37namespace padding_in_base {38class Base {39 char c;40 int i;41};42 43class Derived : public Base {};44 45class Derived2 : public Derived {};46 47void testDerived() {48 Derived a, b;49 std::memcmp(&a, &b, sizeof(Base));50 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'Derived' which does not have a unique object representation; consider comparing the members of the object manually51 std::memcmp(&a, &b, sizeof(Derived));52 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'Derived' which does not have a unique object representation; consider comparing the members of the object manually53}54 55void testDerived2() {56 Derived2 a, b;57 std::memcmp(&a, &b, sizeof(Base));58 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'Derived2' which does not have a unique object representation; consider comparing the members of the object manually59 std::memcmp(&a, &b, sizeof(Derived2));60 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'Derived2' which does not have a unique object representation; consider comparing the members of the object manually61}62 63} // namespace padding_in_base64 65namespace no_padding_in_base {66class Base {67 int a, b;68};69 70class Derived : public Base {};71 72class Derived2 : public Derived {};73 74void testDerived() {75 Derived a, b;76 std::memcmp(&a, &b, sizeof(Base));77 std::memcmp(&a, &b, sizeof(Derived));78}79 80void testDerived2() {81 Derived2 a, b;82 std::memcmp(&a, &b, sizeof(char));83 std::memcmp(&a, &b, sizeof(Base));84 std::memcmp(&a, &b, sizeof(Derived2));85}86} // namespace no_padding_in_base87 88namespace non_standard_layout {89class C {90private:91 int x;92 93public:94 int y;95};96 97void test() {98 C a, b;99 std::memcmp(&a, &b, sizeof(C));100 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of non-standard-layout type 'C'; consider using a comparison operator instead101}102 103} // namespace non_standard_layout104 105namespace static_ignored {106struct S {107 static char c;108 int i;109};110 111void test() {112 S a, b;113 std::memcmp(&a, &b, sizeof(S));114}115} // namespace static_ignored116 117namespace operator_void_ptr {118struct S {119 operator void *() const;120};121 122void test() {123 S s;124 std::memcmp(s, s, sizeof(s));125}126} // namespace operator_void_ptr127 128namespace empty_struct {129struct S {};130 131void test() {132 S a, b;133 std::memcmp(&a, &b, sizeof(S));134 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'S' which does not have a unique object representation; consider comparing the members of the object manually135}136} // namespace empty_struct137 138namespace empty_field {139struct Empty {};140struct S {141 Empty e;142};143 144void test() {145 S a, b;146 std::memcmp(&a, &b, sizeof(S));147 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'S' which does not have a unique object representation; consider comparing the members of the object manually148}149} // namespace empty_field150 151namespace no_unique_address_attribute {152struct Empty {};153 154namespace no_padding {155struct S {156 char c;157 [[no_unique_address]] Empty e;158};159 160void test() {161 S a, b;162 std::memcmp(&a, &b, sizeof(S));163}164 165} // namespace no_padding166 167namespace multiple_empties_same_type {168struct S {169 char c;170 [[no_unique_address]] Empty e1, e2;171};172 173void test() {174 S a, b;175 std::memcmp(&a, &b, sizeof(S));176 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'S' which does not have a unique object representation; consider comparing the members of the object manually177}178 179} // namespace multiple_empties_same_type180 181namespace multiple_empties_different_types {182struct Empty2 {};183 184struct S {185 char c;186 [[no_unique_address]] Empty e1;187 [[no_unique_address]] Empty2 e2;188};189 190void test() {191 S a, b;192 std::memcmp(&a, &b, sizeof(S));193}194} // namespace multiple_empties_different_types195} // namespace no_unique_address_attribute196 197namespace alignment {198struct S {199 char x;200 alignas(sizeof(int)) char y[sizeof(int)];201};202 203void test() {204 S a, b;205 std::memcmp(&a, &b, sizeof(S));206 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'S' which does not have a unique object representation; consider comparing the members of the object manually207}208} // namespace alignment209 210namespace no_warning_in_template {211template <typename T>212int compare(const T *l, const T *r) {213 return std::memcmp(l, r, sizeof(T));214}215 216void test() {217 int a, b;218 compare(&a, &b);219}220} // namespace no_warning_in_template221 222namespace warning_in_template {223template <typename T>224int compare(const T *l, const T *r) {225 return std::memcmp(l, r, sizeof(T));226 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: comparing object representation of type 'float' which does not have a unique object representation; consider comparing the values manually227}228 229void test() {230 float a, b;231 compare(&a, &b);232}233} // namespace warning_in_template234