blob: 16e006b345f226d6a46a5c5e6a48b1d11c839d4c [file] [log] [blame]
// 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
#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