array-struct.c revision c4bac8e376b98d633bb00ee5f510d5e58449753c
1033a07e5fca459ed184369cfee7c90d82367a93aTed Kremenek// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core.CastToStruct -analyzer-store=region -analyzer-constraints=basic -verify %s
2033a07e5fca459ed184369cfee7c90d82367a93aTed Kremenek// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core.CastToStruct -analyzer-store=region -analyzer-constraints=range -verify %s
3ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu
472e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xustruct s {
572e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu  int data;
672e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu  int data_array[10];
772e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu};
8ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu
9234a7d2bf50ba55496433f896577838407119e1aZhongxing Xutypedef struct {
10234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu  int data;
11234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu} STYPE;
12234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu
13918441255162c1a1c77c13752aaa1a3c43ac2ab9Zhongxing Xuvoid g(char *p);
1404b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xuvoid g1(struct s* p);
1504b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu
16661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Array to pointer conversion. Array in the struct field.
17ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xuvoid f(void) {
18ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  int a[10];
19ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  int (*p)[10];
20ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  p = &a;
21ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  (*p)[3] = 1;
22ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu
23ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  struct s d;
24ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  struct s *q;
25ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu  q = &d;
2672e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu  q->data = 3;
2772e1682bbdfd497ce838d648bb2cb6047c015f6fZhongxing Xu  d.data_array[9] = 17;
28ef8b28e9459e729b7bd8c826d204621b039611faZhongxing Xu}
292e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu
30661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// StringLiteral in lvalue context and pointer to array type.
31661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// p: ElementRegion, q: StringRegion
322e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xuvoid f2() {
332e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu  char *p = "/usr/local";
342e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu  char (*q)[4];
352e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu  q = &"abc";
362e971208f48a06b2880a28ba16389f3a0d4213dfZhongxing Xu}
37234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu
38661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Typedef'ed struct definition.
39234a7d2bf50ba55496433f896577838407119e1aZhongxing Xuvoid f3() {
40234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu  STYPE s;
41234a7d2bf50ba55496433f896577838407119e1aZhongxing Xu}
42df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xu
43661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Initialize array with InitExprList.
44df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xuvoid f4() {
45df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xu  int a[] = { 1, 2, 3};
46df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xu  int b[3] = { 1, 2 };
47b61f49cb3cd6ec8c9b17b48173370b3ce16f79b0Zhongxing Xu  struct s c[] = {{1,{1}}};
48df2aa1efbb940aa7bf5ef49235e1d7aff0d52128Zhongxing Xu}
4904b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu
50661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Struct variable in lvalue context.
515834ed6999980d90bd125dd1c8f9301e9d48f40cZhongxing Xu// Assign UnknownVal to the whole struct.
5204b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xuvoid f5() {
5304b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu  struct s data;
5404b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu  g1(&data);
5504b90bc00fc6ce8bc6c559e56220ceb77cdbccf6Zhongxing Xu}
56b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu
57661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// AllocaRegion test.
58b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xuvoid f6() {
59b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu  char *p;
60b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu  p = __builtin_alloca(10);
61918441255162c1a1c77c13752aaa1a3c43ac2ab9Zhongxing Xu  g(p);
62918441255162c1a1c77c13752aaa1a3c43ac2ab9Zhongxing Xu  char c = *p;
63b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu  p[1] = 'a';
642acc3992b61e71d30653bf19be2479a78e4cd7a1Zhongxing Xu  // Test if RegionStore::EvalBinOp converts the alloca region to element
652acc3992b61e71d30653bf19be2479a78e4cd7a1Zhongxing Xu  // region.
66262fd03ee934bebfbbfaabc14744427dd2e7a231Zhongxing Xu  p += 2;
67b670133b9e9fd7bce078674d782dad9d7c320f9dZhongxing Xu}
68fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu
69fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xustruct s2;
70fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu
71fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xuvoid g2(struct s2 *p);
72fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu
73661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Incomplete struct pointer used as function argument.
74fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xuvoid f7() {
75fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu  struct s2 *p = __builtin_alloca(10);
76fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu  g2(p);
77fb75b2583eb82dc42cb8e5bd3c1eda1c661eb76dZhongxing Xu}
7826134a1b596b9763a6975f15bf296a580b141114Zhongxing Xu
79661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// sizeof() is unsigned while -1 is signed in array index.
8026134a1b596b9763a6975f15bf296a580b141114Zhongxing Xuvoid f8() {
8126134a1b596b9763a6975f15bf296a580b141114Zhongxing Xu  int a[10];
8233d7cbfc0aa25dcc5d4470f39b374a1b9473a190Zhongxing Xu  a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
8326134a1b596b9763a6975f15bf296a580b141114Zhongxing Xu}
84617ff31664d7aaaf391272da30d3ae65d0426df7Zhongxing Xu
85661fc39abc5338e9dccd2f64467cac8bbe25c46aZhongxing Xu// Initialization of struct array elements.
86617ff31664d7aaaf391272da30d3ae65d0426df7Zhongxing Xuvoid f9() {
87617ff31664d7aaaf391272da30d3ae65d0426df7Zhongxing Xu  struct s a[10];
88617ff31664d7aaaf391272da30d3ae65d0426df7Zhongxing Xu}
8927cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu
9027cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu// Initializing array with string literal.
9127cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xuvoid f10() {
9227cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu  char a1[4] = "abc";
9327cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu  char a3[6] = "abc";
9427cae9e327eac1352e5159cba7feb72080ce1232Zhongxing Xu}
95562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu
96562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu// Retrieve the default value of element/field region.
97562c4d90418996c927f43e89250570d9967d6eccZhongxing Xuvoid f11() {
98562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu  struct s a;
99918441255162c1a1c77c13752aaa1a3c43ac2ab9Zhongxing Xu  g1(&a);
100562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu  if (a.data == 0) // no-warning
101562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu    a.data = 1;
102562c4d90418996c927f43e89250570d9967d6eccZhongxing Xu}
1033450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu
1043450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu// Convert unsigned offset to signed when creating ElementRegion from
1053450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu// SymbolicRegion.
1063450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xuvoid f12(int *list) {
1073450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu  unsigned i = 0;
1083450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu  list[i] = 1;
1093450a55f403f4b55120d4d5403ac4ebfab3a55d0Zhongxing Xu}
110c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu
111c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xustruct s1 {
112c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu  struct s2 {
113c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu    int d;
114c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu  } e;
115c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu};
116c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu
117c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu// The binding of a.e.d should not be removed. Test recursive subregion map
118c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu// building: a->e, e->d. Only then 'a' could be added to live region roots.
119c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xuvoid f13(double timeout) {
120c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu  struct s1 a;
121680523a91dd3351389667c8de17121ba7ae82673John McCall  a.e.d = (int) timeout;
122c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu  if (a.e.d == 10)
123c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu    a.e.d = 4;
124c57bc595cf7d4e3a5219d30fc20653d595e16ffeZhongxing Xu}
1253e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu
1263e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xustruct s3 {
1273e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu  int a[2];
1283e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu};
1293e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu
1303e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xustatic struct s3 opt;
1313e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu
1323e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu// Test if the embedded array is retrieved correctly.
1333e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xuvoid f14() {
1343e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu  struct s3 my_opt = opt;
1353e001f393d112a50e13c9a8f9a4c0d97f3f51cf4Zhongxing Xu}
136264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu
137264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xuvoid bar(int*);
138264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu
139264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu// Test if the array is correctly invalidated.
140264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xuvoid f15() {
141264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  int a[10];
142264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  bar(a);
143264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu  if (a[1]) // no-warning
1449668b1f6c87bd8d9af87e29900508a52584404efAnders Carlsson    (void)1;
145264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu}
1463f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu
1473f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xustruct s3 p[1];
1483f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu
1493f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu// Code from postgresql.
1503f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu// Current cast logic of region store mistakenly leaves the final result region
1513f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
1523f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu// assigns to 'a'.
1533f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xuvoid f16(struct s3 *p) {
154c4bac8e376b98d633bb00ee5f510d5e58449753cTed 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}}
1553f6978a3fefc16f203afbc64697fe04af329cf2bZhongxing Xu}
1566bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu
1576bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xuvoid inv(struct s1 *);
1586bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu
1596bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu// Invalidate the struct field.
1606bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xuvoid f17() {
1616bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu  struct s1 t;
1626bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu  int x;
1636bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu  inv(&t);
1646bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu  if (t.e.d)
1656bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu    x = 1;
1666bd8a521aa0ed803b8f1b0aea8ea61460285fa0bZhongxing Xu}
167a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu
168a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xuvoid read(char*);
169a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu
170a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xuvoid f18() {
171a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  char *q;
172a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  char *p = (char *) __builtin_alloca(10);
173a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  read(p);
174a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  q = p;
175a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  q++;
176a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  if (*q) { // no-warning
177a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu  }
178a03f157f154d0013e9c3eee261062959371aa868Zhongxing Xu}
179