summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/temporaries.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis/temporaries.cpp')
-rw-r--r--clang/test/Analysis/temporaries.cpp164
1 files changed, 162 insertions, 2 deletions
diff --git a/clang/test/Analysis/temporaries.cpp b/clang/test/Analysis/temporaries.cpp
index 9e2d45f693a..a1fa0368be1 100644
--- a/clang/test/Analysis/temporaries.cpp
+++ b/clang/test/Analysis/temporaries.cpp
@@ -1,9 +1,10 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++03 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config cfg-temporary-dtors=false -verify -w -std=c++11 %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s -std=c++11
extern bool clang_analyzer_eval(bool);
extern bool clang_analyzer_warnIfReached();
+void clang_analyzer_checkInlined(bool);
struct Trivial {
Trivial(int x) : value(x) {}
@@ -422,6 +423,10 @@ namespace destructors {
struct CtorWithNoReturnDtor {
CtorWithNoReturnDtor() = default;
+ CtorWithNoReturnDtor(int x) {
+ clang_analyzer_checkInlined(false); // no-warning
+ }
+
~CtorWithNoReturnDtor() __attribute__((noreturn));
};
@@ -439,6 +444,12 @@ namespace destructors {
clang_analyzer_warnIfReached(); // no-warning
}
+#if __cplusplus >= 201103L
+ CtorWithNoReturnDtor returnNoReturnDtor() {
+ return {1}; // no-crash
+ }
+#endif
+
#endif // TEMPORARY_DTORS
}
@@ -530,3 +541,152 @@ void run() {
Sub(i).m();
}
}
+
+namespace test_return_temporary {
+class C {
+ int x, y;
+
+public:
+ C(int x, int y) : x(x), y(y) {}
+ int getX() const { return x; }
+ int getY() const { return y; }
+ ~C() {}
+};
+
+class D: public C {
+public:
+ D() : C(1, 2) {}
+ D(const D &d): C(d.getX(), d.getY()) {}
+};
+
+C returnTemporaryWithVariable() { C c(1, 2); return c; }
+C returnTemporaryWithAnotherFunctionWithVariable() {
+ return returnTemporaryWithVariable();
+}
+C returnTemporaryWithCopyConstructionWithVariable() {
+ return C(returnTemporaryWithVariable());
+}
+
+C returnTemporaryWithConstruction() { return C(1, 2); }
+C returnTemporaryWithAnotherFunctionWithConstruction() {
+ return returnTemporaryWithConstruction();
+}
+C returnTemporaryWithCopyConstructionWithConstruction() {
+ return C(returnTemporaryWithConstruction());
+}
+
+D returnTemporaryWithVariableAndNonTrivialCopy() { D d; return d; }
+D returnTemporaryWithAnotherFunctionWithVariableAndNonTrivialCopy() {
+ return returnTemporaryWithVariableAndNonTrivialCopy();
+}
+D returnTemporaryWithCopyConstructionWithVariableAndNonTrivialCopy() {
+ return D(returnTemporaryWithVariableAndNonTrivialCopy());
+}
+
+#if __cplusplus >= 201103L
+C returnTemporaryWithBraces() { return {1, 2}; }
+C returnTemporaryWithAnotherFunctionWithBraces() {
+ return returnTemporaryWithBraces();
+}
+C returnTemporaryWithCopyConstructionWithBraces() {
+ return C(returnTemporaryWithBraces());
+}
+#endif // C++11
+
+void test() {
+ C c1 = returnTemporaryWithVariable();
+ clang_analyzer_eval(c1.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c1.getY() == 2); // expected-warning{{TRUE}}
+
+ C c2 = returnTemporaryWithAnotherFunctionWithVariable();
+ clang_analyzer_eval(c2.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c2.getY() == 2); // expected-warning{{TRUE}}
+
+ C c3 = returnTemporaryWithCopyConstructionWithVariable();
+ clang_analyzer_eval(c3.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c3.getY() == 2); // expected-warning{{TRUE}}
+
+ C c4 = returnTemporaryWithConstruction();
+ // Should be TRUE under TEMPORARY_DTORS once this sort of construction
+ // in the inlined function is supported.
+ clang_analyzer_eval(c4.getX() == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c4.getY() == 2); // expected-warning{{UNKNOWN}}
+
+ C c5 = returnTemporaryWithAnotherFunctionWithConstruction();
+ // Should be TRUE under TEMPORARY_DTORS once this sort of construction
+ // in the inlined function is supported.
+ clang_analyzer_eval(c5.getX() == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c5.getY() == 2); // expected-warning{{UNKNOWN}}
+
+ C c6 = returnTemporaryWithCopyConstructionWithConstruction();
+ // Should be TRUE under TEMPORARY_DTORS once this sort of construction
+ // in the inlined function is supported.
+ clang_analyzer_eval(c5.getX() == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(c5.getY() == 2); // expected-warning{{UNKNOWN}}
+
+#if __cplusplus >= 201103L
+
+ C c7 = returnTemporaryWithBraces();
+ clang_analyzer_eval(c7.getX() == 1);
+ clang_analyzer_eval(c7.getY() == 2);
+#ifdef TEMPORARY_DTORS
+ // expected-warning@-3{{TRUE}}
+ // expected-warning@-3{{TRUE}}
+#else
+ // expected-warning@-6{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
+#endif
+
+ C c8 = returnTemporaryWithAnotherFunctionWithBraces();
+ clang_analyzer_eval(c8.getX() == 1);
+ clang_analyzer_eval(c8.getY() == 2);
+#ifdef TEMPORARY_DTORS
+ // expected-warning@-3{{TRUE}}
+ // expected-warning@-3{{TRUE}}
+#else
+ // expected-warning@-6{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
+#endif
+
+ C c9 = returnTemporaryWithCopyConstructionWithBraces();
+ clang_analyzer_eval(c9.getX() == 1);
+ clang_analyzer_eval(c9.getY() == 2);
+#ifdef TEMPORARY_DTORS
+ // expected-warning@-3{{TRUE}}
+ // expected-warning@-3{{TRUE}}
+#else
+ // expected-warning@-6{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
+#endif
+
+#endif // C++11
+
+ D d1 = returnTemporaryWithVariableAndNonTrivialCopy();
+ clang_analyzer_eval(d1.getX() == 1);
+ clang_analyzer_eval(d1.getY() == 2);
+#ifdef TEMPORARY_DTORS
+ // expected-warning@-3{{TRUE}}
+ // expected-warning@-3{{TRUE}}
+#else
+ // expected-warning@-6{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
+#endif
+
+ D d2 = returnTemporaryWithAnotherFunctionWithVariableAndNonTrivialCopy();
+ clang_analyzer_eval(d2.getX() == 1);
+ clang_analyzer_eval(d2.getY() == 2);
+#ifdef TEMPORARY_DTORS
+ // expected-warning@-3{{TRUE}}
+ // expected-warning@-3{{TRUE}}
+#else
+ // expected-warning@-6{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
+#endif
+
+ // Should be TRUE under TEMPORARY_DTORS once this sort of construction
+ // in the inlined function is supported.
+ D d3 = returnTemporaryWithCopyConstructionWithVariableAndNonTrivialCopy();
+ clang_analyzer_eval(d3.getX() == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(d3.getY() == 2); // expected-warning{{UNKNOWN}}
+}
+} // namespace test_return_temporary
OpenPOWER on IntegriCloud