1 // RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\
2 // RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\
3 // RUN: -analyzer-config eagerly-assume=false -verify %s\
4 // RUN: -std=c++03 -analyzer-config cfg-temporary-dtors=false
6 // RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\
7 // RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\
8 // RUN: -analyzer-config eagerly-assume=false -verify %s\
9 // RUN: -std=c++11 -analyzer-config cfg-temporary-dtors=false
11 // RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\
12 // RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\
13 // RUN: -analyzer-config eagerly-assume=false -verify %s\
14 // RUN: -std=c++11 -analyzer-config cfg-temporary-dtors=true\
15 // RUN: -DTEMPORARY_DTORS
17 // RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus\
18 // RUN: -analyzer-checker debug.ExprInspection -Wno-non-pod-varargs\
19 // RUN: -analyzer-config eagerly-assume=false -verify %s\
20 // RUN: -std=c++17 -analyzer-config cfg-temporary-dtors=true\
21 // RUN: -DTEMPORARY_DTORS
24 extern bool clang_analyzer_eval(bool);
25 extern bool clang_analyzer_warnIfReached();
26 void clang_analyzer_checkInlined(bool);
28 #include "Inputs/system-header-simulator-cxx.h"
31 Trivial(int x
) : value(x
) {}
35 struct NonTrivial
: public Trivial
{
36 NonTrivial(int x
) : Trivial(x
) {}
41 Trivial
getTrivial() {
42 return Trivial(42); // no-warning
45 const Trivial
&getTrivialRef() {
46 return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'Trivial' returned to caller}}
50 NonTrivial
getNonTrivial() {
51 return NonTrivial(42); // no-warning
54 const NonTrivial
&getNonTrivialRef() {
55 return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'NonTrivial' returned to caller}}
58 namespace rdar13265460
{
59 struct TrivialSubclass
: public Trivial
{
60 TrivialSubclass(int x
) : Trivial(x
), anotherValue(-x
) {}
64 TrivialSubclass
getTrivialSub() {
65 TrivialSubclass
obj(1);
67 obj
.anotherValue
= -42;
71 void testImmediate() {
72 TrivialSubclass obj
= getTrivialSub();
74 clang_analyzer_eval(obj
.value
== 42); // expected-warning{{TRUE}}
75 clang_analyzer_eval(obj
.anotherValue
== -42); // expected-warning{{TRUE}}
77 clang_analyzer_eval(getTrivialSub().value
== 42); // expected-warning{{TRUE}}
78 clang_analyzer_eval(getTrivialSub().anotherValue
== -42); // expected-warning{{TRUE}}
81 void testMaterializeTemporaryExpr() {
82 const TrivialSubclass
&ref
= getTrivialSub();
83 clang_analyzer_eval(ref
.value
== 42); // expected-warning{{TRUE}}
85 const Trivial
&baseRef
= getTrivialSub();
86 clang_analyzer_eval(baseRef
.value
== 42); // expected-warning{{TRUE}}
90 namespace rdar13281951
{
91 struct Derived
: public Trivial
{
92 Derived(int value
) : Trivial(value
), value2(-value
) {}
99 const Trivial
* const &pointerRef
= &obj
;
100 clang_analyzer_eval(pointerRef
->value
== 42); // expected-warning{{TRUE}}
104 namespace compound_literals
{
109 HasCtor(int x
, int y
) : x(x
), y(y
) {}
117 HasCtorDtor(int x
, int y
) : x(x
), y(y
) {}
123 clang_analyzer_eval(((POD
){1, 42}).y
== 42); // expected-warning{{TRUE}}
124 clang_analyzer_eval(((HasDtor
){1, 42}).y
== 42); // expected-warning{{TRUE}}
126 #if __cplusplus >= 201103L
127 clang_analyzer_eval(((HasCtor
){1, 42}).y
== 42); // expected-warning{{TRUE}}
129 // FIXME: should be TRUE, but we don't inline the constructors of
130 // temporaries because we can't model their destructors yet.
131 clang_analyzer_eval(((HasCtorDtor
){1, 42}).y
== 42); // expected-warning{{UNKNOWN}}
136 namespace destructors
{
141 extern bool check(const Dtor
&);
143 void testPR16664andPR18159Crash() {
144 // Regression test: we used to assert here when tmp dtors are enabled.
145 // PR16664 and PR18159
146 if (coin() && (coin() || coin() || check(Dtor()))) {
151 #ifdef TEMPORARY_DTORS
152 struct NoReturnDtor
{
153 ~NoReturnDtor() __attribute__((noreturn
));
156 void noReturnTemp(int *x
) {
157 if (! x
) NoReturnDtor();
158 *x
= 47; // no warning
161 void noReturnInline(int **x
) {
165 void callNoReturn() {
168 *x
= 47; // no warning
171 extern bool check(const NoReturnDtor
&);
173 void testConsistencyIf(int i
) {
176 if (i
== 5 && (i
== 4 || check(NoReturnDtor()) || i
== 5)) {
177 clang_analyzer_eval(true); // no warning, unreachable code
181 void testConsistencyTernary(int i
) {
182 (i
== 5 && (i
== 4 || check(NoReturnDtor()) || i
== 5)) ? 1 : 0;
184 clang_analyzer_eval(true); // expected-warning{{TRUE}}
189 (i
== 5 && (i
== 4 || check(NoReturnDtor()) || i
== 5)) ? 1 : 0;
191 clang_analyzer_eval(true); // no warning, unreachable code
194 // Regression test: we used to assert here.
195 // PR16664 and PR18159
196 void testConsistencyNested(int i
) {
197 extern bool compute(bool);
199 if (i
== 5 && (i
== 4 || i
== 5 || check(NoReturnDtor())))
200 clang_analyzer_eval(true); // expected-warning{{TRUE}}
202 if (i
== 5 && (i
== 4 || i
== 5 || check(NoReturnDtor())))
203 clang_analyzer_eval(true); // expected-warning{{TRUE}}
208 if (compute(i
== 5 &&
209 (i
== 4 || compute(true) ||
210 compute(i
== 5 && (i
== 4 || check(NoReturnDtor()))))) ||
212 clang_analyzer_eval(true); // expected-warning{{TRUE}}
215 if (compute(i
== 5 &&
217 compute(i
== 5 && (i
== 4 || check(NoReturnDtor()))))) ||
219 clang_analyzer_eval(true); // no warning, unreachable code
223 // PR16664 and PR18159
224 void testConsistencyNestedSimple(bool value
) {
226 if (!value
|| check(NoReturnDtor())) {
227 clang_analyzer_eval(true); // no warning, unreachable code
232 // PR16664 and PR18159
233 void testConsistencyNestedComplex(bool value
) {
235 if (!value
|| !value
|| check(NoReturnDtor())) {
236 clang_analyzer_eval(true); // no warning, unreachable code
241 // PR16664 and PR18159
242 void testConsistencyNestedWarning(bool value
) {
244 if (!value
|| value
|| check(NoReturnDtor())) {
245 clang_analyzer_eval(true); // expected-warning{{TRUE}}
249 // PR16664 and PR18159
250 void testConsistencyNestedComplexMidBranch(bool value
) {
252 if (!value
|| !value
|| check(NoReturnDtor()) || value
) {
253 clang_analyzer_eval(true); // no warning, unreachable code
258 // PR16664 and PR18159
259 void testConsistencyNestedComplexNestedBranch(bool value
) {
261 if (!value
|| (!value
|| check(NoReturnDtor()) || value
)) {
262 clang_analyzer_eval(true); // no warning, unreachable code
267 // PR16664 and PR18159
268 void testConsistencyNestedVariableModification(bool value
) {
271 if (!other
|| !value
|| (other
= false) || check(NoReturnDtor()) ||
273 clang_analyzer_eval(true); // no warning, unreachable code
278 void testTernaryNoReturnTrueBranch(bool value
) {
280 bool b
= value
&& (value
? check(NoReturnDtor()) : true);
281 clang_analyzer_eval(true); // no warning, unreachable code
284 void testTernaryNoReturnFalseBranch(bool value
) {
286 bool b
= !value
&& !value
? true : check(NoReturnDtor());
287 clang_analyzer_eval(true); // no warning, unreachable code
290 void testTernaryIgnoreNoreturnBranch(bool value
) {
292 bool b
= !value
&& !value
? check(NoReturnDtor()) : true;
293 clang_analyzer_eval(true); // expected-warning{{TRUE}}
296 void testTernaryTrueBranchReached(bool value
) {
297 value
? clang_analyzer_warnIfReached() : // expected-warning{{REACHABLE}}
298 check(NoReturnDtor());
300 void testTernaryFalseBranchReached(bool value
) {
301 value
? check(NoReturnDtor()) :
302 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
306 for (int i
= 0; i
< 10; ++i
) {
307 if (i
< 3 && (i
>= 2 || check(NoReturnDtor()))) {
308 clang_analyzer_eval(true); // no warning, unreachable code
313 bool testRecursiveFrames(bool isInner
) {
315 (clang_analyzer_warnIfReached(), false) || // expected-warning{{REACHABLE}}
316 check(NoReturnDtor()) ||
317 testRecursiveFrames(true)) {
318 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
321 void testRecursiveFramesStart() { testRecursiveFrames(false); }
324 []() { check(NoReturnDtor()); } != nullptr || check(Dtor());
327 void testGnuExpressionStatements(int v
) {
328 ({ ++v
; v
== 10 || check(NoReturnDtor()); v
== 42; }) || v
== 23;
329 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
331 ({ ++v
; check(NoReturnDtor()); v
== 42; }) || v
== 23;
332 clang_analyzer_warnIfReached(); // no warning, unreachable code
335 void testGnuExpressionStatementsDestructionPoint(int v
) {
336 // In normal context, the temporary destructor runs at the end of the full
337 // statement, thus the last statement is reached.
338 (++v
, check(NoReturnDtor()), v
== 42),
339 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
341 // GNU expression statements execute temporary destructors within the
342 // blocks, thus the last statement is not reached.
343 ({ ++v
; check(NoReturnDtor()); v
== 42; }),
344 clang_analyzer_warnIfReached(); // no warning, unreachable code
347 void testMultipleTemporaries(bool value
) {
349 // FIXME: Find a way to verify construction order.
350 // ~Dtor should run before ~NoReturnDtor() because construction order is
351 // guaranteed by comma operator.
352 if (!value
|| check((NoReturnDtor(), Dtor())) || value
) {
353 clang_analyzer_eval(true); // no warning, unreachable code
358 void testBinaryOperatorShortcut(bool value
) {
360 if (false && false && check(NoReturnDtor()) && true) {
361 clang_analyzer_eval(true);
366 void testIfAtEndOfLoop() {
370 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
373 // Test that the CFG gets hooked up correctly when temporary destructors
374 // are handled after a statically known branch condition.
375 if (true) (void)0; else (void)check(NoReturnDtor());
379 void testTernaryAtEndOfLoop() {
383 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
386 // Test that the CFG gets hooked up correctly when temporary destructors
387 // are handled after a statically known branch condition.
388 true ? (void)0 : (void)check(NoReturnDtor());
392 void testNoReturnInComplexCondition() {
394 (check(NoReturnDtor()) || check(NoReturnDtor())) && check(Dtor());
395 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
398 void testSequencingOfConditionalTempDtors(bool b
) {
399 b
|| (check(Dtor()), check(NoReturnDtor()));
400 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
403 void testSequencingOfConditionalTempDtors2(bool b
) {
404 (b
|| check(Dtor())), check(NoReturnDtor());
405 clang_analyzer_warnIfReached(); // no warning, unreachable code
408 void testSequencingOfConditionalTempDtorsWithinBinaryOperators(bool b
) {
409 b
|| (check(Dtor()) + check(NoReturnDtor()));
410 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
413 void f(Dtor d
= Dtor());
414 void testDefaultParameters() {
418 struct DefaultParam
{
419 DefaultParam(int, const Dtor
& d
= Dtor());
422 void testDefaultParamConstructorsInLoops() {
424 // FIXME: This exact pattern triggers the temporary cleanup logic
425 // to fail when adding a 'clean' state.
430 void testDefaultParamConstructorsInTernariesInLoops(bool value
) {
432 // FIXME: This exact pattern triggers the temporary cleanup logic
433 // to visit the bind-temporary logic with a state that already has that
434 // temporary marked as executed.
435 value
? DefaultParam(42) : DefaultParam(42);
438 #else // !TEMPORARY_DTORS
440 // Test for fallback logic that conservatively stops exploration after
441 // executing a temporary constructor for a class with a no-return destructor
442 // when temporary destructors are not enabled in the CFG.
444 struct CtorWithNoReturnDtor
{
445 CtorWithNoReturnDtor() = default;
447 CtorWithNoReturnDtor(int x
) {
448 clang_analyzer_checkInlined(false); // no-warning
451 ~CtorWithNoReturnDtor() __attribute__((noreturn
));
454 void testDefaultContructorWithNoReturnDtor() {
455 CtorWithNoReturnDtor();
456 clang_analyzer_warnIfReached(); // no-warning
459 void testLifeExtensionWithNoReturnDtor() {
460 const CtorWithNoReturnDtor
&c
= CtorWithNoReturnDtor();
462 // This represents an (expected) loss of coverage, since the destructor
463 // of the lifetime-exended temporary is executed at the end of
465 clang_analyzer_warnIfReached(); // no-warning
468 #if __cplusplus >= 201103L
469 struct CtorWithNoReturnDtor2
{
470 CtorWithNoReturnDtor2() = default;
472 CtorWithNoReturnDtor2(int x
) {
473 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
476 ~CtorWithNoReturnDtor2() __attribute__((noreturn
));
478 CtorWithNoReturnDtor2
returnNoReturnDtor() {
479 return {1}; // no-crash
483 #endif // TEMPORARY_DTORS
486 namespace default_param_elided_destructors
{
499 } // namespace default_param_elided_destructors
501 void testStaticMaterializeTemporaryExpr() {
502 static const Trivial
&ref
= getTrivial();
503 clang_analyzer_eval(ref
.value
== 42); // expected-warning{{TRUE}}
505 static const Trivial
&directRef
= Trivial(42);
506 clang_analyzer_eval(directRef
.value
== 42); // expected-warning{{TRUE}}
508 #if __has_feature(cxx_thread_local)
509 thread_local
static const Trivial
&threadRef
= getTrivial();
510 clang_analyzer_eval(threadRef
.value
== 42); // expected-warning{{TRUE}}
512 thread_local
static const Trivial
&threadDirectRef
= Trivial(42);
513 clang_analyzer_eval(threadDirectRef
.value
== 42); // expected-warning{{TRUE}}
519 explicit A(int* p_
) : p(p_
) {}
523 extern void escape(const A
*[]);
524 extern void check(int);
526 void callEscape(const A
& a
) {
527 const A
* args
[] = { &a
};
531 void testNoWarning() {
534 check(x
); // Analyzer used to give a "x is uninitialized warning" here
537 void set(const A
*a
[]) {
541 void callSet(const A
& a
) {
542 const A
* args
[] = { &a
};
546 void testConsistency() {
549 clang_analyzer_eval(x
== 47); // expected-warning{{TRUE}}
554 void testReturnFromStmtExprInitializer() {
555 // We shouldn't try to destroy the object pointed to by `obj' upon return.
556 const NonTrivial
&obj
= ({
563 namespace CopyToTemporaryCorrectly
{
569 virtual void mImpl() = 0;
571 class Sub
: public Super
{
573 Sub(const int &p
) : j(p
) {}
574 virtual void mImpl() override
{
575 // Used to be undefined pointer dereference because we didn't copy
576 // the subclass data (j) to the temporary object properly.
577 (void)(j
+ 1); // no-warning
579 clang_analyzer_warnIfReached(); // no-warning
590 namespace test_return_temporary
{
595 C(int x
, int y
) : x(x
), y(y
) {}
596 int getX() const { return x
; }
597 int getY() const { return y
; }
604 D(const D
&d
): C(d
.getX(), d
.getY()) {}
607 C
returnTemporaryWithVariable() { C
c(1, 2); return c
; }
608 C
returnTemporaryWithAnotherFunctionWithVariable() {
609 return returnTemporaryWithVariable();
611 C
returnTemporaryWithCopyConstructionWithVariable() {
612 return C(returnTemporaryWithVariable());
615 C
returnTemporaryWithConstruction() { return C(1, 2); }
616 C
returnTemporaryWithAnotherFunctionWithConstruction() {
617 return returnTemporaryWithConstruction();
619 C
returnTemporaryWithCopyConstructionWithConstruction() {
620 return C(returnTemporaryWithConstruction());
623 D
returnTemporaryWithVariableAndNonTrivialCopy() { D d
; return d
; }
624 D
returnTemporaryWithAnotherFunctionWithVariableAndNonTrivialCopy() {
625 return returnTemporaryWithVariableAndNonTrivialCopy();
627 D
returnTemporaryWithCopyConstructionWithVariableAndNonTrivialCopy() {
628 return D(returnTemporaryWithVariableAndNonTrivialCopy());
631 #if __cplusplus >= 201103L
632 C
returnTemporaryWithBraces() { return {1, 2}; }
633 C
returnTemporaryWithAnotherFunctionWithBraces() {
634 return returnTemporaryWithBraces();
636 C
returnTemporaryWithCopyConstructionWithBraces() {
637 return C(returnTemporaryWithBraces());
642 C c1
= returnTemporaryWithVariable();
643 clang_analyzer_eval(c1
.getX() == 1); // expected-warning{{TRUE}}
644 clang_analyzer_eval(c1
.getY() == 2); // expected-warning{{TRUE}}
646 C c2
= returnTemporaryWithAnotherFunctionWithVariable();
647 clang_analyzer_eval(c2
.getX() == 1); // expected-warning{{TRUE}}
648 clang_analyzer_eval(c2
.getY() == 2); // expected-warning{{TRUE}}
650 C c3
= returnTemporaryWithCopyConstructionWithVariable();
651 clang_analyzer_eval(c3
.getX() == 1); // expected-warning{{TRUE}}
652 clang_analyzer_eval(c3
.getY() == 2); // expected-warning{{TRUE}}
654 C c4
= returnTemporaryWithConstruction();
655 clang_analyzer_eval(c4
.getX() == 1); // expected-warning{{TRUE}}
656 clang_analyzer_eval(c4
.getY() == 2); // expected-warning{{TRUE}}
658 C c5
= returnTemporaryWithAnotherFunctionWithConstruction();
659 clang_analyzer_eval(c5
.getX() == 1); // expected-warning{{TRUE}}
660 clang_analyzer_eval(c5
.getY() == 2); // expected-warning{{TRUE}}
662 C c6
= returnTemporaryWithCopyConstructionWithConstruction();
663 clang_analyzer_eval(c5
.getX() == 1); // expected-warning{{TRUE}}
664 clang_analyzer_eval(c5
.getY() == 2); // expected-warning{{TRUE}}
666 #if __cplusplus >= 201103L
668 C c7
= returnTemporaryWithBraces();
669 clang_analyzer_eval(c7
.getX() == 1); // expected-warning{{TRUE}}
670 clang_analyzer_eval(c7
.getY() == 2); // expected-warning{{TRUE}}
672 C c8
= returnTemporaryWithAnotherFunctionWithBraces();
673 clang_analyzer_eval(c8
.getX() == 1); // expected-warning{{TRUE}}
674 clang_analyzer_eval(c8
.getY() == 2); // expected-warning{{TRUE}}
676 C c9
= returnTemporaryWithCopyConstructionWithBraces();
677 clang_analyzer_eval(c9
.getX() == 1); // expected-warning{{TRUE}}
678 clang_analyzer_eval(c9
.getY() == 2); // expected-warning{{TRUE}}
682 D d1
= returnTemporaryWithVariableAndNonTrivialCopy();
683 clang_analyzer_eval(d1
.getX() == 1); // expected-warning{{TRUE}}
684 clang_analyzer_eval(d1
.getY() == 2); // expected-warning{{TRUE}}
686 D d2
= returnTemporaryWithAnotherFunctionWithVariableAndNonTrivialCopy();
687 clang_analyzer_eval(d2
.getX() == 1); // expected-warning{{TRUE}}
688 clang_analyzer_eval(d2
.getY() == 2); // expected-warning{{TRUE}}
690 D d3
= returnTemporaryWithCopyConstructionWithVariableAndNonTrivialCopy();
691 clang_analyzer_eval(d3
.getX() == 1); // expected-warning{{TRUE}}
692 clang_analyzer_eval(d3
.getY() == 2); // expected-warning{{TRUE}}
694 } // namespace test_return_temporary
697 namespace test_temporary_object_expr_without_dtor
{
702 int getX() const { return x
; }
706 clang_analyzer_eval(C(3).getX() == 3); // expected-warning{{TRUE}}
710 namespace test_temporary_object_expr_with_dtor
{
717 int getX() const { return x
; }
720 void test(int coin
) {
721 clang_analyzer_eval(C(3).getX() == 3);
722 #ifdef TEMPORARY_DTORS
723 // expected-warning@-2{{TRUE}}
725 // expected-warning@-4{{UNKNOWN}}
728 const C
&c1
= coin
? C(1) : C(2);
730 clang_analyzer_eval(c1
.getX() == 1);
731 #ifdef TEMPORARY_DTORS
732 // expected-warning@-2{{TRUE}}
734 // expected-warning@-4{{UNKNOWN}}
737 clang_analyzer_eval(c1
.getX() == 2);
738 #ifdef TEMPORARY_DTORS
739 // expected-warning@-2{{TRUE}}
741 // expected-warning@-4{{UNKNOWN}}
745 C c2
= coin
? C(1) : C(2);
747 clang_analyzer_eval(c2
.getX() == 1); // expected-warning{{TRUE}}
749 clang_analyzer_eval(c2
.getX() == 2); // expected-warning{{TRUE}}
753 } // namespace test_temporary_object_expr
755 namespace test_match_constructors_and_destructors
{
759 C(int &_x
, int &_y
) : x(_x
), y(_y
) { ++x
; }
760 C(const C
&c
): x(c
.x
), y(c
.y
) { ++x
; }
764 void test_simple_temporary() {
767 const C
&c
= C(x
, y
);
769 // One constructor and one destructor.
770 clang_analyzer_eval(x
== 1);
771 clang_analyzer_eval(y
== 1);
772 #ifdef TEMPORARY_DTORS
773 // expected-warning@-3{{TRUE}}
774 // expected-warning@-3{{TRUE}}
776 // expected-warning@-6{{UNKNOWN}}
777 // expected-warning@-6{{UNKNOWN}}
781 void test_simple_temporary_with_copy() {
786 // Only one constructor directly into the variable, and one destructor.
787 clang_analyzer_eval(x
== 1); // expected-warning{{TRUE}}
788 clang_analyzer_eval(y
== 1); // expected-warning{{TRUE}}
791 void test_ternary_temporary(int coin
) {
792 int x
= 0, y
= 0, z
= 0, w
= 0;
794 const C
&c
= coin
? C(x
, y
) : C(z
, w
);
796 // Only one constructor on every branch, and one automatic destructor.
798 clang_analyzer_eval(x
== 1);
799 clang_analyzer_eval(y
== 1);
800 #ifdef TEMPORARY_DTORS
801 // expected-warning@-3{{TRUE}}
802 // expected-warning@-3{{TRUE}}
804 // expected-warning@-6{{UNKNOWN}}
805 // expected-warning@-6{{UNKNOWN}}
807 clang_analyzer_eval(z
== 0); // expected-warning{{TRUE}}
808 clang_analyzer_eval(w
== 0); // expected-warning{{TRUE}}
811 clang_analyzer_eval(x
== 0); // expected-warning{{TRUE}}
812 clang_analyzer_eval(y
== 0); // expected-warning{{TRUE}}
813 clang_analyzer_eval(z
== 1);
814 clang_analyzer_eval(w
== 1);
815 #ifdef TEMPORARY_DTORS
816 // expected-warning@-3{{TRUE}}
817 // expected-warning@-3{{TRUE}}
819 // expected-warning@-6{{UNKNOWN}}
820 // expected-warning@-6{{UNKNOWN}}
825 void test_ternary_temporary_with_copy(int coin
) {
826 int x
= 0, y
= 0, z
= 0, w
= 0;
828 C c
= coin
? C(x
, y
) : C(z
, w
);
830 // On each branch the variable is constructed directly.
832 clang_analyzer_eval(x
== 1); // expected-warning{{TRUE}}
833 clang_analyzer_eval(y
== 1); // expected-warning{{TRUE}}
834 clang_analyzer_eval(z
== 0); // expected-warning{{TRUE}}
835 clang_analyzer_eval(w
== 0); // expected-warning{{TRUE}}
838 clang_analyzer_eval(x
== 0); // expected-warning{{TRUE}}
839 clang_analyzer_eval(y
== 0); // expected-warning{{TRUE}}
840 clang_analyzer_eval(z
== 1); // expected-warning{{TRUE}}
841 clang_analyzer_eval(w
== 1); // expected-warning{{TRUE}}
844 } // namespace test_match_constructors_and_destructors
846 namespace destructors_for_return_values
{
851 1 / 0; // expected-warning{{Division by zero}}
857 void testFloatingCall() {
859 // Should have divided by zero in the destructor.
860 clang_analyzer_warnIfReached();
861 #ifndef TEMPORARY_DTORS
862 // expected-warning@-2{{REACHABLE}}
866 void testLifetimeExtendedCall() {
869 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
871 // Should have divided by zero in the destructor.
872 clang_analyzer_warnIfReached(); // no-warning
875 void testCopiedCall() {
878 // Should have elided the constructor/destructor for the temporary
879 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
881 // Should have divided by zero in the destructor.
882 clang_analyzer_warnIfReached(); // no-warning
884 } // namespace destructors_for_return_values
886 namespace dont_forget_destructor_around_logical_op
{
893 clang_analyzer_checkInlined(true);
894 #ifdef TEMPORARY_DTORS
895 // expected-warning@-2{{TRUE}}
905 void test(int coin
) {
906 // Here temporaries are being cleaned up after && is evaluated. There are two
907 // temporaries: the return value of get() and the elidable copy constructor
908 // of that return value into is(). According to the CFG, we need to cleanup
909 // both of them depending on whether the temporary corresponding to the
910 // return value of get() was initialized. However, we didn't track
911 // temporaries returned from functions, so we took the wrong branch.
912 coin
&& is(get()); // no-crash
914 clang_analyzer_eval(glob
);
915 #ifdef TEMPORARY_DTORS
916 // expected-warning@-2{{TRUE}}
918 // expected-warning@-4{{UNKNOWN}}
921 // The destructor is not called on this branch.
922 clang_analyzer_eval(glob
); // expected-warning{{UNKNOWN}}
925 } // namespace dont_forget_destructor_around_logical_op
927 #if __cplusplus >= 201103L
928 namespace temporary_list_crash
{
936 std::initializer_list
<C
>{C(), C()}; // no-crash
938 } // namespace temporary_list_crash
941 namespace implicit_constructor_conversion
{
952 C(const S
&s
) : x(s
.x
) {}
954 int getX() const { return x
; }
959 clang_analyzer_eval(c1
.getX() == 10);
960 #ifdef TEMPORARY_DTORS
961 // expected-warning@-2{{TRUE}}
963 // expected-warning@-4{{UNKNOWN}}
967 clang_analyzer_eval(s
.x
== 20); // expected-warning{{TRUE}}
970 clang_analyzer_eval(c2
.getX() == 20); // expected-warning{{TRUE}}
972 } // end namespace implicit_constructor_conversion
974 namespace pass_references_through
{
983 // In these examples the foo() expression has record type, not reference type.
984 // Don't try to figure out how to perform construction of the record here.
985 const C
&bar1() { return foo1(); } // no-crash
986 C
&&bar2() { return foo2(); } // no-crash
987 } // end namespace pass_references_through
990 namespace arguments
{
996 S(const S
&s
) : x(s
.x
) {}
1008 virtual void bar3(S s
) {}
1014 virtual void bar3(S s
) override
{ glob
= s
.x
; }
1021 // Record-typed calls are a different CFGStmt, let's see if we handle that
1028 void bar5(int, ...);
1030 void foo(void (*bar4
)(S
)) {
1032 clang_analyzer_eval(glob
== 1);
1033 #ifdef TEMPORARY_DTORS
1034 // expected-warning@-2{{TRUE}}
1036 // expected-warning@-4{{UNKNOWN}}
1040 clang_analyzer_eval(glob
== 2);
1041 #ifdef TEMPORARY_DTORS
1042 // expected-warning@-2{{TRUE}}
1044 // expected-warning@-4{{UNKNOWN}}
1049 // FIXME: Should be TRUE.
1050 clang_analyzer_eval(glob
== 3); // expected-warning{{UNKNOWN}}
1053 // What if we've no idea what we're calling?
1054 bar4(S(4)); // no-crash
1057 clang_analyzer_eval(glob
== 6);
1058 #ifdef TEMPORARY_DTORS
1059 // expected-warning@-2{{TRUE}}
1061 // expected-warning@-4{{UNKNOWN}}
1064 // Variadic functions. This will __builtin_trap() because you cannot pass
1065 // an object as a variadic argument.
1066 bar5(7, S(7)); // no-crash
1067 clang_analyzer_warnIfReached(); // no-warning
1069 } // namespace arguments
1071 namespace ctor_argument
{
1072 // Stripped down unique_ptr<int>
1074 IntPtr(): i(new int) {}
1075 IntPtr(IntPtr
&&o
): i(o
.i
) { o
.i
= 0; }
1076 ~IntPtr() { delete i
; }
1091 Foo
f(static_cast<IntPtr
&&>(ptr
));
1092 *i
= 99; // no-warning
1094 } // namespace ctor_argument
1096 namespace operator_implicit_argument
{
1100 operator bool() const { return x
; }
1105 clang_analyzer_warnIfReached(); // no-warning
1108 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
1111 } // namespace operator_implicit_argument
1114 #if __cplusplus >= 201103L
1115 namespace argument_lazy_bindings
{
1125 T(int w
): s
{5, 6, 7}, w(w
) {}
1135 clang_analyzer_eval(glob
== 4); // expected-warning{{TRUE}}
1137 } // namespace argument_lazy_bindings
1140 namespace operator_argument_cleanup
{
1152 c
= S(); // no-crash
1154 } // namespace operator_argument_cleanup
1156 namespace argument_decl_lookup
{
1159 int bar(C c
) { foo(c
); }
1161 } // namespace argument_decl_lookup
1163 namespace argument_virtual_decl_lookup
{
1167 virtual void foo(C
);
1172 t
->foo(C()); // no-crash // expected-warning{{Called C++ object pointer is uninitialized}}
1175 // This is after run() because the test is about picking the correct decl
1176 // for the parameter region, which should belong to the correct function decl,
1177 // and the non-definition decl should be found by direct lookup.
1179 } // namespace argument_virtual_decl_lookup
1181 namespace union_indirect_field_crash
{
1188 template <typename T
> class C
{
1191 (void)(true ? U().x
: 0);
1199 } // namespace union_indirect_field_crash
1201 namespace return_from_top_frame
{
1204 S() { p
= new int; }
1205 S(S
&&s
) : p(s
.p
) { s
.p
= 0; }
1206 ~S(); // Presumably releases 'p'.
1215 return foo(); // no-warning
1223 return coin
? S() : foo(); // no-warning
1225 } // namespace return_from_top_frame
1227 #if __cplusplus >= 201103L
1228 namespace arguments_of_operators
{
1236 auto foo
= [](S s
, int &y
) { y
= 1; };
1238 clang_analyzer_eval(x
== 1); // expected-warning{{TRUE}}
1240 } // namespace arguments_of_operators
1241 #endif // __cplusplus >= 201103L