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