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);
    107     #if INLINE
    108         // expected-warning@-2 {{TRUE}}
    109     #endif
    110     return size == 0;
    111   }
    112 
    113   struct iterator {
    114     int *impl;
    115 
    116     iterator(int *p) : impl(p) {}
    117   };
    118 
    119   iterator begin() {
    120     clang_analyzer_checkInlined(true);
    121     #if INLINE
    122         // expected-warning@-2 {{TRUE}}
    123     #endif
    124     return iterator(storage);
    125   }
    126 
    127   iterator end() {
    128     clang_analyzer_checkInlined(true);
    129     #if INLINE
    130         // expected-warning@-2 {{TRUE}}
    131     #endif
    132     return iterator(storage+size);
    133   }
    134 
    135   typedef int *raw_iterator;
    136 
    137   raw_iterator raw_begin() {
    138     clang_analyzer_checkInlined(true);
    139     #if INLINE
    140         // expected-warning@-2 {{TRUE}}
    141     #endif
    142     return storage;
    143   }
    144   raw_iterator raw_end() {
    145     clang_analyzer_checkInlined(true);
    146     #if INLINE
    147         // expected-warning@-2 {{TRUE}}
    148     #endif
    149     return storage + size;
    150   }
    151 };
    152 
    153 class MySetSubclass : public MySet {
    154 public:
    155   MySetSubclass() {
    156     clang_analyzer_checkInlined(true);
    157 #if INLINE
    158     // expected-warning@-2 {{TRUE}}
    159 #endif
    160   }
    161 
    162   void useIterator(iterator i) {
    163     clang_analyzer_checkInlined(true);
    164     #if INLINE
    165         // expected-warning@-2 {{TRUE}}
    166     #endif
    167   }
    168 };
    169 
    170 class BeginOnlySet {
    171   MySet impl;
    172 public:
    173   struct IterImpl {
    174     MySet::iterator impl;
    175     typedef std::forward_iterator_tag iterator_category;
    176 
    177     IterImpl(MySet::iterator i) : impl(i) {
    178       clang_analyzer_checkInlined(true);
    179 #if INLINE
    180       // expected-warning@-2 {{TRUE}}
    181 #endif
    182     }
    183   };
    184 
    185   BeginOnlySet() {
    186     clang_analyzer_checkInlined(true);
    187 #if INLINE
    188     // expected-warning@-2 {{TRUE}}
    189 #endif
    190   }
    191 
    192   typedef IterImpl wrapped_iterator;
    193 
    194   wrapped_iterator begin() {
    195     clang_analyzer_checkInlined(true);
    196     #if INLINE
    197         // expected-warning@-2 {{TRUE}}
    198     #endif
    199     return IterImpl(impl.begin());
    200   }
    201 };
    202 
    203 class IteratorTypedefOnlySet {
    204   MySet impl;
    205 public:
    206 
    207   IteratorTypedefOnlySet() {
    208     clang_analyzer_checkInlined(true);
    209 #if INLINE
    210     // expected-warning@-2 {{TRUE}}
    211 #endif
    212   }
    213 
    214   typedef MySet::iterator iterator;
    215 
    216   iterator start() {
    217     clang_analyzer_checkInlined(true);
    218 #if INLINE
    219     // expected-warning@-2 {{TRUE}}
    220 #endif
    221     return impl.begin();
    222   }
    223 };
    224 
    225 class IteratorUsingOnlySet {
    226   MySet impl;
    227 public:
    228 
    229   IteratorUsingOnlySet() {
    230     clang_analyzer_checkInlined(true);
    231 #if INLINE
    232     // expected-warning@-2 {{TRUE}}
    233 #endif
    234   }
    235 
    236   using iterator = MySet::iterator;
    237 
    238   iterator start() {
    239     clang_analyzer_checkInlined(true);
    240     #if INLINE
    241         // expected-warning@-2 {{TRUE}}
    242     #endif
    243     return impl.begin();
    244   }
    245 };
    246 
    247 class IteratorStructOnlySet {
    248   MySet impl;
    249 public:
    250 
    251   IteratorStructOnlySet() {
    252     clang_analyzer_checkInlined(true);
    253 #if INLINE
    254     // expected-warning@-2 {{TRUE}}
    255 #endif
    256   }
    257 
    258   struct iterator {
    259     int *impl;
    260   };
    261 
    262   iterator start() {
    263     clang_analyzer_checkInlined(true);
    264     #if INLINE
    265         // expected-warning@-2 {{TRUE}}
    266     #endif
    267     return iterator{impl.begin().impl};
    268   }
    269 };
    270 
    271 #endif // HEADER
    272