|
@@ -0,0 +1,234 @@
|
|
|
+// 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
|
|
|
+
|
|
|
+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;
|
|
|
+ IterImpl(MySet::iterator i) : impl(i) {
|
|
|
+ clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ 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
|