| // RUN: %check_clang_tidy %s bugprone-suspicious-memory-comparison %t \ |
| // RUN: -- -- -target x86_64-unknown-unknown |
| |
| namespace std { |
| typedef __SIZE_TYPE__ size_t; |
| int memcmp(const void *lhs, const void *rhs, size_t count); |
| } // namespace std |
| |
| namespace sei_cert_example_oop57_cpp { |
| class C { |
| int i; |
| |
| public: |
| virtual void f(); |
| }; |
| |
| void f(C &c1, C &c2) { |
| if (!std::memcmp(&c1, &c2, sizeof(C))) { |
| // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: comparing object representation of non-standard-layout type 'sei_cert_example_oop57_cpp::C'; consider using a comparison operator instead |
| } |
| } |
| } // namespace sei_cert_example_oop57_cpp |
| |
| namespace inner_padding_64bit_only { |
| struct S { |
| int x; |
| int *y; |
| }; |
| |
| void test() { |
| S a, b; |
| std::memcmp(&a, &b, sizeof(S)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'inner_padding_64bit_only::S' which does not have a unique object representation; consider comparing the members of the object manually |
| } |
| } // namespace inner_padding_64bit_only |
| |
| namespace padding_in_base { |
| class Base { |
| char c; |
| int i; |
| }; |
| |
| class Derived : public Base {}; |
| |
| class Derived2 : public Derived {}; |
| |
| void testDerived() { |
| Derived a, b; |
| std::memcmp(&a, &b, sizeof(Base)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'padding_in_base::Derived' which does not have a unique object representation; consider comparing the members of the object manually |
| std::memcmp(&a, &b, sizeof(Derived)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'padding_in_base::Derived' which does not have a unique object representation; consider comparing the members of the object manually |
| } |
| |
| void testDerived2() { |
| Derived2 a, b; |
| std::memcmp(&a, &b, sizeof(Base)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'padding_in_base::Derived2' which does not have a unique object representation; consider comparing the members of the object manually |
| std::memcmp(&a, &b, sizeof(Derived2)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'padding_in_base::Derived2' which does not have a unique object representation; consider comparing the members of the object manually |
| } |
| |
| } // namespace padding_in_base |
| |
| namespace no_padding_in_base { |
| class Base { |
| int a, b; |
| }; |
| |
| class Derived : public Base {}; |
| |
| class Derived2 : public Derived {}; |
| |
| void testDerived() { |
| Derived a, b; |
| std::memcmp(&a, &b, sizeof(Base)); |
| std::memcmp(&a, &b, sizeof(Derived)); |
| } |
| |
| void testDerived2() { |
| Derived2 a, b; |
| std::memcmp(&a, &b, sizeof(char)); |
| std::memcmp(&a, &b, sizeof(Base)); |
| std::memcmp(&a, &b, sizeof(Derived2)); |
| } |
| } // namespace no_padding_in_base |
| |
| namespace non_standard_layout { |
| class C { |
| private: |
| int x; |
| |
| public: |
| int y; |
| }; |
| |
| void test() { |
| C a, b; |
| std::memcmp(&a, &b, sizeof(C)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of non-standard-layout type 'non_standard_layout::C'; consider using a comparison operator instead |
| } |
| |
| } // namespace non_standard_layout |
| |
| namespace static_ignored { |
| struct S { |
| static char c; |
| int i; |
| }; |
| |
| void test() { |
| S a, b; |
| std::memcmp(&a, &b, sizeof(S)); |
| } |
| } // namespace static_ignored |
| |
| namespace operator_void_ptr { |
| struct S { |
| operator void *() const; |
| }; |
| |
| void test() { |
| S s; |
| std::memcmp(s, s, sizeof(s)); |
| } |
| } // namespace operator_void_ptr |
| |
| namespace empty_struct { |
| struct S {}; |
| |
| void test() { |
| S a, b; |
| std::memcmp(&a, &b, sizeof(S)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'empty_struct::S' which does not have a unique object representation; consider comparing the members of the object manually |
| } |
| } // namespace empty_struct |
| |
| namespace empty_field { |
| struct Empty {}; |
| struct S { |
| Empty e; |
| }; |
| |
| void test() { |
| S a, b; |
| std::memcmp(&a, &b, sizeof(S)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'empty_field::S' which does not have a unique object representation; consider comparing the members of the object manually |
| } |
| } // namespace empty_field |
| |
| namespace no_unique_address_attribute { |
| struct Empty {}; |
| |
| namespace no_padding { |
| struct S { |
| char c; |
| [[no_unique_address]] Empty e; |
| }; |
| |
| void test() { |
| S a, b; |
| std::memcmp(&a, &b, sizeof(S)); |
| } |
| |
| } // namespace no_padding |
| |
| namespace multiple_empties_same_type { |
| struct S { |
| char c; |
| [[no_unique_address]] Empty e1, e2; |
| }; |
| |
| void test() { |
| S a, b; |
| std::memcmp(&a, &b, sizeof(S)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'no_unique_address_attribute::multiple_empties_same_type::S' which does not have a unique object representation; consider comparing the members of the object manually |
| } |
| |
| } // namespace multiple_empties_same_type |
| |
| namespace multiple_empties_different_types { |
| struct Empty2 {}; |
| |
| struct S { |
| char c; |
| [[no_unique_address]] Empty e1; |
| [[no_unique_address]] Empty2 e2; |
| }; |
| |
| void test() { |
| S a, b; |
| std::memcmp(&a, &b, sizeof(S)); |
| } |
| } // namespace multiple_empties_different_types |
| } // namespace no_unique_address_attribute |
| |
| namespace alignment { |
| struct S { |
| char x; |
| alignas(sizeof(int)) char y[sizeof(int)]; |
| }; |
| |
| void test() { |
| S a, b; |
| std::memcmp(&a, &b, sizeof(S)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'alignment::S' which does not have a unique object representation; consider comparing the members of the object manually |
| } |
| } // namespace alignment |
| |
| namespace no_warning_in_template { |
| template <typename T> |
| int compare(const T *l, const T *r) { |
| return std::memcmp(l, r, sizeof(T)); |
| } |
| |
| void test() { |
| int a, b; |
| compare(&a, &b); |
| } |
| } // namespace no_warning_in_template |
| |
| namespace warning_in_template { |
| template <typename T> |
| int compare(const T *l, const T *r) { |
| return std::memcmp(l, r, sizeof(T)); |
| // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: comparing object representation of type 'float' which does not have a unique object representation; consider comparing the values manually |
| } |
| |
| void test() { |
| float a, b; |
| compare(&a, &b); |
| } |
| } // namespace warning_in_template |