diff options
Diffstat (limited to 'clang/test/Analysis')
| -rw-r--r-- | clang/test/Analysis/cxx17-mandatory-elision.cpp | 30 | ||||
| -rw-r--r-- | clang/test/Analysis/gtest.cpp | 6 | ||||
| -rw-r--r-- | clang/test/Analysis/inlining/temp-dtors-path-notes.cpp | 9 | ||||
| -rw-r--r-- | clang/test/Analysis/lifetime-extension.cpp | 158 | ||||
| -rw-r--r-- | clang/test/Analysis/temporaries.cpp | 188 |
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 |

