Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++11 -analyze -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
      2 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++11 -analyze -analyzer-store=region -analyzer-constraints=range -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
      3 
      4 //===----------------------------------------------------------------------===//
      5 // Basic dead store checking (but in C++ mode).
      6 //===----------------------------------------------------------------------===//
      7 
      8 int j;
      9 void test1() {
     10   int x = 4;
     11 
     12   x = x + 1; // expected-warning{{never read}}
     13 
     14   switch (j) {
     15   case 1:
     16     throw 1;
     17     (void)x;
     18     break;
     19   }
     20 }
     21 
     22 //===----------------------------------------------------------------------===//
     23 // Dead store checking involving constructors.
     24 //===----------------------------------------------------------------------===//
     25 
     26 class Test2 {
     27   int &x;
     28 public:
     29   Test2(int &y) : x(y) {}
     30   ~Test2() { ++x; }
     31 };
     32 
     33 int test2(int x) {
     34   { Test2 a(x); } // no-warning
     35   return x;
     36 }
     37 
     38 //===----------------------------------------------------------------------===//
     39 // Dead store checking involving CXXTemporaryExprs
     40 //===----------------------------------------------------------------------===//
     41 
     42 namespace TestTemp {
     43   template<typename _Tp>
     44   class pencil {
     45   public:
     46     ~pencil() throw() {}
     47   };
     48   template<typename _Tp, typename _Number2> struct _Row_base {
     49     _Row_base(const pencil<_Tp>& x) {}
     50   };
     51   template<typename _Tp, typename _Number2 = TestTemp::pencil<_Tp> >
     52   class row : protected _Row_base<_Tp, _Number2>     {
     53     typedef _Row_base<_Tp, _Number2> _Base;
     54     typedef _Number2 pencil_type;
     55   public:
     56     explicit row(const pencil_type& __a = pencil_type()) : _Base(__a) {}
     57   };
     58 }
     59 
     60 void test2_b() {
     61   TestTemp::row<const char*> x; // no-warning
     62 }
     63 
     64 //===----------------------------------------------------------------------===//
     65 // Test references.
     66 //===----------------------------------------------------------------------===//
     67 
     68 void test3_a(int x) {
     69    x = x + 1; // expected-warning{{never read}}
     70 }
     71 
     72 void test3_b(int &x) {
     73   x = x + 1; // no-warninge
     74 }
     75 
     76 void test3_c(int x) {
     77   int &y = x;
     78   // Shows the limitation of dead stores tracking.  The write is really
     79   // dead since the value cannot escape the function.
     80   ++y; // no-warning
     81 }
     82 
     83 void test3_d(int &x) {
     84   int &y = x;
     85   ++y; // no-warning
     86 }
     87 
     88 void test3_e(int &x) {
     89   int &y = x;
     90 }
     91 
     92 //===----------------------------------------------------------------------===//
     93 // Dead stores involving 'new'
     94 //===----------------------------------------------------------------------===//
     95 
     96 static void test_new(unsigned n) {
     97   char **p = new char* [n]; // expected-warning{{never read}}
     98 }
     99 
    100 //===----------------------------------------------------------------------===//
    101 // Dead stores in namespaces.
    102 //===----------------------------------------------------------------------===//
    103 
    104 namespace foo {
    105   int test_4(int x) {
    106     x = 2; // expected-warning{{Value stored to 'x' is never read}}
    107     x = 2;
    108     return x;
    109   }
    110 }
    111 
    112 //===----------------------------------------------------------------------===//
    113 // Dead stores in with EH code.
    114 //===----------------------------------------------------------------------===//
    115 
    116 void test_5_Aux();
    117 int test_5() {
    118   int x = 0;
    119   try {
    120     x = 2; // no-warning
    121     test_5_Aux();
    122   }
    123   catch (int z) {
    124     return x + z;
    125   }
    126   return 1;
    127 }
    128 
    129 
    130 int test_6_aux(unsigned x);
    131 
    132 void test_6() {
    133   unsigned currDestLen = 0;  // no-warning
    134   try {
    135     while (test_6_aux(currDestLen)) {
    136       currDestLen += 2; // no-warning
    137     }
    138   }
    139   catch (void *) {}
    140 }
    141 
    142 void test_6b() {
    143   unsigned currDestLen = 0;  // no-warning
    144   try {
    145     while (test_6_aux(currDestLen)) {
    146       currDestLen += 2; // expected-warning {{Value stored to 'currDestLen' is never read}}
    147       break;
    148     }
    149   }
    150   catch (void *) {}
    151 }
    152 
    153 
    154 void testCXX11Using() {
    155   using Int = int;
    156   Int value;
    157   value = 1; // expected-warning {{never read}}
    158 }
    159 
    160 //===----------------------------------------------------------------------===//
    161 // Dead stores in template instantiations (do not warn).
    162 //===----------------------------------------------------------------------===//
    163 
    164 template <bool f> int radar13213575_testit(int i) {
    165   int x = 5+i; // warning: Value stored to 'x' during its initialization is never read
    166   int y = 7;
    167   if (f)
    168     return x;
    169   else
    170     return y;
    171 }
    172 
    173 int radar_13213575() {
    174   return radar13213575_testit<true>(5) + radar13213575_testit<false>(3);
    175 }
    176 
    177