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 6void clang_analyzer_eval(bool); 7void clang_analyzer_checkInlined(bool); 8 9#define HEADER 10#include "containers.cpp" 11#undef HEADER 12 13void 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 38void testSubclass(MySetSubclass &sub) { 39 sub.useIterator(sub.begin()); 40 41 MySetSubclass local; 42} 43 44void 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 85class MySet { 86 int *storage; 87 unsigned size; 88public: 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 153class MySetSubclass : public MySet { 154public: 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 170class BeginOnlySet { 171 MySet impl; 172public: 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 203class IteratorTypedefOnlySet { 204 MySet impl; 205public: 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 225class IteratorUsingOnlySet { 226 MySet impl; 227public: 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 247class IteratorStructOnlySet { 248 MySet impl; 249public: 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