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