Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core.CastToStruct -analyzer-store=region -analyzer-constraints=basic -verify %s
      2 // RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core.CastToStruct -analyzer-store=region -analyzer-constraints=range -verify %s
      3 
      4 struct s {
      5   int data;
      6   int data_array[10];
      7 };
      8 
      9 typedef struct {
     10   int data;
     11 } STYPE;
     12 
     13 void g(char *p);
     14 void g1(struct s* p);
     15 
     16 // Array to pointer conversion. Array in the struct field.
     17 void 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
     32 void f2() {
     33   char *p = "/usr/local";
     34   char (*q)[4];
     35   q = &"abc";
     36 }
     37 
     38 // Typedef'ed struct definition.
     39 void f3() {
     40   STYPE s;
     41 }
     42 
     43 // Initialize array with InitExprList.
     44 void 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.
     52 void f5() {
     53   struct s data;
     54   g1(&data);
     55 }
     56 
     57 // AllocaRegion test.
     58 void 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 
     69 struct s2;
     70 
     71 void g2(struct s2 *p);
     72 
     73 // Incomplete struct pointer used as function argument.
     74 void f7() {
     75   struct s2 *p = __builtin_alloca(10);
     76   g2(p);
     77 }
     78 
     79 // sizeof() is unsigned while -1 is signed in array index.
     80 void f8() {
     81   int a[10];
     82   a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
     83 }
     84 
     85 // Initialization of struct array elements.
     86 void f9() {
     87   struct s a[10];
     88 }
     89 
     90 // Initializing array with string literal.
     91 void f10() {
     92   char a1[4] = "abc";
     93   char a3[6] = "abc";
     94 }
     95 
     96 // Retrieve the default value of element/field region.
     97 void 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.
    106 void f12(int *list) {
    107   unsigned i = 0;
    108   list[i] = 1;
    109 }
    110 
    111 struct 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.
    119 void 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 
    126 struct s3 {
    127   int a[2];
    128 };
    129 
    130 static struct s3 opt;
    131 
    132 // Test if the embedded array is retrieved correctly.
    133 void f14() {
    134   struct s3 my_opt = opt;
    135 }
    136 
    137 void bar(int*);
    138 
    139 // Test if the array is correctly invalidated.
    140 void f15() {
    141   int a[10];
    142   bar(a);
    143   if (a[1]) // no-warning
    144     (void)1;
    145 }
    146 
    147 struct 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'.
    153 void 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 
    157 void inv(struct s1 *);
    158 
    159 // Invalidate the struct field.
    160 void f17() {
    161   struct s1 t;
    162   int x;
    163   inv(&t);
    164   if (t.e.d)
    165     x = 1;
    166 }
    167 
    168 void read(char*);
    169 
    170 void 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