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