summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis')
-rw-r--r--clang/test/Analysis/cxx17-mandatory-elision.cpp30
-rw-r--r--clang/test/Analysis/gtest.cpp6
-rw-r--r--clang/test/Analysis/inlining/temp-dtors-path-notes.cpp9
-rw-r--r--clang/test/Analysis/lifetime-extension.cpp158
-rw-r--r--clang/test/Analysis/temporaries.cpp188
5 files changed, 114 insertions, 277 deletions
diff --git a/clang/test/Analysis/cxx17-mandatory-elision.cpp b/clang/test/Analysis/cxx17-mandatory-elision.cpp
index e8261052796..cf77912ea6c 100644
--- a/clang/test/Analysis/cxx17-mandatory-elision.cpp
+++ b/clang/test/Analysis/cxx17-mandatory-elision.cpp
@@ -1,5 +1,17 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 -analyzer-config elide-constructors=false -DNO_ELIDE_FLAG -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -analyzer-config elide-constructors=false -DNO_ELIDE_FLAG -verify %s
+
+// Copy elision always occurs in C++17, otherwise it's under
+// an on-by-default flag.
+#if __cplusplus >= 201703L
+ #define ELIDE 1
+#else
+ #ifndef NO_ELIDE_FLAG
+ #define ELIDE 1
+ #endif
+#endif
void clang_analyzer_eval(bool);
@@ -39,9 +51,9 @@ public:
C() : t(T(4)) {
S s = {1, 2, 3};
t.s = s;
- // FIXME: Should be TRUE in C++11 as well.
+ // FIXME: Should be TRUE regardless of copy elision.
clang_analyzer_eval(t.w == 4);
-#if __cplusplus >= 201703L
+#ifdef ELIDE
// expected-warning@-2{{TRUE}}
#else
// expected-warning@-4{{UNKNOWN}}
@@ -149,7 +161,7 @@ void testMultipleReturns() {
AddressVector<ClassWithoutDestructor> v;
ClassWithoutDestructor c = make3(v);
-#if __cplusplus >= 201703L
+#if ELIDE
clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
clang_analyzer_eval(v.buf[0] == &c); // expected-warning{{TRUE}}
#else
@@ -184,13 +196,13 @@ void testVariable() {
ClassWithDestructor c = ClassWithDestructor(v);
// Check if the last destructor is an automatic destructor.
// A temporary destructor would have fired by now.
-#if __cplusplus >= 201703L
+#if ELIDE
clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
#else
clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}}
#endif
}
-#if __cplusplus >= 201703L
+#if ELIDE
// 0. Construct the variable.
// 1. Destroy the variable.
clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
@@ -218,13 +230,13 @@ void testCtorInitializer() {
TestCtorInitializer t(v);
// Check if the last destructor is an automatic destructor.
// A temporary destructor would have fired by now.
-#if __cplusplus >= 201703L
+#if ELIDE
clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
#else
clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}}
#endif
}
-#if __cplusplus >= 201703L
+#if ELIDE
// 0. Construct the member variable.
// 1. Destroy the member variable.
clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
@@ -257,14 +269,14 @@ void testMultipleReturnsWithDestructors() {
ClassWithDestructor c = make3(v);
// Check if the last destructor is an automatic destructor.
// A temporary destructor would have fired by now.
-#if __cplusplus >= 201703L
+#if ELIDE
clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
#else
clang_analyzer_eval(v.len == 9); // expected-warning{{TRUE}}
#endif
}
-#if __cplusplus >= 201703L
+#if ELIDE
// 0. Construct the variable. Yes, constructor in make1() constructs
// the variable 'c'.
// 1. Destroy the variable.
diff --git a/clang/test/Analysis/gtest.cpp b/clang/test/Analysis/gtest.cpp
index 1c6e01a6173..e68303d5492 100644
--- a/clang/test/Analysis/gtest.cpp
+++ b/clang/test/Analysis/gtest.cpp
@@ -154,13 +154,11 @@ void testConstrainState(int p) {
void testAssertSymbolicPtr(const bool *b) {
ASSERT_TRUE(*b); // no-crash
- // FIXME: Our solver doesn't handle this well yet.
- clang_analyzer_eval(*b); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(*b); // expected-warning{{TRUE}}
}
void testAssertSymbolicRef(const bool &b) {
ASSERT_TRUE(b); // no-crash
- // FIXME: Our solver doesn't handle this well yet.
- clang_analyzer_eval(b); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(b); // expected-warning{{TRUE}}
}
diff --git a/clang/test/Analysis/inlining/temp-dtors-path-notes.cpp b/clang/test/Analysis/inlining/temp-dtors-path-notes.cpp
index 6d1a42ff50c..40b26b5c91a 100644
--- a/clang/test/Analysis/inlining/temp-dtors-path-notes.cpp
+++ b/clang/test/Analysis/inlining/temp-dtors-path-notes.cpp
@@ -30,19 +30,14 @@ public:
};
void test(int coin) {
- // We'd divide by zero in the temporary destructor that goes after the
- // elidable copy-constructor from C(0) to the lifetime-extended temporary.
- // So in fact this example has nothing to do with lifetime extension.
- // Actually, it would probably be better to elide the constructor, and
- // put the note for the destructor call at the closing brace after nop.
+ // We'd divide by zero in the automatic destructor for variable 'c'.
const C &c = coin ? C(1) : C(0); // expected-note {{Assuming 'coin' is 0}}
// expected-note@-1{{'?' condition is false}}
// expected-note@-2{{Passing the value 0 via 1st parameter 'x'}}
// expected-note@-3{{Calling constructor for 'C'}}
// expected-note@-4{{Returning from constructor for 'C'}}
- // expected-note@-5{{Calling '~C'}}
c.nop();
-}
+} // expected-note{{Calling '~C'}}
} // end namespace test_lifetime_extended_temporary
namespace test_bug_after_dtor {
diff --git a/clang/test/Analysis/lifetime-extension.cpp b/clang/test/Analysis/lifetime-extension.cpp
index ee55107838d..4337632b31c 100644
--- a/clang/test/Analysis/lifetime-extension.cpp
+++ b/clang/test/Analysis/lifetime-extension.cpp
@@ -97,13 +97,10 @@ void f1() {
void f2() {
C *after, *before;
- C c = C(1, &after, &before);
- clang_analyzer_eval(after == before);
-#ifdef TEMPORARIES
- // expected-warning@-2{{TRUE}}
-#else
- // expected-warning@-4{{UNKNOWN}}
-#endif
+ {
+ C c = C(1, &after, &before);
+ }
+ clang_analyzer_eval(after == before); // expected-warning{{TRUE}}
}
void f3(bool coin) {
@@ -129,6 +126,7 @@ void f4(bool coin) {
// operator. Ideally also add support for the binary conditional operator in
// C++. Because for now it calls the constructor for the condition twice.
if (coin) {
+ // FIXME: Should not warn.
clang_analyzer_eval(after == before);
#ifdef TEMPORARIES
// expected-warning@-2{{The left operand of '==' is a garbage value}}
@@ -136,13 +134,12 @@ void f4(bool coin) {
// expected-warning@-4{{UNKNOWN}}
#endif
} else {
+ // FIXME: Should be TRUE.
clang_analyzer_eval(after == before);
#ifdef TEMPORARIES
- // Seems to work at the moment, but also seems accidental.
- // Feel free to break.
- // expected-warning@-4{{TRUE}}
+ // expected-warning@-2{{FALSE}}
#else
- // expected-warning@-6{{UNKNOWN}}
+ // expected-warning@-4{{UNKNOWN}}
#endif
}
}
@@ -234,24 +231,25 @@ void f2() {
} // end namespace maintain_original_object_address_on_move
namespace maintain_address_of_copies {
+class C;
-template <typename T> struct AddressVector {
- const T *buf[10];
+struct AddressVector {
+ C *buf[10];
int len;
AddressVector() : len(0) {}
- void push(const T *t) {
- buf[len] = t;
+ void push(C *c) {
+ buf[len] = c;
++len;
}
};
class C {
- AddressVector<C> &v;
+ AddressVector &v;
public:
- C(AddressVector<C> &v) : v(v) { v.push(this); }
+ C(AddressVector &v) : v(v) { v.push(this); }
~C() { v.push(this); }
#ifdef MOVES
@@ -267,132 +265,70 @@ public:
#endif
} // no-warning
- static C make(AddressVector<C> &v) { return C(v); }
+ static C make(AddressVector &v) { return C(v); }
};
void f1() {
- AddressVector<C> v;
+ AddressVector v;
{
C c = C(v);
}
- // 0. Create the original temporary and lifetime-extend it into variable 'c'
- // construction argument.
- // 1. Construct variable 'c' (elidable copy/move).
- // 2. Destroy the temporary.
- // 3. Destroy variable 'c'.
- clang_analyzer_eval(v.len == 4);
- clang_analyzer_eval(v.buf[0] == v.buf[2]);
- clang_analyzer_eval(v.buf[1] == v.buf[3]);
-#ifdef TEMPORARIES
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
-#else
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
-#endif
+ // 0. Construct variable 'c' (copy/move elided).
+ // 1. Destroy variable 'c'.
+ clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
}
void f2() {
- AddressVector<C> v;
+ AddressVector v;
{
const C &c = C::make(v);
}
- // 0. Construct the original temporary within make(),
- // 1. Construct the return value of make() (elidable copy/move) and
- // lifetime-extend it via reference 'c',
- // 2. Destroy the temporary within make(),
- // 3. Destroy the temporary lifetime-extended by 'c'.
- clang_analyzer_eval(v.len == 4);
- clang_analyzer_eval(v.buf[0] == v.buf[2]);
- clang_analyzer_eval(v.buf[1] == v.buf[3]);
+ // 0. Construct the return value of make() (copy/move elided) and
+ // lifetime-extend it directly via reference 'c',
+ // 1. Destroy the temporary lifetime-extended by 'c'.
+ clang_analyzer_eval(v.len == 2);
+ clang_analyzer_eval(v.buf[0] == v.buf[1]);
#ifdef TEMPORARIES
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
+ // expected-warning@-3{{TRUE}}
+ // expected-warning@-3{{TRUE}}
#else
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
#endif
}
void f3() {
- AddressVector<C> v;
+ AddressVector v;
{
C &&c = C::make(v);
}
- // 0. Construct the original temporary within make(),
- // 1. Construct the return value of make() (elidable copy/move) and
- // lifetime-extend it via reference 'c',
- // 2. Destroy the temporary within make(),
- // 3. Destroy the temporary lifetime-extended by 'c'.
- clang_analyzer_eval(v.len == 4);
- clang_analyzer_eval(v.buf[0] == v.buf[2]);
- clang_analyzer_eval(v.buf[1] == v.buf[3]);
+ // 0. Construct the return value of make() (copy/move elided) and
+ // lifetime-extend it directly via reference 'c',
+ // 1. Destroy the temporary lifetime-extended by 'c'.
+ clang_analyzer_eval(v.len == 2);
+ clang_analyzer_eval(v.buf[0] == v.buf[1]);
#ifdef TEMPORARIES
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
+ // expected-warning@-3{{TRUE}}
+ // expected-warning@-3{{TRUE}}
#else
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
+ // expected-warning@-6{{UNKNOWN}}
#endif
}
-C doubleMake(AddressVector<C> &v) {
+C doubleMake(AddressVector &v) {
return C::make(v);
}
void f4() {
- AddressVector<C> v;
+ AddressVector v;
{
C c = doubleMake(v);
}
- // 0. Construct the original temporary within make(),
- // 1. Construct the return value of make() (elidable copy/move) and
- // lifetime-extend it into the return value constructor argument within
- // doubleMake(),
- // 2. Destroy the temporary within make(),
- // 3. Construct the return value of doubleMake() (elidable copy/move) and
- // lifetime-extend it into the variable 'c' constructor argument,
- // 4. Destroy the return value of make(),
- // 5. Construct variable 'c' (elidable copy/move),
- // 6. Destroy the return value of doubleMake(),
- // 7. Destroy variable 'c'.
- clang_analyzer_eval(v.len == 8);
- clang_analyzer_eval(v.buf[0] == v.buf[2]);
- clang_analyzer_eval(v.buf[1] == v.buf[4]);
- clang_analyzer_eval(v.buf[3] == v.buf[6]);
- clang_analyzer_eval(v.buf[5] == v.buf[7]);
-#ifdef TEMPORARIES
- // expected-warning@-6{{TRUE}}
- // expected-warning@-6{{TRUE}}
- // expected-warning@-6{{TRUE}}
- // expected-warning@-6{{TRUE}}
- // expected-warning@-6{{TRUE}}
-#else
- // expected-warning@-12{{UNKNOWN}}
- // expected-warning@-12{{UNKNOWN}}
- // expected-warning@-12{{UNKNOWN}}
- // expected-warning@-12{{UNKNOWN}}
- // expected-warning@-12{{UNKNOWN}}
-#endif
+ // 0. Construct variable 'c' (all copies/moves elided),
+ // 1. Destroy variable 'c'.
+ clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
}
-
-class NoDtor {
- AddressVector<NoDtor> &v;
-
-public:
- NoDtor(AddressVector<NoDtor> &v) : v(v) { v.push(this); }
-};
-
-void f5() {
- AddressVector<NoDtor> v;
- const NoDtor &N = NoDtor(v);
- clang_analyzer_eval(v.buf[0] == &N); // expected-warning{{TRUE}}
-}
-
} // end namespace maintain_address_of_copies
diff --git a/clang/test/Analysis/temporaries.cpp b/clang/test/Analysis/temporaries.cpp
index 964e7f13c56..de3420e7089 100644
--- a/clang/test/Analysis/temporaries.cpp
+++ b/clang/test/Analysis/temporaries.cpp
@@ -612,107 +612,44 @@ void test() {
clang_analyzer_eval(c3.getY() == 2); // expected-warning{{TRUE}}
C c4 = returnTemporaryWithConstruction();
- clang_analyzer_eval(c4.getX() == 1);
- clang_analyzer_eval(c4.getY() == 2);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-3{{TRUE}}
- // expected-warning@-3{{TRUE}}
-#else
- // expected-warning@-6{{UNKNOWN}}
- // expected-warning@-6{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(c4.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c4.getY() == 2); // expected-warning{{TRUE}}
C c5 = returnTemporaryWithAnotherFunctionWithConstruction();
- clang_analyzer_eval(c5.getX() == 1);
- clang_analyzer_eval(c5.getY() == 2);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-3{{TRUE}}
- // expected-warning@-3{{TRUE}}
-#else
- // expected-warning@-6{{UNKNOWN}}
- // expected-warning@-6{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(c5.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c5.getY() == 2); // expected-warning{{TRUE}}
C c6 = returnTemporaryWithCopyConstructionWithConstruction();
- clang_analyzer_eval(c5.getX() == 1);
- clang_analyzer_eval(c5.getY() == 2);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-3{{TRUE}}
- // expected-warning@-3{{TRUE}}
-#else
- // expected-warning@-6{{UNKNOWN}}
- // expected-warning@-6{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(c5.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c5.getY() == 2); // expected-warning{{TRUE}}
#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
+ clang_analyzer_eval(c7.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c7.getY() == 2); // expected-warning{{TRUE}}
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
+ clang_analyzer_eval(c8.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c8.getY() == 2); // expected-warning{{TRUE}}
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
+ clang_analyzer_eval(c9.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c9.getY() == 2); // expected-warning{{TRUE}}
#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
+ clang_analyzer_eval(d1.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d1.getY() == 2); // expected-warning{{TRUE}}
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
+ clang_analyzer_eval(d2.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d2.getY() == 2); // expected-warning{{TRUE}}
D d3 = returnTemporaryWithCopyConstructionWithVariableAndNonTrivialCopy();
- clang_analyzer_eval(d3.getX() == 1);
- clang_analyzer_eval(d3.getY() == 2);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-3{{TRUE}}
- // expected-warning@-3{{TRUE}}
-#else
- // expected-warning@-6{{UNKNOWN}}
- // expected-warning@-6{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(d3.getX() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d3.getY() == 2); // expected-warning{{TRUE}}
}
} // namespace test_return_temporary
@@ -767,19 +704,9 @@ void test(int coin) {
C c2 = coin ? C(1) : C(2);
if (coin) {
- clang_analyzer_eval(c2.getX() == 1);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-2{{TRUE}}
-#else
- // expected-warning@-4{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(c2.getX() == 1); // expected-warning{{TRUE}}
} else {
- clang_analyzer_eval(c2.getX() == 2);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-2{{TRUE}}
-#else
- // expected-warning@-4{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(c2.getX() == 2); // expected-warning{{TRUE}}
}
}
@@ -816,16 +743,9 @@ void test_simple_temporary_with_copy() {
{
C c = C(x, y);
}
- // Two constructors (temporary object expr and copy) and two destructors.
- clang_analyzer_eval(x == 2);
- clang_analyzer_eval(y == 2);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-3{{TRUE}}
- // expected-warning@-3{{TRUE}}
-#else
- // expected-warning@-6{{UNKNOWN}}
- // expected-warning@-6{{UNKNOWN}}
-#endif
+ // Only one constructor directly into the variable, and one destructor.
+ clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(y == 1); // expected-warning{{TRUE}}
}
void test_ternary_temporary(int coin) {
@@ -833,10 +753,10 @@ void test_ternary_temporary(int coin) {
{
const C &c = coin ? C(x, y) : C(z, w);
}
- // This time each branch contains an additional elidable copy constructor.
+ // Only one constructor on every branch, and one automatic destructor.
if (coin) {
- clang_analyzer_eval(x == 2);
- clang_analyzer_eval(y == 2);
+ clang_analyzer_eval(x == 1);
+ clang_analyzer_eval(y == 1);
#ifdef TEMPORARY_DTORS
// expected-warning@-3{{TRUE}}
// expected-warning@-3{{TRUE}}
@@ -850,8 +770,8 @@ void test_ternary_temporary(int coin) {
} else {
clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}
- clang_analyzer_eval(z == 2);
- clang_analyzer_eval(w == 2);
+ clang_analyzer_eval(z == 1);
+ clang_analyzer_eval(w == 1);
#ifdef TEMPORARY_DTORS
// expected-warning@-3{{TRUE}}
// expected-warning@-3{{TRUE}}
@@ -867,33 +787,18 @@ void test_ternary_temporary_with_copy(int coin) {
{
C c = coin ? C(x, y) : C(z, w);
}
- // Temporary expression, elidable copy within branch,
- // constructor for variable - 3 total.
+ // On each branch the variable is constructed directly.
if (coin) {
- clang_analyzer_eval(x == 3);
- clang_analyzer_eval(y == 3);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-3{{TRUE}}
- // expected-warning@-3{{TRUE}}
-#else
- // expected-warning@-6{{UNKNOWN}}
- // expected-warning@-6{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(y == 1); // expected-warning{{TRUE}}
clang_analyzer_eval(z == 0); // expected-warning{{TRUE}}
clang_analyzer_eval(w == 0); // expected-warning{{TRUE}}
} else {
clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}
- clang_analyzer_eval(z == 3);
- clang_analyzer_eval(w == 3);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-3{{TRUE}}
- // expected-warning@-3{{TRUE}}
-#else
- // expected-warning@-6{{UNKNOWN}}
- // expected-warning@-6{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(z == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(w == 1); // expected-warning{{TRUE}}
}
}
} // namespace test_match_constructors_and_destructors
@@ -928,12 +833,13 @@ void testLifetimeExtendedCall() {
}
void testCopiedCall() {
- C c = make();
- // Should have divided by zero in the temporary destructor.
- clang_analyzer_warnIfReached();
-#ifndef TEMPORARY_DTORS
- // expected-warning@-2{{REACHABLE}}
-#endif
+ {
+ C c = make();
+ // Should have elided the constructor/destructor for the temporary
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ }
+ // Should have divided by zero in the destructor.
+ clang_analyzer_warnIfReached(); // no-warning
}
} // namespace destructors_for_return_values
@@ -1018,20 +924,10 @@ void test() {
#endif
S s = 20;
- clang_analyzer_eval(s.x == 20);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-2{{TRUE}}
-#else
- // expected-warning@-4{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(s.x == 20); // expected-warning{{TRUE}}
C c2 = s;
- clang_analyzer_eval(c2.getX() == 20);
-#ifdef TEMPORARY_DTORS
- // expected-warning@-2{{TRUE}}
-#else
- // expected-warning@-4{{UNKNOWN}}
-#endif
+ clang_analyzer_eval(c2.getX() == 20); // expected-warning{{TRUE}}
}
} // end namespace implicit_constructor_conversion
OpenPOWER on IntegriCloud