Home | History | Annotate | Download | only in inlining
      1 // RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=false -verify %s
      2 // RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=true -DINLINE=1 -verify %s
      3 
      4 #ifndef HEADER
      5 
      6 void clang_analyzer_eval(bool);
      7 void clang_analyzer_checkInlined(bool);
      8 
      9 #define HEADER
     10 #include "containers.cpp"
     11 #undef HEADER
     12 
     13 void test() {
     14   MySet set(0);
     15 
     16   clang_analyzer_eval(set.isEmpty());
     17 #if INLINE
     18   // expected-warning@-2 {{TRUE}}
     19 #else
     20   // expected-warning@-4 {{UNKNOWN}}
     21 #endif
     22 
     23   clang_analyzer_eval(set.raw_begin() == set.raw_end());
     24 #if INLINE
     25   // expected-warning@-2 {{TRUE}}
     26 #else
     27   // expected-warning@-4 {{UNKNOWN}}
     28 #endif
     29 
     30   clang_analyzer_eval(set.begin().impl == set.end().impl);
     31 #if INLINE
     32   // expected-warning@-2 {{TRUE}}
     33 #else
     34   // expected-warning@-4 {{UNKNOWN}}
     35 #endif
     36 }
     37 
     38 void testSubclass(MySetSubclass &sub) {
     39   sub.useIterator(sub.begin());
     40 
     41   MySetSubclass local;
     42 }
     43 
     44 void testWrappers(BeginOnlySet &w1, IteratorStructOnlySet &w2,
     45                   IteratorTypedefOnlySet &w3, IteratorUsingOnlySet &w4) {
     46   BeginOnlySet local1;
     47   IteratorStructOnlySet local2;
     48   IteratorTypedefOnlySet local3;
     49   IteratorUsingOnlySet local4;
     50 
     51   clang_analyzer_eval(w1.begin().impl.impl == w1.begin().impl.impl);
     52 #if INLINE
     53   // expected-warning@-2 {{TRUE}}
     54 #else
     55   // expected-warning@-4 {{UNKNOWN}}
     56 #endif
     57 
     58   clang_analyzer_eval(w2.start().impl == w2.start().impl);
     59 #if INLINE
     60   // expected-warning@-2 {{TRUE}}
     61 #else
     62   // expected-warning@-4 {{UNKNOWN}}
     63 #endif
     64 
     65   clang_analyzer_eval(w3.start().impl == w3.start().impl);
     66 #if INLINE
     67   // expected-warning@-2 {{TRUE}}
     68 #else
     69   // expected-warning@-4 {{UNKNOWN}}
     70 #endif
     71 
     72   clang_analyzer_eval(w4.start().impl == w4.start().impl);
     73 #if INLINE
     74   // expected-warning@-2 {{TRUE}}
     75 #else
     76   // expected-warning@-4 {{UNKNOWN}}
     77 #endif
     78 }
     79 
     80 
     81 #else // HEADER
     82 
     83 #include "../Inputs/system-header-simulator-cxx.h"
     84 
     85 class MySet {
     86   int *storage;
     87   unsigned size;
     88 public:
     89   MySet() : storage(0), size(0) {
     90     clang_analyzer_checkInlined(true);
     91 #if INLINE
     92     // expected-warning@-2 {{TRUE}}
     93 #endif
     94   }
     95 
     96   MySet(unsigned n) : storage(new int[n]), size(n) {
     97     clang_analyzer_checkInlined(true);
     98 #if INLINE
     99     // expected-warning@-2 {{TRUE}}
    100 #endif
    101   }
    102 
    103   ~MySet() { delete[] storage; }
    104 
    105   bool isEmpty() {
    106     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    107     return size == 0;
    108   }
    109 
    110   struct iterator {
    111     int *impl;
    112 
    113     iterator(int *p) : impl(p) {}
    114   };
    115 
    116   iterator begin() {
    117     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    118     return iterator(storage);
    119   }
    120 
    121   iterator end() {
    122     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    123     return iterator(storage+size);
    124   }
    125 
    126   typedef int *raw_iterator;
    127 
    128   raw_iterator raw_begin() {
    129     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    130     return storage;
    131   }
    132   raw_iterator raw_end() {
    133     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    134     return storage + size;
    135   }
    136 };
    137 
    138 class MySetSubclass : public MySet {
    139 public:
    140   MySetSubclass() {
    141     clang_analyzer_checkInlined(true);
    142 #if INLINE
    143     // expected-warning@-2 {{TRUE}}
    144 #endif
    145   }
    146 
    147   void useIterator(iterator i) {
    148     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    149   }
    150 };
    151 
    152 class BeginOnlySet {
    153   MySet impl;
    154 public:
    155   struct IterImpl {
    156     MySet::iterator impl;
    157     typedef std::forward_iterator_tag iterator_category;
    158 
    159     IterImpl(MySet::iterator i) : impl(i) {
    160       clang_analyzer_checkInlined(true);
    161 #if INLINE
    162       // expected-warning@-2 {{TRUE}}
    163 #endif
    164     }
    165   };
    166 
    167   BeginOnlySet() {
    168     clang_analyzer_checkInlined(true);
    169 #if INLINE
    170     // expected-warning@-2 {{TRUE}}
    171 #endif
    172   }
    173 
    174   typedef IterImpl wrapped_iterator;
    175 
    176   wrapped_iterator begin() {
    177     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    178     return IterImpl(impl.begin());
    179   }
    180 };
    181 
    182 class IteratorTypedefOnlySet {
    183   MySet impl;
    184 public:
    185 
    186   IteratorTypedefOnlySet() {
    187     clang_analyzer_checkInlined(true);
    188 #if INLINE
    189     // expected-warning@-2 {{TRUE}}
    190 #endif
    191   }
    192 
    193   typedef MySet::iterator iterator;
    194 
    195   iterator start() {
    196     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    197     return impl.begin();
    198   }
    199 };
    200 
    201 class IteratorUsingOnlySet {
    202   MySet impl;
    203 public:
    204 
    205   IteratorUsingOnlySet() {
    206     clang_analyzer_checkInlined(true);
    207 #if INLINE
    208     // expected-warning@-2 {{TRUE}}
    209 #endif
    210   }
    211 
    212   using iterator = MySet::iterator;
    213 
    214   iterator start() {
    215     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    216     return impl.begin();
    217   }
    218 };
    219 
    220 class IteratorStructOnlySet {
    221   MySet impl;
    222 public:
    223 
    224   IteratorStructOnlySet() {
    225     clang_analyzer_checkInlined(true);
    226 #if INLINE
    227     // expected-warning@-2 {{TRUE}}
    228 #endif
    229   }
    230 
    231   struct iterator {
    232     int *impl;
    233   };
    234 
    235   iterator start() {
    236     clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
    237     return iterator{impl.begin().impl};
    238   }
    239 };
    240 
    241 #endif // HEADER
    242