Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
      2 // RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub -analyzer-store=region -verify -triple i686-apple-darwin9 %s
      3 
      4 // Used to trigger warnings for unreachable paths.
      5 #define WARN do { int a, b; int c = &b-&a; } while (0)
      6 
      7 void f1() {
      8   int a[10];
      9   int *p = a;
     10   ++p;
     11 }
     12 
     13 char* foo();
     14 
     15 void f2() {
     16   char *p = foo();
     17   ++p;
     18 }
     19 
     20 // This test case checks if we get the right rvalue type of a TypedViewRegion.
     21 // The ElementRegion's type depends on the array region's rvalue type. If it was
     22 // a pointer type, we would get a loc::SymbolVal for '*p'.
     23 void* memchr();
     24 static int
     25 domain_port (const char *domain_b, const char *domain_e,
     26              const char **domain_e_ptr)
     27 {
     28   int port = 0;
     29 
     30   const char *p;
     31   const char *colon = memchr (domain_b, ':', domain_e - domain_b);
     32 
     33   for (p = colon + 1; p < domain_e ; p++)
     34     port = 10 * port + (*p - '0');
     35   return port;
     36 }
     37 
     38 void f3() {
     39   int x, y;
     40   int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result.}}
     41 
     42   int a[10];
     43   int *p = &a[2];
     44   int *q = &a[8];
     45   d = q-p; // no-warning
     46 }
     47 
     48 void f4() {
     49   int *p;
     50   p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms.}}
     51 }
     52 
     53 void f5() {
     54   int x, y;
     55   int *p;
     56   p = &x + 1;  // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous.}}
     57 
     58   int a[10];
     59   p = a + 1; // no-warning
     60 }
     61 
     62 // Allow arithmetic on different symbolic regions.
     63 void f6(int *p, int *q) {
     64   int d = q - p; // no-warning
     65 }
     66 
     67 void null_operand(int *a) {
     68 start:
     69   // LHS is a label, RHS is NULL
     70   if (&&start == 0)
     71     WARN; // no-warning
     72   if (&&start <  0)
     73     WARN; // no-warning
     74   if (&&start <= 0)
     75     WARN; // no-warning
     76   if (!(&&start != 0))
     77     WARN; // no-warning
     78   if (!(&&start >  0))
     79     WARN; // no-warning
     80   if (!(&&start >= 0))
     81     WARN; // no-warning
     82   if (!(&&start - 0))
     83     WARN; // no-warning
     84 
     85   // LHS is a non-symbolic value, RHS is NULL
     86   if (&a == 0)
     87     WARN; // no-warning
     88   if (&a <  0)
     89     WARN; // no-warning
     90   if (&a <= 0)
     91     WARN; // no-warning
     92   if (!(&a != 0))
     93     WARN; // no-warning
     94   if (!(&a >  0))
     95     WARN; // no-warning
     96   if (!(&a >= 0))
     97     WARN; // no-warning
     98 
     99   if (!(&a - 0)) // expected-warning{{Pointer arithmetic done on non-array variables}}
    100     WARN; // no-warning
    101 
    102   // LHS is NULL, RHS is non-symbolic
    103   // The same code is used for labels and non-symbolic values.
    104   if (0 == &a)
    105     WARN; // no-warning
    106   if (0 >  &a)
    107     WARN; // no-warning
    108   if (0 >= &a)
    109     WARN; // no-warning
    110   if (!(0 != &a))
    111     WARN; // no-warning
    112   if (!(0 <  &a))
    113     WARN; // no-warning
    114   if (!(0 <= &a))
    115     WARN; // no-warning
    116 
    117   // LHS is a symbolic value, RHS is NULL
    118   if (a == 0)
    119     WARN; // expected-warning{{}}
    120   if (a <  0)
    121     WARN; // no-warning
    122   if (a <= 0)
    123     WARN; // expected-warning{{}}
    124   if (!(a != 0))
    125     WARN; // expected-warning{{}}
    126   if (!(a >  0))
    127     WARN; // expected-warning{{}}
    128   if (!(a >= 0))
    129     WARN; // no-warning
    130   if (!(a - 0))
    131     WARN; // expected-warning{{}}
    132 
    133   // LHS is NULL, RHS is a symbolic value
    134   if (0 == a)
    135     WARN; // expected-warning{{}}
    136   if (0 >  a)
    137     WARN; // no-warning
    138   if (0 >= a)
    139     WARN; // expected-warning{{}}
    140   if (!(0 != a))
    141     WARN; // expected-warning{{}}
    142   if (!(0 <  a))
    143     WARN; // expected-warning{{}}
    144   if (!(0 <= a))
    145     WARN; // no-warning
    146 }
    147 
    148 void const_locs() {
    149   char *a = (char*)0x1000;
    150   char *b = (char*)0x1100;
    151 start:
    152   if (a==b)
    153     WARN; // no-warning
    154   if (!(a!=b))
    155     WARN; // no-warning
    156   if (a>b)
    157     WARN; // no-warning
    158   if (b<a)
    159     WARN; // no-warning
    160   if (a>=b)
    161     WARN; // no-warning
    162   if (b<=a)
    163     WARN; // no-warning
    164   if (b-a != 0x100)
    165     WARN; // no-warning
    166 
    167   if (&&start == a)
    168     WARN; // expected-warning{{}}
    169   if (a == &&start)
    170     WARN; // expected-warning{{}}
    171   if (&a == (char**)a)
    172     WARN; // expected-warning{{}}
    173   if ((char**)a == &a)
    174     WARN; // expected-warning{{}}
    175 }
    176 
    177 void array_matching_types() {
    178   int array[10];
    179   int *a = &array[2];
    180   int *b = &array[5];
    181 
    182   if (a==b)
    183     WARN; // no-warning
    184   if (!(a!=b))
    185     WARN; // no-warning
    186   if (a>b)
    187     WARN; // no-warning
    188   if (b<a)
    189     WARN; // no-warning
    190   if (a>=b)
    191     WARN; // no-warning
    192   if (b<=a)
    193     WARN; // no-warning
    194   if ((b-a) == 0)
    195     WARN; // no-warning
    196 }
    197 
    198 // This takes a different code path than array_matching_types()
    199 void array_different_types() {
    200   int array[10];
    201   int *a = &array[2];
    202   char *b = (char*)&array[5];
    203 
    204   if (a==b) // expected-warning{{comparison of distinct pointer types}}
    205     WARN; // no-warning
    206   if (!(a!=b)) // expected-warning{{comparison of distinct pointer types}}
    207     WARN; // no-warning
    208   if (a>b) // expected-warning{{comparison of distinct pointer types}}
    209     WARN; // no-warning
    210   if (b<a) // expected-warning{{comparison of distinct pointer types}}
    211     WARN; // no-warning
    212   if (a>=b) // expected-warning{{comparison of distinct pointer types}}
    213     WARN; // no-warning
    214   if (b<=a) // expected-warning{{comparison of distinct pointer types}}
    215     WARN; // no-warning
    216 }
    217 
    218 struct test { int x; int y; };
    219 void struct_fields() {
    220   struct test a, b;
    221 
    222   if (&a.x == &a.y)
    223     WARN; // no-warning
    224   if (!(&a.x != &a.y))
    225     WARN; // no-warning
    226   if (&a.x > &a.y)
    227     WARN; // no-warning
    228   if (&a.y < &a.x)
    229     WARN; // no-warning
    230   if (&a.x >= &a.y)
    231     WARN; // no-warning
    232   if (&a.y <= &a.x)
    233     WARN; // no-warning
    234 
    235   if (&a.x == &b.x)
    236     WARN; // no-warning
    237   if (!(&a.x != &b.x))
    238     WARN; // no-warning
    239   if (&a.x > &b.x)
    240     WARN; // expected-warning{{}}
    241   if (&b.x < &a.x)
    242     WARN; // expected-warning{{}}
    243   if (&a.x >= &b.x)
    244     WARN; // expected-warning{{}}
    245   if (&b.x <= &a.x)
    246     WARN; // expected-warning{{}}
    247 }
    248 
    249 void mixed_region_types() {
    250   struct test s;
    251   int array[2];
    252   void *a = &array, *b = &s;
    253 
    254   if (&a == &b)
    255     WARN; // no-warning
    256   if (!(&a != &b))
    257     WARN; // no-warning
    258   if (&a > &b)
    259     WARN; // expected-warning{{}}
    260   if (&b < &a)
    261     WARN; // expected-warning{{}}
    262   if (&a >= &b)
    263     WARN; // expected-warning{{}}
    264   if (&b <= &a)
    265     WARN; // expected-warning{{}}
    266 }
    267 
    268 void symbolic_region(int *p) {
    269   int a;
    270 
    271   if (&a == p)
    272     WARN; // no-warning
    273   if (&a != p)
    274     WARN; // expected-warning{{}}
    275   if (&a > p)
    276     WARN; // expected-warning{{}}
    277   if (&a < p)
    278     WARN; // expected-warning{{}}
    279   if (&a >= p)
    280     WARN; // expected-warning{{}}
    281   if (&a <= p)
    282     WARN; // expected-warning{{}}
    283 }
    284 
    285 void PR7527 (int *p) {
    286   if (((int) p) & 1) // not crash
    287     return;
    288 }
    289