forked from OSchip/llvm-project
179 lines
6.2 KiB
C++
179 lines
6.2 KiB
C++
|
// RUN: %check_clang_tidy %s bugprone-undefined-memory-manipulation %t
|
||
|
|
||
|
void *memset(void *, int, __SIZE_TYPE__);
|
||
|
void *memcpy(void *, const void *, __SIZE_TYPE__);
|
||
|
void *memmove(void *, const void *, __SIZE_TYPE__);
|
||
|
|
||
|
namespace std {
|
||
|
using ::memcpy;
|
||
|
using ::memmove;
|
||
|
using ::memset;
|
||
|
}
|
||
|
|
||
|
// TriviallyCopyable types:
|
||
|
struct Plain {
|
||
|
int n;
|
||
|
};
|
||
|
|
||
|
enum E {
|
||
|
X,
|
||
|
Y,
|
||
|
Z
|
||
|
};
|
||
|
|
||
|
struct Base {
|
||
|
float b;
|
||
|
};
|
||
|
|
||
|
struct Derived : Base {
|
||
|
bool d;
|
||
|
};
|
||
|
|
||
|
// not TriviallyCopyable types:
|
||
|
struct Destruct {
|
||
|
~Destruct() {}
|
||
|
};
|
||
|
|
||
|
struct Copy {
|
||
|
Copy() {}
|
||
|
Copy(const Copy &) {}
|
||
|
};
|
||
|
|
||
|
struct Move {
|
||
|
Move() {}
|
||
|
Move(Move &&) {}
|
||
|
};
|
||
|
|
||
|
struct VirtualFunc {
|
||
|
virtual void f() {}
|
||
|
};
|
||
|
|
||
|
struct VirtualBase : virtual Base {
|
||
|
int vb;
|
||
|
};
|
||
|
|
||
|
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]
|
||
|
}
|
||
|
|
||
|
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]
|
||
|
}
|
||
|
|
||
|
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]
|
||
|
}
|
||
|
|
||
|
void notTriviallyCopyable() {
|
||
|
Plain p; // TriviallyCopyable for variety
|
||
|
Destruct d;
|
||
|
Copy c;
|
||
|
Move m;
|
||
|
VirtualFunc vf;
|
||
|
VirtualBase vb;
|
||
|
|
||
|
memset(&vf, 0, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
memset(&d, 0, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
memset(&c, 0, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
std::memset(&m, 0, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
::memset(&vb, 0, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
|
||
|
memcpy(&p, &vf, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
memcpy(&p, &d, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
memcpy(&c, &p, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
std::memcpy(&m, &p, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
::memcpy(&vb, &p, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
|
||
|
memmove(&vf, &p, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
memmove(&d, &p, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
memmove(&p, &c, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
std::memmove(&p, &m, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
::memmove(&p, &vb, sizeof(int));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
|
||
|
|
||
|
#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]
|
||
|
#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]
|
||
|
#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]
|
||
|
|
||
|
memset_temp<VirtualFunc>(&vf);
|
||
|
memcpy_temp<Plain, VirtualFunc>(&p, &vf);
|
||
|
memmove_temp<Plain, VirtualFunc>(&p, &vf);
|
||
|
}
|
||
|
|
||
|
void triviallyCopyable() {
|
||
|
Plain p;
|
||
|
Base base;
|
||
|
Derived derived;
|
||
|
|
||
|
int i = 5;
|
||
|
int ia[3] = {1, 2, 3};
|
||
|
float f = 3.14;
|
||
|
float fa[3] = {1.1, 2.2, 3.3};
|
||
|
bool b = false;
|
||
|
bool ba[2] = {true, false};
|
||
|
E e = X;
|
||
|
p.n = 2;
|
||
|
|
||
|
memset(&p, 0, sizeof(int));
|
||
|
memset(&base, 0, sizeof(float));
|
||
|
memset(&derived, 0, sizeof(bool));
|
||
|
memset(&i, 0, sizeof(int));
|
||
|
memset(ia, 0, sizeof(int));
|
||
|
memset(&f, 0, sizeof(float));
|
||
|
memset(fa, 0, sizeof(float));
|
||
|
memset(&b, 0, sizeof(bool));
|
||
|
memset(ba, 0, sizeof(bool));
|
||
|
memset(&e, 0, sizeof(int));
|
||
|
memset(&p.n, 0, sizeof(int));
|
||
|
|
||
|
memcpy(&p, &p, sizeof(int));
|
||
|
memcpy(&base, &base, sizeof(float));
|
||
|
memcpy(&derived, &derived, sizeof(bool));
|
||
|
memcpy(&i, &i, sizeof(int));
|
||
|
memcpy(ia, ia, sizeof(int));
|
||
|
memcpy(&f, &f, sizeof(float));
|
||
|
memcpy(fa, fa, sizeof(float));
|
||
|
memcpy(&b, &b, sizeof(bool));
|
||
|
memcpy(ba, ba, sizeof(bool));
|
||
|
memcpy(&e, &e, sizeof(int));
|
||
|
memcpy(&p.n, &p.n, sizeof(int));
|
||
|
|
||
|
memmove(&p, &p, sizeof(int));
|
||
|
memmove(&base, &base, sizeof(float));
|
||
|
memmove(&derived, &derived, sizeof(bool));
|
||
|
memmove(&i, &i, sizeof(int));
|
||
|
memmove(ia, ia, sizeof(int));
|
||
|
memmove(&f, &f, sizeof(float));
|
||
|
memmove(fa, fa, sizeof(float));
|
||
|
memmove(&b, &b, sizeof(bool));
|
||
|
memmove(ba, ba, sizeof(bool));
|
||
|
memmove(&e, &e, sizeof(int));
|
||
|
memmove(&p.n, &p.n, sizeof(int));
|
||
|
}
|