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