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