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 82 83 class MySet { 84 int *storage; 85 unsigned size; 86 public: 87 MySet() : storage(0), size(0) { 88 clang_analyzer_checkInlined(true); 89 #if INLINE 90 // expected-warning@-2 {{TRUE}} 91 #endif 92 } 93 94 MySet(unsigned n) : storage(new int[n]), size(n) { 95 clang_analyzer_checkInlined(true); 96 #if INLINE 97 // expected-warning@-2 {{TRUE}} 98 #endif 99 } 100 101 ~MySet() { delete[] storage; } 102 103 bool isEmpty() { 104 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 105 return size == 0; 106 } 107 108 struct iterator { 109 int *impl; 110 111 iterator(int *p) : impl(p) {} 112 }; 113 114 iterator begin() { 115 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 116 return iterator(storage); 117 } 118 119 iterator end() { 120 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 121 return iterator(storage+size); 122 } 123 124 typedef int *raw_iterator; 125 126 raw_iterator raw_begin() { 127 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 128 return storage; 129 } 130 raw_iterator raw_end() { 131 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 132 return storage + size; 133 } 134 }; 135 136 class MySetSubclass : public MySet { 137 public: 138 MySetSubclass() { 139 clang_analyzer_checkInlined(true); 140 #if INLINE 141 // expected-warning@-2 {{TRUE}} 142 #endif 143 } 144 145 void useIterator(iterator i) { 146 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 147 } 148 }; 149 150 class BeginOnlySet { 151 MySet impl; 152 public: 153 struct IterImpl { 154 MySet::iterator impl; 155 IterImpl(MySet::iterator i) : impl(i) { 156 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 157 } 158 }; 159 160 BeginOnlySet() { 161 clang_analyzer_checkInlined(true); 162 #if INLINE 163 // expected-warning@-2 {{TRUE}} 164 #endif 165 } 166 167 typedef IterImpl wrapped_iterator; 168 169 wrapped_iterator begin() { 170 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 171 return IterImpl(impl.begin()); 172 } 173 }; 174 175 class IteratorTypedefOnlySet { 176 MySet impl; 177 public: 178 179 IteratorTypedefOnlySet() { 180 clang_analyzer_checkInlined(true); 181 #if INLINE 182 // expected-warning@-2 {{TRUE}} 183 #endif 184 } 185 186 typedef MySet::iterator iterator; 187 188 iterator start() { 189 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 190 return impl.begin(); 191 } 192 }; 193 194 class IteratorUsingOnlySet { 195 MySet impl; 196 public: 197 198 IteratorUsingOnlySet() { 199 clang_analyzer_checkInlined(true); 200 #if INLINE 201 // expected-warning@-2 {{TRUE}} 202 #endif 203 } 204 205 using iterator = MySet::iterator; 206 207 iterator start() { 208 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 209 return impl.begin(); 210 } 211 }; 212 213 class IteratorStructOnlySet { 214 MySet impl; 215 public: 216 217 IteratorStructOnlySet() { 218 clang_analyzer_checkInlined(true); 219 #if INLINE 220 // expected-warning@-2 {{TRUE}} 221 #endif 222 } 223 224 struct iterator { 225 int *impl; 226 }; 227 228 iterator start() { 229 clang_analyzer_checkInlined(true); // expected-warning {{TRUE}} 230 return iterator{impl.begin().impl}; 231 } 232 }; 233 234 #endif 235