1 #include <string.h>
2 #include "analyzer-decls.h"
3
4 /* Zero-fill of uninitialized buffer. */
5
test_1(void)6 void test_1 (void)
7 {
8 char buf[256];
9 memset (buf, 0, 256);
10 __analyzer_eval (buf[42] == 0); /* { dg-warning "TRUE" } */
11 }
12
13 /* As above, but with __builtin_memset. */
14
test_1a(void)15 void test_1a (void)
16 {
17 char buf[256];
18 __builtin_memset (buf, 0, 256);
19 __analyzer_eval (buf[42] == 0); /* { dg-warning "TRUE" } */
20 }
21
22 /* Zero-fill of partially initialized buffer. */
23
test_2(void)24 void test_2 (void)
25 {
26 char buf[256];
27 buf[42] = 'A';
28 __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
29 memset (buf, 0, 256);
30 __analyzer_eval (buf[42] == '\0'); /* { dg-warning "TRUE" } */
31 }
32
33 /* A "memset" with known non-zero value. */
34
test_3(int val)35 void test_3 (int val)
36 {
37 char buf[256];
38 memset (buf, 'A', 256);
39 /* We currently merely mark such regions as "unknown", so querying
40 values within them yields UNKNOWN when ideally it would be TRUE. */
41 __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
42 /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
43 }
44
45 /* A "memset" with unknown value. */
46
test_4(int val)47 void test_4 (int val)
48 {
49 char buf[256];
50 memset (buf, val, 256);
51 /* We currently merely mark such regions as "unknown", so querying
52 values within them yields UNKNOWN when ideally it would be TRUE. */
53 __analyzer_eval (buf[42] == (char)val); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
54 /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
55 }
56
57 /* A "memset" with unknown num bytes. */
58
test_5(int n)59 void test_5 (int n)
60 {
61 char buf[256];
62 buf[42] = 'A';
63 __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
64 memset (buf, 0, n);
65
66 /* We can't know if buf[42] was written to or not. */
67 __analyzer_eval (buf[42] == 'A'); /* { dg-warning "UNKNOWN" } */
68 __analyzer_eval (buf[42] == '\0'); /* { dg-warning "UNKNOWN" } */
69 }
70
71 /* As test_5, but with "__builtin___memset_chk". */
72
test_5a(int n)73 void test_5a (int n)
74 {
75 char buf[256];
76 buf[42] = 'A';
77 __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
78 __builtin___memset_chk (buf, 0, n, __builtin_object_size (buf, 0));
79
80 /* We can't know if buf[42] was written to or not. */
81 __analyzer_eval (buf[42] == 'A'); /* { dg-warning "UNKNOWN" } */
82 __analyzer_eval (buf[42] == '\0'); /* { dg-warning "UNKNOWN" } */
83 }
84
85 /* A "memset" with unknown value, but with zero size. */
86
87 static size_t __attribute__((noinline))
get_zero(void)88 get_zero (void)
89 {
90 return 0;
91 }
92
test_6(int val)93 void test_6 (int val)
94 {
95 char buf[256];
96 buf[42] = 'A';
97 memset (buf, 'B', get_zero ());
98 __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
99 }
100
101 /* A "memset" of known size that's not the full buffer. */
102
test_7(void)103 void test_7 (void)
104 {
105 char buf[256];
106 buf[128] = 'A';
107 memset (buf, 0, 128);
108 /* We currently merely mark the whole region as "unknown", so querying
109 values within them yields UNKNOWN. */
110 __analyzer_eval (buf[127] == '\0'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
111 /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
112 __analyzer_eval (buf[128] == 'A'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
113 /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
114 }
115