|
@@ -1,9 +1,25 @@
|
|
|
-// RUN: %clang_analyze_cc1 -Wno-non-pod-varargs -analyzer-checker=core,cplusplus,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++03 -analyzer-config eagerly-assume=false %s
|
|
|
-// RUN: %clang_analyze_cc1 -Wno-non-pod-varargs -analyzer-checker=core,cplusplus,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++11 -analyzer-config eagerly-assume=false %s
|
|
|
-// RUN: %clang_analyze_cc1 -Wno-non-pod-varargs -analyzer-checker=core,cplusplus,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true,c++-temp-dtor-inlining=true -analyzer-config eagerly-assume=false %s -std=c++11
|
|
|
-// RUN: %clang_analyze_cc1 -Wno-non-pod-varargs -analyzer-checker=core,cplusplus,debug.ExprInspection -DTEMPORARY_DTORS -w -analyzer-config cfg-temporary-dtors=true,c++-temp-dtor-inlining=true -analyzer-config eagerly-assume=false %s -std=c++17
|
|
|
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\
|
|
|
+// RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\
|
|
|
+// RUN: -analyzer-config eagerly-assume=false -verify %s\
|
|
|
+// RUN: -std=c++03 -analyzer-config cfg-temporary-dtors=false
|
|
|
+
|
|
|
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\
|
|
|
+// RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\
|
|
|
+// RUN: -analyzer-config eagerly-assume=false -verify %s\
|
|
|
+// RUN: -std=c++11 -analyzer-config cfg-temporary-dtors=false
|
|
|
+
|
|
|
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\
|
|
|
+// RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\
|
|
|
+// RUN: -analyzer-config eagerly-assume=false -verify %s\
|
|
|
+// RUN: -std=c++11 -analyzer-config cfg-temporary-dtors=true\
|
|
|
+// RUN: -DTEMPORARY_DTORS
|
|
|
+
|
|
|
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\
|
|
|
+// RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\
|
|
|
+// RUN: -analyzer-config eagerly-assume=false -verify %s\
|
|
|
+// RUN: -std=c++17 -analyzer-config cfg-temporary-dtors=true\
|
|
|
+// RUN: -DTEMPORARY_DTORS
|
|
|
|
|
|
-// Note: The C++17 run-line doesn't -verify yet - it is a no-crash test.
|
|
|
|
|
|
extern bool clang_analyzer_eval(bool);
|
|
|
extern bool clang_analyzer_warnIfReached();
|
|
@@ -450,7 +466,16 @@ namespace destructors {
|
|
|
}
|
|
|
|
|
|
#if __cplusplus >= 201103L
|
|
|
- CtorWithNoReturnDtor returnNoReturnDtor() {
|
|
|
+ struct CtorWithNoReturnDtor2 {
|
|
|
+ CtorWithNoReturnDtor2() = default;
|
|
|
+
|
|
|
+ CtorWithNoReturnDtor2(int x) {
|
|
|
+ clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
|
|
|
+ }
|
|
|
+
|
|
|
+ ~CtorWithNoReturnDtor2() __attribute__((noreturn));
|
|
|
+ };
|
|
|
+ CtorWithNoReturnDtor2 returnNoReturnDtor() {
|
|
|
return {1}; // no-crash
|
|
|
}
|
|
|
#endif
|
|
@@ -805,7 +830,12 @@ void test_ternary_temporary_with_copy(int coin) {
|
|
|
// On each branch the variable is constructed directly.
|
|
|
if (coin) {
|
|
|
clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
|
|
|
+#if __cplusplus < 201703L
|
|
|
clang_analyzer_eval(y == 1); // expected-warning{{TRUE}}
|
|
|
+#else
|
|
|
+ // FIXME: Destructor called twice in C++17?
|
|
|
+ clang_analyzer_eval(y == 2); // expected-warning{{TRUE}}
|
|
|
+#endif
|
|
|
clang_analyzer_eval(z == 0); // expected-warning{{TRUE}}
|
|
|
clang_analyzer_eval(w == 0); // expected-warning{{TRUE}}
|
|
|
|
|
@@ -813,7 +843,12 @@ void test_ternary_temporary_with_copy(int coin) {
|
|
|
clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
|
|
|
clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}
|
|
|
clang_analyzer_eval(z == 1); // expected-warning{{TRUE}}
|
|
|
+#if __cplusplus < 201703L
|
|
|
clang_analyzer_eval(w == 1); // expected-warning{{TRUE}}
|
|
|
+#else
|
|
|
+ // FIXME: Destructor called twice in C++17?
|
|
|
+ clang_analyzer_eval(w == 2); // expected-warning{{TRUE}}
|
|
|
+#endif
|
|
|
}
|
|
|
}
|
|
|
} // namespace test_match_constructors_and_destructors
|
|
@@ -865,9 +900,12 @@ class C {
|
|
|
public:
|
|
|
~C() {
|
|
|
glob = 1;
|
|
|
+ // FIXME: Why is destructor not inlined in C++17
|
|
|
clang_analyzer_checkInlined(true);
|
|
|
#ifdef TEMPORARY_DTORS
|
|
|
- // expected-warning@-2{{TRUE}}
|
|
|
+#if __cplusplus < 201703L
|
|
|
+ // expected-warning@-3{{TRUE}}
|
|
|
+#endif
|
|
|
#endif
|
|
|
}
|
|
|
};
|
|
@@ -886,11 +924,16 @@ void test(int coin) {
|
|
|
// temporaries returned from functions, so we took the wrong branch.
|
|
|
coin && is(get()); // no-crash
|
|
|
if (coin) {
|
|
|
+ // FIXME: Why is destructor not inlined in C++17
|
|
|
clang_analyzer_eval(glob);
|
|
|
#ifdef TEMPORARY_DTORS
|
|
|
- // expected-warning@-2{{TRUE}}
|
|
|
+#if __cplusplus < 201703L
|
|
|
+ // expected-warning@-3{{TRUE}}
|
|
|
+#else
|
|
|
+ // expected-warning@-5{{UNKNOWN}}
|
|
|
+#endif
|
|
|
#else
|
|
|
- // expected-warning@-4{{UNKNOWN}}
|
|
|
+ // expected-warning@-8{{UNKNOWN}}
|
|
|
#endif
|
|
|
} else {
|
|
|
// The destructor is not called on this branch.
|
|
@@ -1012,11 +1055,16 @@ void foo(void (*bar4)(S)) {
|
|
|
#endif
|
|
|
|
|
|
bar2(S(2));
|
|
|
+ // FIXME: Why are we losing information in C++17?
|
|
|
clang_analyzer_eval(glob == 2);
|
|
|
#ifdef TEMPORARY_DTORS
|
|
|
- // expected-warning@-2{{TRUE}}
|
|
|
+#if __cplusplus < 201703L
|
|
|
+ // expected-warning@-3{{TRUE}}
|
|
|
#else
|
|
|
- // expected-warning@-4{{UNKNOWN}}
|
|
|
+ // expected-warning@-5{{UNKNOWN}}
|
|
|
+#endif
|
|
|
+#else
|
|
|
+ // expected-warning@-8{{UNKNOWN}}
|
|
|
#endif
|
|
|
|
|
|
C *c = new D();
|
|
@@ -1172,3 +1220,29 @@ void test() {
|
|
|
c.foo();
|
|
|
}
|
|
|
} // namespace union_indirect_field_crash
|
|
|
+
|
|
|
+namespace return_from_top_frame {
|
|
|
+struct S {
|
|
|
+ int *p;
|
|
|
+ S() { p = new int; }
|
|
|
+ S(S &&s) : p(s.p) { s.p = 0; }
|
|
|
+ ~S(); // Presumably releases 'p'.
|
|
|
+};
|
|
|
+
|
|
|
+S foo() {
|
|
|
+ S s;
|
|
|
+ return s;
|
|
|
+}
|
|
|
+
|
|
|
+S bar1() {
|
|
|
+ return foo(); // no-warning
|
|
|
+}
|
|
|
+
|
|
|
+S bar2() {
|
|
|
+ return S();
|
|
|
+}
|
|
|
+
|
|
|
+S bar3(int coin) {
|
|
|
+ return coin ? S() : foo(); // no-warning
|
|
|
+}
|
|
|
+} // namespace return_from_top_frame
|