f4a2713ac8
Change-Id: Ia40e9ffdf29b5dab2f122f673ff6802a58bc690f
241 lines
5 KiB
C++
241 lines
5 KiB
C++
// 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
|
|
// 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
|
|
|
|
#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); // expected-warning {{TRUE}}
|
|
return size == 0;
|
|
}
|
|
|
|
struct iterator {
|
|
int *impl;
|
|
|
|
iterator(int *p) : impl(p) {}
|
|
};
|
|
|
|
iterator begin() {
|
|
clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
|
|
return iterator(storage);
|
|
}
|
|
|
|
iterator end() {
|
|
clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
|
|
return iterator(storage+size);
|
|
}
|
|
|
|
typedef int *raw_iterator;
|
|
|
|
raw_iterator raw_begin() {
|
|
clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
|
|
return storage;
|
|
}
|
|
raw_iterator raw_end() {
|
|
clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
|
|
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); // expected-warning {{TRUE}}
|
|
}
|
|
};
|
|
|
|
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); // expected-warning {{TRUE}}
|
|
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); // expected-warning {{TRUE}}
|
|
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); // expected-warning {{TRUE}}
|
|
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); // expected-warning {{TRUE}}
|
|
return iterator{impl.begin().impl};
|
|
}
|
|
};
|
|
|
|
#endif // HEADER
|