containers.cpp revision c63a460d78a7625ff38d2b3580f78030c44f07db
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 82 83class MySet { 84 int *storage; 85 unsigned size; 86public: 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 136class MySetSubclass : public MySet { 137public: 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 150class BeginOnlySet { 151 MySet impl; 152public: 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 175class IteratorTypedefOnlySet { 176 MySet impl; 177public: 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 194class IteratorUsingOnlySet { 195 MySet impl; 196public: 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 213class IteratorStructOnlySet { 214 MySet impl; 215public: 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