1cdc3a89d5de90b2299c56f4a46c3de590c5184d1Ted Kremenek// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.CastToStruct -analyzer-store=region -analyzer-constraints=range -verify %s
2ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu
372e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xustruct s {
472e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu  int data;
572e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu  int data_array[10];
672e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu};
7ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu
8234a7d2bf50ba55496433f896577838407119e1aZhongxing Xutypedef struct {
9234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu  int data;
10234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu} STYPE;
11234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu
12918441255162c1a1c77c13752aaa1a3c43ac2ab9Zhongxing Xuvoid g(char *p);
1304b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xuvoid g1(struct s* p);
1404b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu
15661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Array to pointer conversion. Array in the struct field.
16ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xuvoid f(void) {
17ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  int a[10];
18ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  int (*p)[10];
19ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  p = &a;
20ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  (*p)[3] = 1;
21ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu
22ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  struct s d;
23ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  struct s *q;
24ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  q = &d;
2572e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu  q->data = 3;
2672e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu  d.data_array[9] = 17;
27ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu}
282e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu
29661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// StringLiteral in lvalue context and pointer to array type.
30661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// p: ElementRegion, q: StringRegion
312e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xuvoid f2() {
322e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu  char *p = "/usr/local";
332e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu  char (*q)[4];
342e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu  q = &"abc";
352e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu}
36234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu
37661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Typedef'ed struct definition.
38234a7d2bf50ba55496433f896577838407119e1aZhongxing Xuvoid f3() {
39234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu  STYPE s;
40234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu}
41df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xu
42661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Initialize array with InitExprList.
43df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xuvoid f4() {
44df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xu  int a[] = { 1, 2, 3};
45df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xu  int b[3] = { 1, 2 };
46b61f49cb3cd6ec8c9b17b48173370b3ce16f79b0Zhongxing Xu  struct s c[] = {{1,{1}}};
47df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xu}
4804b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu
49661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Struct variable in lvalue context.
505834ed6999980d90bd125dd1c8f9301e9d48f40cZhongxing Xu// Assign UnknownVal to the whole struct.
5104b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xuvoid f5() {
5204b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu  struct s data;
5304b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu  g1(&data);
5404b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu}
55b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu
56661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// AllocaRegion test.
57b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xuvoid f6() {
58b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu  char *p;
59b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu  p = __builtin_alloca(10);
60918441255162c1a1c77c13752aaa1a3c43ac2ab9Zhongxing Xu  g(p);
61918441255162c1a1c77c13752aaa1a3c43ac2ab9Zhongxing Xu  char c = *p;
62b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu  p[1] = 'a';
632acc3992b61e71d30653bf19be2479a78e4cd7a1Zhongxing Xu  // Test if RegionStore::EvalBinOp converts the alloca region to element
642acc3992b61e71d30653bf19be2479a78e4cd7a1Zhongxing Xu  // region.
65262fd03ee934bebfbbfaabc14744427dd2e7a231Zhongxing Xu  p += 2;
66b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu}
67fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu
68fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xustruct s2;
69fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu
70fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xuvoid g2(struct s2 *p);
71fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu
72661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Incomplete struct pointer used as function argument.
73fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xuvoid f7() {
74fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu  struct s2 *p = __builtin_alloca(10);
75fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu  g2(p);
76fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu}
7726134a1b596b9763a6975f15bf296a580b141114Zhongxing Xu
78661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// sizeof() is unsigned while -1 is signed in array index.
7926134a1b596b9763a6975f15bf296a580b141114Zhongxing Xuvoid f8() {
8026134a1b596b9763a6975f15bf296a580b141114Zhongxing Xu  int a[10];
8133d7cbfc0aa25dcc5d4470f39b374a1b9473a190Zhongxing Xu  a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
8226134a1b596b9763a6975f15bf296a580b141114Zhongxing Xu}
83617ff31664d7aaaf391272da30d3ae65d0426df7Zhongxing Xu
84661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Initialization of struct array elements.
85617ff31664d7aaaf391272da30d3ae65d0426df7Zhongxing Xuvoid f9() {
86617ff31664d7aaaf391272da30d3ae65d0426df7Zhongxing Xu  struct s a[10];
87617ff31664d7aaaf391272da30d3ae65d0426df7Zhongxing Xu}
8827cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu
8927cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu// Initializing array with string literal.
9027cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xuvoid f10() {
9127cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu  char a1[4] = "abc";
9227cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu  char a3[6] = "abc";
9327cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu}
94562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu
95562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu// Retrieve the default value of element/field region.
96562c4d90418996c927f43e89250570d9967d6eccZhongxing Xuvoid f11() {
97562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu  struct s a;
98918441255162c1a1c77c13752aaa1a3c43ac2ab9Zhongxing Xu  g1(&a);
99562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu  if (a.data == 0) // no-warning
100562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu    a.data = 1;
101562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu}
1023450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu
1033450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu// Convert unsigned offset to signed when creating ElementRegion from
1043450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu// SymbolicRegion.
1053450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xuvoid f12(int *list) {
1063450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu  unsigned i = 0;
1073450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu  list[i] = 1;
1083450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu}
109c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu
110c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xustruct s1 {
111c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu  struct s2 {
112c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu    int d;
113c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu  } e;
114c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu};
115c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu
116c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu// The binding of a.e.d should not be removed. Test recursive subregion map
117c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu// building: a->e, e->d. Only then 'a' could be added to live region roots.
118c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xuvoid f13(double timeout) {
119c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu  struct s1 a;
120680523a91dd3351389667c8de17121ba7ae82673John McCall  a.e.d = (int) timeout;
121c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu  if (a.e.d == 10)
122c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu    a.e.d = 4;
123c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu}
1243e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu
1253e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xustruct s3 {
1263e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu  int a[2];
1273e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu};
1283e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu
1293e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xustatic struct s3 opt;
1303e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu
1313e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu// Test if the embedded array is retrieved correctly.
1323e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xuvoid f14() {
1333e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu  struct s3 my_opt = opt;
1343e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu}
135264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu
136264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xuvoid bar(int*);
137264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu
138264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu// Test if the array is correctly invalidated.
139264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xuvoid f15() {
140264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  int a[10];
141264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  bar(a);
142264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  if (a[1]) // no-warning
1439668b1f6c87bd8d9af87e29900508a52584404efAnders Carlsson    (void)1;
144264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu}
1453f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu
1463f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xustruct s3 p[1];
1473f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu
1483f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu// Code from postgresql.
1493f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu// Current cast logic of region store mistakenly leaves the final result region
1503f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
1513f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu// assigns to 'a'.
1523f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xuvoid f16(struct s3 *p) {
153c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  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}}
1543f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu}
1556bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu
1566bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xuvoid inv(struct s1 *);
1576bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu
1586bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu// Invalidate the struct field.
1596bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xuvoid f17() {
1606bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu  struct s1 t;
1616bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu  int x;
1626bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu  inv(&t);
1636bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu  if (t.e.d)
1646bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu    x = 1;
1656bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu}
166a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu
167a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xuvoid read(char*);
168a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu
169a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xuvoid f18() {
170a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  char *q;
171a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  char *p = (char *) __builtin_alloca(10);
172a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  read(p);
173a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  q = p;
174a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  q++;
175a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  if (*q) { // no-warning
176a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  }
177a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu}
17875c5e6df52e055537cf92687cf80fe644233381fJordan Rose
17975c5e6df52e055537cf92687cf80fe644233381fJordan Rose
18075c5e6df52e055537cf92687cf80fe644233381fJordan Rose// [PR13927] offsetof replacement macro flagged as "dereference of a null pointer"
18175c5e6df52e055537cf92687cf80fe644233381fJordan Roseint offset_of_data_array(void)
18275c5e6df52e055537cf92687cf80fe644233381fJordan Rose{
18375c5e6df52e055537cf92687cf80fe644233381fJordan Rose  return ((char *)&(((struct s*)0)->data_array)) - ((char *)0); // no-warning
18475c5e6df52e055537cf92687cf80fe644233381fJordan Rose}
18575c5e6df52e055537cf92687cf80fe644233381fJordan Rose
1860e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesint testPointerArithmeticOnVoid(void *bytes) {
1870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  int p = 0;
1880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (&bytes[0] == &bytes[1])
1890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return 6/p; // no-warning
1900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return 0;
1910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
1920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1930e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesint testRValueArraySubscriptExpr(void *bytes) {
1940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  int *p = (int*)&bytes[0];
1950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  *p = 0;
1960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (*(int*)&bytes[0] == 0)
1970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return 0;
1980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return 5/(*p); // no-warning
1990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
2000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
2010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
202