blob: 3e46a0a62235f148da1629618becb290d1f780ed [file] [log] [blame]
Shih-wei Liaof8fd82b2010-02-10 11:10:31 -08001// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
2// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
3// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
4// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
5
6struct s {
7 int data;
8 int data_array[10];
9};
10
11typedef struct {
12 int data;
13} STYPE;
14
15void g(char *p);
16void g1(struct s* p);
17
18// Array to pointer conversion. Array in the struct field.
19void f(void) {
20 int a[10];
21 int (*p)[10];
22 p = &a;
23 (*p)[3] = 1;
24
25 struct s d;
26 struct s *q;
27 q = &d;
28 q->data = 3;
29 d.data_array[9] = 17;
30}
31
32// StringLiteral in lvalue context and pointer to array type.
33// p: ElementRegion, q: StringRegion
34void f2() {
35 char *p = "/usr/local";
36 char (*q)[4];
37 q = &"abc";
38}
39
40// Typedef'ed struct definition.
41void f3() {
42 STYPE s;
43}
44
45// Initialize array with InitExprList.
46void f4() {
47 int a[] = { 1, 2, 3};
48 int b[3] = { 1, 2 };
49 struct s c[] = {{1,{1}}};
50}
51
52// Struct variable in lvalue context.
53// Assign UnknownVal to the whole struct.
54void f5() {
55 struct s data;
56 g1(&data);
57}
58
59// AllocaRegion test.
60void f6() {
61 char *p;
62 p = __builtin_alloca(10);
63 g(p);
64 char c = *p;
65 p[1] = 'a';
66 // Test if RegionStore::EvalBinOp converts the alloca region to element
67 // region.
68 p += 2;
69}
70
71struct s2;
72
73void g2(struct s2 *p);
74
75// Incomplete struct pointer used as function argument.
76void f7() {
77 struct s2 *p = __builtin_alloca(10);
78 g2(p);
79}
80
81// sizeof() is unsigned while -1 is signed in array index.
82void f8() {
83 int a[10];
84 a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
85}
86
87// Initialization of struct array elements.
88void f9() {
89 struct s a[10];
90}
91
92// Initializing array with string literal.
93void f10() {
94 char a1[4] = "abc";
95 char a3[6] = "abc";
96}
97
98// Retrieve the default value of element/field region.
99void f11() {
100 struct s a;
101 g1(&a);
102 if (a.data == 0) // no-warning
103 a.data = 1;
104}
105
106// Convert unsigned offset to signed when creating ElementRegion from
107// SymbolicRegion.
108void f12(int *list) {
109 unsigned i = 0;
110 list[i] = 1;
111}
112
113struct s1 {
114 struct s2 {
115 int d;
116 } e;
117};
118
119// The binding of a.e.d should not be removed. Test recursive subregion map
120// building: a->e, e->d. Only then 'a' could be added to live region roots.
121void f13(double timeout) {
122 struct s1 a;
123 a.e.d = (int) timeout;
124 if (a.e.d == 10)
125 a.e.d = 4;
126}
127
128struct s3 {
129 int a[2];
130};
131
132static struct s3 opt;
133
134// Test if the embedded array is retrieved correctly.
135void f14() {
136 struct s3 my_opt = opt;
137}
138
139void bar(int*);
140
141// Test if the array is correctly invalidated.
142void f15() {
143 int a[10];
144 bar(a);
145 if (a[1]) // no-warning
146 (void)1;
147}
148
149struct s3 p[1];
150
151// Code from postgresql.
152// Current cast logic of region store mistakenly leaves the final result region
153// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
154// assigns to 'a'.
155void f16(struct s3 *p) {
156 struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
157}
158
159void inv(struct s1 *);
160
161// Invalidate the struct field.
162void f17() {
163 struct s1 t;
164 int x;
165 inv(&t);
166 if (t.e.d)
167 x = 1;
168}
169
170void read(char*);
171
172void f18() {
173 char *q;
174 char *p = (char *) __builtin_alloca(10);
175 read(p);
176 q = p;
177 q++;
178 if (*q) { // no-warning
179 }
180}