// 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 %s // 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 %s // 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 %s // 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 %s #ifndef HEADER void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool); #define HEADER #include "containers.cpp" #undef HEADER void test() { MySet set(0); clang_analyzer_eval(set.isEmpty()); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif clang_analyzer_eval(set.raw_begin() == set.raw_end()); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif clang_analyzer_eval(set.begin().impl == set.end().impl); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif } void testSubclass(MySetSubclass &sub) { sub.useIterator(sub.begin()); MySetSubclass local; } void testWrappers(BeginOnlySet &w1, IteratorStructOnlySet &w2, IteratorTypedefOnlySet &w3, IteratorUsingOnlySet &w4) { BeginOnlySet local1; IteratorStructOnlySet local2; IteratorTypedefOnlySet local3; IteratorUsingOnlySet local4; clang_analyzer_eval(w1.begin().impl.impl == w1.begin().impl.impl); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif clang_analyzer_eval(w2.start().impl == w2.start().impl); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif clang_analyzer_eval(w3.start().impl == w3.start().impl); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif clang_analyzer_eval(w4.start().impl == w4.start().impl); #if INLINE // expected-warning@-2 {{TRUE}} #else // expected-warning@-4 {{UNKNOWN}} #endif } #else // HEADER #include "../Inputs/system-header-simulator-cxx.h" class MySet { int *storage; unsigned size; public: MySet() : storage(0), size(0) { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } MySet(unsigned n) : storage(new int[n]), size(n) { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } ~MySet() { delete[] storage; } bool isEmpty() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return size == 0; } struct iterator { int *impl; iterator(int *p) : impl(p) {} }; iterator begin() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return iterator(storage); } iterator end() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return iterator(storage+size); } typedef int *raw_iterator; raw_iterator raw_begin() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return storage; } raw_iterator raw_end() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return storage + size; } }; class MySetSubclass : public MySet { public: MySetSubclass() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } void useIterator(iterator i) { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } }; class BeginOnlySet { MySet impl; public: struct IterImpl { MySet::iterator impl; typedef std::forward_iterator_tag iterator_category; IterImpl(MySet::iterator i) : impl(i) { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } }; BeginOnlySet() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } typedef IterImpl wrapped_iterator; wrapped_iterator begin() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return IterImpl(impl.begin()); } }; class IteratorTypedefOnlySet { MySet impl; public: IteratorTypedefOnlySet() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } typedef MySet::iterator iterator; iterator start() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return impl.begin(); } }; class IteratorUsingOnlySet { MySet impl; public: IteratorUsingOnlySet() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } using iterator = MySet::iterator; iterator start() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return impl.begin(); } }; class IteratorStructOnlySet { MySet impl; public: IteratorStructOnlySet() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif } struct iterator { int *impl; }; iterator start() { clang_analyzer_checkInlined(true); #if INLINE // expected-warning@-2 {{TRUE}} #endif return iterator{impl.begin().impl}; } }; #endif // HEADER