1// RUN: %check_clang_tidy %s bugprone-suspicious-memset-usage %t
2
3void *memset(void *, int, __SIZE_TYPE__);
4
5namespace std {
6 using ::memset;
7}
8
9template <typename T>
10void 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
24void 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
79void *memset(int);
80void NoCrash() {
81 memset(1);
82}
83

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-memset-usage.cpp