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