brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.3 KiB · e0abba0 Raw
295 lines · c
1// RUN: %check_clang_tidy %s bugprone-suspicious-memory-comparison %t \2// RUN: -- -- -target x86_64-unknown-unknown -std=c993 4typedef __SIZE_TYPE__ size_t;5int memcmp(const void *lhs, const void *rhs, size_t count);6 7// Examples from cert rule exp42-c8 9struct S {10  char c;11  int i;12  char buffer[13];13};14 15void exp42_c_noncompliant(const struct S *left, const struct S *right) {16  if ((left && right) && (0 == memcmp(left, right, sizeof(struct S)))) {17    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: comparing object representation of type 'struct S' which does not have a unique object representation; consider comparing the members of the object manually18  }19}20 21void exp42_c_compliant(const struct S *left, const struct S *right) {22  if ((left && right) && (left->c == right->c) && (left->i == right->i) &&23      (0 == memcmp(left->buffer, right->buffer, 13))) {24  }25}26 27#pragma pack(push, 1)28struct Packed_S {29  char c;30  int i;31  char buffer[13];32};33#pragma pack(pop)34 35void compliant_packed(const struct Packed_S *left,36                      const struct Packed_S *right) {37  if ((left && right) && (0 == memcmp(left, right, sizeof(struct Packed_S)))) {38    // no-warning39  }40}41 42// Examples from cert rule flp37-c43 44struct S2 {45  int i;46  float f;47};48 49int flp37_c_noncompliant(const struct S2 *s1, const struct S2 *s2) {50  if (!s1 && !s2)51    return 1;52  else if (!s1 || !s2)53    return 0;54  return 0 == memcmp(s1, s2, sizeof(struct S2));55  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: comparing object representation of type 'struct S2' which does not have a unique object representation; consider comparing the members of the object manually56}57 58int flp37_c_compliant(const struct S2 *s1, const struct S2 *s2) {59  if (!s1 && !s2)60    return 1;61  else if (!s1 || !s2)62    return 0;63  return s1->i == s2->i && s1->f == s2->f;64  // no-warning65}66 67void Test_Float(void) {68  float a, b;69  memcmp(&a, &b, sizeof(float));70  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'float' which does not have a unique object representation; consider comparing the values manually71}72 73void TestArray_Float(void) {74  float a[3], b[3];75  memcmp(a, b, sizeof(a));76  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'float' which does not have a unique object representation; consider comparing the values manually77}78 79struct PredeclaredType;80 81void Test_PredeclaredType(const struct PredeclaredType *lhs,82                          const struct PredeclaredType *rhs) {83  memcmp(lhs, rhs, 1); // no-warning: predeclared type84}85 86struct NoPadding {87  int x;88  int y;89};90 91void Test_NoPadding(void) {92  struct NoPadding a, b;93  memcmp(&a, &b, sizeof(struct NoPadding));94}95 96void TestArray_NoPadding(void) {97  struct NoPadding a[3], b[3];98  memcmp(a, b, 3 * sizeof(struct NoPadding));99}100 101struct TrailingPadding {102  int i;103  char c;104};105 106void Test_TrailingPadding(void) {107  struct TrailingPadding a, b;108  memcmp(&a, &b, sizeof(struct TrailingPadding));109  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct TrailingPadding' which does not have a unique object representation; consider comparing the members of the object manually110  memcmp(&a, &b, sizeof(int)); // no-warning: not comparing entire object111  memcmp(&a, &b, 2 * sizeof(int));112  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct TrailingPadding' which does not have a unique object representation; consider comparing the members of the object manually113}114 115struct TrailingPadding2 {116  int i[2];117  char c;118};119 120void Test_TrailingPadding2(void) {121  struct TrailingPadding2 a, b;122  memcmp(&a, &b, 2 * sizeof(int)); // no-warning: not comparing entire object123  memcmp(&a, &b, sizeof(struct TrailingPadding2));124  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct TrailingPadding2' which does not have a unique object representation; consider comparing the members of the object manually125}126 127void Test_UnknownCount(size_t count) {128  struct TrailingPadding a, b;129  memcmp(&a, &b, count); // no-warning: unknown count value130}131 132void Test_ExplicitVoidCast(void) {133  struct TrailingPadding a, b;134  memcmp((void *)&a, (void *)&b,135         sizeof(struct TrailingPadding)); // no-warning: explicit cast136}137 138void TestArray_TrailingPadding(void) {139  struct TrailingPadding a[3], b[3];140  memcmp(a, b, 3 * sizeof(struct TrailingPadding));141  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct TrailingPadding' which does not have a unique object representation; consider comparing the members of the object manually142}143 144struct InnerPadding {145  char c;146  int i;147};148 149void Test_InnerPadding(void) {150  struct InnerPadding a, b;151  memcmp(&a, &b, sizeof(struct InnerPadding));152  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct InnerPadding' which does not have a unique object representation; consider comparing the members of the object manually153}154 155struct Bitfield_TrailingPaddingBytes {156  int x : 10;157  int y : 6;158};159 160void Test_Bitfield_TrailingPaddingBytes(void) {161  struct Bitfield_TrailingPaddingBytes a, b;162  memcmp(&a, &b, sizeof(struct S));163  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct Bitfield_TrailingPaddingBytes' which does not have a unique object representation; consider comparing the members of the object manually164}165 166struct Bitfield_TrailingPaddingBits {167  int x : 10;168  int y : 20;169};170 171void Test_Bitfield_TrailingPaddingBits(void) {172  struct Bitfield_TrailingPaddingBits a, b;173  memcmp(&a, &b, sizeof(struct Bitfield_TrailingPaddingBits));174  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct Bitfield_TrailingPaddingBits' which does not have a unique object representation; consider comparing the members of the object manually175}176 177struct Bitfield_InnerPaddingBits {178  char x : 2;179  int : 0;180  char y : 8;181};182 183void Test_Bitfield_InnerPaddingBits(void) {184  struct Bitfield_InnerPaddingBits a, b;185  memcmp(&a, &b, sizeof(struct Bitfield_InnerPaddingBits));186  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct Bitfield_InnerPaddingBits' which does not have a unique object representation; consider comparing the members of the object manually187}188 189struct Bitfield_NoPadding {190  int i : 10;191  int j : 10;192  int k : 10;193  int l : 2;194};195_Static_assert(sizeof(struct Bitfield_NoPadding) == sizeof(int),196               "Bit-fields should line up perfectly");197 198void Test_Bitfield_NoPadding(void) {199  struct Bitfield_NoPadding a, b;200  memcmp(&a, &b, sizeof(struct Bitfield_NoPadding)); // no-warning201}202 203struct Bitfield_TrailingUnnamed {204  int i[2];205  int : 0;206};207 208void Bitfield_TrailingUnnamed(void) {209  struct Bitfield_TrailingUnnamed a, b;210  memcmp(&a, &b, 2 * sizeof(int));                         // no-warning211  memcmp(&a, &b, sizeof(struct Bitfield_TrailingUnnamed)); // no-warning212}213 214struct PaddingAfterUnion {215  union {216    unsigned short a;217    short b;218  } x;219 220  int y;221};222 223void Test_PaddingAfterUnion(void) {224  struct PaddingAfterUnion a, b;225  memcmp(&a, &b, sizeof(struct PaddingAfterUnion));226  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct PaddingAfterUnion' which does not have a unique object representation; consider comparing the members of the object manually227}228 229struct Union_NoPadding {230  union {231    int a;232    unsigned int b;233  } x;234 235  int y;236};237 238void Test_Union_NoPadding(void) {239  struct Union_NoPadding a, b;240  memcmp(&a, &b, 2 * sizeof(int));241  memcmp(&a, &b, sizeof(struct Union_NoPadding));242}243 244union UnionWithPaddingInNestedStruct {245  int i;246 247  struct {248    int i;249    char c;250  } x;251};252 253void Test_UnionWithPaddingInNestedStruct(void) {254  union UnionWithPaddingInNestedStruct a, b;255  memcmp(&a, &b, sizeof(union UnionWithPaddingInNestedStruct));256  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'union UnionWithPaddingInNestedStruct' which does not have a unique object representation; consider comparing the members of the object manually257}258 259struct PaddingInNested {260  struct TrailingPadding x;261  char y;262};263 264void Test_PaddingInNested(void) {265  struct PaddingInNested a, b;266  memcmp(&a, &b, sizeof(struct PaddingInNested));267  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct PaddingInNested' which does not have a unique object representation; consider comparing the members of the object manually268}269 270struct PaddingAfterNested {271  struct {272    char a;273    char b;274  } x;275  int y;276};277 278void Test_PaddingAfterNested(void) {279  struct PaddingAfterNested a, b;280  memcmp(&a, &b, sizeof(struct PaddingAfterNested));281  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct PaddingAfterNested' which does not have a unique object representation; consider comparing the members of the object manually282}283 284struct AtomicMember {285  _Atomic(int) x;286};287 288void Test_AtomicMember(void) {289  // FIXME: this is a false positive as the list of objects with unique object290  // representations is incomplete.291  struct AtomicMember a, b;292  memcmp(&a, &b, sizeof(struct AtomicMember));293  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct AtomicMember' which does not have a unique object representation; consider comparing the members of the object manually294}295