| 1 | // RUN: %check_clang_tidy %s bugprone-suspicious-memset-usage %t |
| 2 | |
| 3 | void *memset(void *, int, __SIZE_TYPE__); |
| 4 | |
| 5 | namespace std { |
| 6 | using ::memset; |
| 7 | } |
| 8 | |
| 9 | template <typename T> |
| 10 | void mtempl(int *ptr) { |
| 11 | memset(ptr, '0', sizeof(T)); |
| 12 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage] |
| 13 | // CHECK-FIXES: memset(ptr, 0, sizeof(T)); |
| 14 | memset(ptr, 256, sizeof(T)); |
| 15 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage] |
| 16 | memset(0, sizeof(T), 0); |
| 17 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage] |
| 18 | // CHECK-FIXES: memset(0, 0, sizeof(T)); |
| 19 | memset(0, sizeof(int), 0); |
| 20 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage] |
| 21 | // CHECK-FIXES: memset(0, 0, sizeof(int)); |
| 22 | } |
| 23 | |
| 24 | void foo(int xsize, int ysize) { |
| 25 | int i[5] = {1, 2, 3, 4, 5}; |
| 26 | char ca[3] = {'a', 'b', 'c'}; |
| 27 | int *p = i; |
| 28 | int l = 5; |
| 29 | char z = '1'; |
| 30 | char *c = &z; |
| 31 | int v = 0; |
| 32 | |
| 33 | memset(p, '0', l); |
| 34 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage] |
| 35 | // CHECK-FIXES: memset(p, 0, l); |
| 36 | |
| 37 | memset(p, 0xabcd, l); |
| 38 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage] |
| 39 | |
| 40 | memset(p, sizeof(int), 0); |
| 41 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage] |
| 42 | // CHECK-FIXES: memset(p, 0, sizeof(int)); |
| 43 | std::memset(p, sizeof(int), 0x00); |
| 44 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage] |
| 45 | // CHECK-FIXES: std::memset(p, 0x00, sizeof(int)); |
| 46 | |
| 47 | #define M_CHAR_ZERO memset(p, '0', l); |
| 48 | M_CHAR_ZERO |
| 49 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage] |
| 50 | |
| 51 | #define M_OUTSIDE_RANGE memset(p, 0xabcd, l); |
| 52 | M_OUTSIDE_RANGE |
| 53 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage] |
| 54 | |
| 55 | #define M_ZERO_LENGTH memset(p, sizeof(int), 0); |
| 56 | M_ZERO_LENGTH |
| 57 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage] |
| 58 | |
| 59 | memset(p, '2', l); |
| 60 | memset(p, 0, l); |
| 61 | memset(c, '0', 1); |
| 62 | memset(ca, '0', sizeof(ca)); |
| 63 | |
| 64 | memset(p, 0x00, l); |
| 65 | mtempl<int>(ptr: p); |
| 66 | |
| 67 | memset(p, sizeof(int), v + 1); |
| 68 | memset(p, 0xcd, 1); |
| 69 | |
| 70 | // Don't warn when the fill char and the length are both known to be |
| 71 | // zero. No bug is possible. |
| 72 | memset(p, 0, v); |
| 73 | |
| 74 | // -1 is clearly not a length by virtue of being negative, so no warning |
| 75 | // despite v == 0. |
| 76 | memset(p, -1, v); |
| 77 | } |
| 78 | |
| 79 | void *memset(int); |
| 80 | void NoCrash() { |
| 81 | memset(1); |
| 82 | } |
| 83 | |