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