brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · d368c5f Raw
231 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-undefined-memory-manipulation %t2 3void *memset(void *, int, __SIZE_TYPE__);4void *memcpy(void *, const void *, __SIZE_TYPE__);5void *memmove(void *, const void *, __SIZE_TYPE__);6 7namespace std {8using ::memcpy;9using ::memmove;10using ::memset;11}12 13namespace types {14// TriviallyCopyable types:15struct Plain {16  int n;17};18 19enum E {20  X,21  Y,22  Z23};24 25struct Base {26  float b;27};28 29struct Derived : Base {30  bool d;31};32 33// not TriviallyCopyable types:34struct Destruct {35  ~Destruct() {}36};37 38struct Copy {39  Copy() {}40  Copy(const Copy &) {}41};42 43struct Move {44  Move() {}45  Move(Move &&) {}46};47 48struct VirtualFunc {49  virtual void f() {}50};51 52struct VirtualBase : virtual Base {53  int vb;54};55 56// Incomplete type, assume it is TriviallyCopyable.57struct NoDef;58 59} // end namespace types60 61void f(types::NoDef *s) {62  memset(s, 0, 5);63}64 65template <typename T>66void memset_temp(T *b) {67  memset(b, 0, sizeof(T));68  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc' is not TriviallyCopyable [bugprone-undefined-memory-manipulation]69}70 71template <typename S, typename T>72void memcpy_temp(S *a, T *b) {73  memcpy(a, b, sizeof(T));74  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'75}76 77template <typename S, typename T>78void memmove_temp(S *a, T *b) {79  memmove(a, b, sizeof(T));80  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'81}82 83namespace aliases {84using Copy2 = types::Copy;85typedef types::Move Move2;86}87 88void notTriviallyCopyable() {89  types::Plain p; // TriviallyCopyable for variety90  types::Destruct d;91  types::Copy c;92  types::Move m;93  types::VirtualFunc vf;94  types::VirtualBase vb;95 96  memset(&vf, 0, sizeof(int));97  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'98  memset(&d, 0, sizeof(int));99  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'100  memset(&c, 0, sizeof(int));101  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'102  std::memset(&m, 0, sizeof(int));103  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'104  ::memset(&vb, 0, sizeof(int));105  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'106 107  memcpy(&p, &vf, sizeof(int));108  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'109  memcpy(&p, &d, sizeof(int));110  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Destruct'111  memcpy(&c, &p, sizeof(int));112  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'113  std::memcpy(&m, &p, sizeof(int));114  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'115  ::memcpy(&vb, &p, sizeof(int));116  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'117 118  memmove(&vf, &p, sizeof(int));119  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'120  memmove(&d, &p, sizeof(int));121  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'122  memmove(&p, &c, sizeof(int));123  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'124  std::memmove(&p, &m, sizeof(int));125  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Move'126  ::memmove(&p, &vb, sizeof(int));127  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualBase'128 129  types::Copy ca[10];130  memset(ca, 0, sizeof(ca));131  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy[10]'132  memset(&ca, 0, sizeof(ca));133  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy[10]'134 135#define MEMSET memset(&vf, 0, sizeof(int));136  MEMSET137  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'138#define MEMCPY memcpy(&d, &p, sizeof(int));139  MEMCPY140  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'141#define MEMMOVE memmove(&p, &c, sizeof(int));142  MEMMOVE143  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'144 145  memset_temp<types::VirtualFunc>(&vf);146  memcpy_temp<types::Plain, types::VirtualFunc>(&p, &vf);147  memmove_temp<types::Plain, types::VirtualFunc>(&p, &vf);148 149  aliases::Copy2 c2;150  aliases::Move2 m2;151  memset(&c2, 0, sizeof(int));152  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'153  memset(&m2, 0, sizeof(int));154  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Move2'155 156  typedef aliases::Copy2 Copy3;157  typedef aliases::Copy2 *PCopy2;158  typedef Copy3 *PCopy3;159  Copy3 c3;160  PCopy2 pc2;161  PCopy3 pc3;162  memset(&c3, 0, sizeof(int));163  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'164  memset(pc2, 0, sizeof(int));165  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'166  memset(pc3, 0, sizeof(int));167  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'168  using Copy3Arr = Copy3[5];169  Copy3Arr c3a;170  memset(c3a, 0, sizeof(c3a));171  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3Arr'172  memset(&c3a, 0, sizeof(c3a));173  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3Arr'174 175  typedef Copy3 Copy3Arr2[5];176  Copy3Arr2 c3a2;177  memset(c3a2, 0, sizeof(c3a2));178  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3Arr2'179}180 181void triviallyCopyable() {182  types::Plain p;183  types::Base base;184  types::Derived derived;185 186  int i = 5;187  int ia[3] = {1, 2, 3};188  float f = 3.14;189  float fa[3] = {1.1, 2.2, 3.3};190  bool b = false;191  bool ba[2] = {true, false};192  types::E e = types::X;193  p.n = 2;194 195  memset(&p, 0, sizeof(int));196  memset(&base, 0, sizeof(float));197  memset(&derived, 0, sizeof(bool));198  memset(&i, 0, sizeof(int));199  memset(ia, 0, sizeof(int));200  memset(&f, 0, sizeof(float));201  memset(fa, 0, sizeof(float));202  memset(&b, 0, sizeof(bool));203  memset(ba, 0, sizeof(bool));204  memset(&e, 0, sizeof(int));205  memset(&p.n, 0, sizeof(int));206 207  memcpy(&p, &p, sizeof(int));208  memcpy(&base, &base, sizeof(float));209  memcpy(&derived, &derived, sizeof(bool));210  memcpy(&i, &i, sizeof(int));211  memcpy(ia, ia, sizeof(int));212  memcpy(&f, &f, sizeof(float));213  memcpy(fa, fa, sizeof(float));214  memcpy(&b, &b, sizeof(bool));215  memcpy(ba, ba, sizeof(bool));216  memcpy(&e, &e, sizeof(int));217  memcpy(&p.n, &p.n, sizeof(int));218 219  memmove(&p, &p, sizeof(int));220  memmove(&base, &base, sizeof(float));221  memmove(&derived, &derived, sizeof(bool));222  memmove(&i, &i, sizeof(int));223  memmove(ia, ia, sizeof(int));224  memmove(&f, &f, sizeof(float));225  memmove(fa, fa, sizeof(float));226  memmove(&b, &b, sizeof(bool));227  memmove(ba, ba, sizeof(bool));228  memmove(&e, &e, sizeof(int));229  memmove(&p.n, &p.n, sizeof(int));230}231