Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
      2 
      3 void clang_analyzer_eval(bool);
      4 
      5 void usePointer(int * const *);
      6 void useReference(int * const &);
      7 
      8 void testPointer() {
      9   int x;
     10   int *p;
     11 
     12   p = &x;
     13   x = 42;
     14   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
     15   usePointer(&p);
     16   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
     17 
     18   p = &x;
     19   x = 42;
     20   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
     21   useReference(p);
     22   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
     23 
     24   int * const cp1 = &x;
     25   x = 42;
     26   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
     27   usePointer(&cp1);
     28   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
     29 
     30   int * const cp2 = &x;
     31   x = 42;
     32   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
     33   useReference(cp2);
     34   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
     35 }
     36 
     37 
     38 struct Wrapper {
     39   int *ptr;
     40 };
     41 
     42 void useStruct(Wrapper &w);
     43 void useConstStruct(const Wrapper &w);
     44 
     45 void testPointerStruct() {
     46   int x;
     47   Wrapper w;
     48 
     49   w.ptr = &x;
     50   x = 42;
     51   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
     52   useStruct(w);
     53   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
     54 
     55   w.ptr = &x;
     56   x = 42;
     57   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
     58   useConstStruct(w);
     59   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
     60 }
     61 
     62 
     63 struct RefWrapper {
     64   int &ref;
     65 };
     66 
     67 void useStruct(RefWrapper &w);
     68 void useConstStruct(const RefWrapper &w);
     69 
     70 void testReferenceStruct() {
     71   int x;
     72   RefWrapper w = { x };
     73 
     74   x = 42;
     75   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
     76   useStruct(w);
     77   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
     78 }
     79 
     80 // FIXME: This test is split into two functions because region invalidation
     81 // does not preserve reference bindings. <rdar://problem/13320347>
     82 void testConstReferenceStruct() {
     83   int x;
     84   RefWrapper w = { x };
     85 
     86   x = 42;
     87   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
     88   useConstStruct(w);
     89   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
     90 }
     91 
     92 
     93 void usePointerPure(int * const *) __attribute__((pure));
     94 void usePointerConst(int * const *) __attribute__((const));
     95 
     96 void testPureConst() {
     97   extern int global;
     98   int x;
     99   int *p;
    100 
    101   p = &x;
    102   x = 42;
    103   global = -5;
    104   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
    105   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
    106 
    107   usePointerPure(&p);
    108   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
    109   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
    110 
    111   usePointerConst(&p);
    112   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
    113   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
    114 
    115   usePointer(&p);
    116   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
    117   clang_analyzer_eval(global == -5); // expected-warning{{UNKNOWN}}
    118 }
    119 
    120 
    121