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