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