temporaries.cpp revision a4de17562d13d7a8188108243c4cfbd52f33229a
16376703eb3325fe41233aed234fde81164af42a1Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s 299b3cc6ec4fbcd887b632dcb7147ef472d83fc37Pavel Labath// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s 3176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s -std=c++11 473212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 59f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Roseextern bool clang_analyzer_eval(bool); 6176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesextern bool clang_analyzer_warnIfReached(); 79f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose 873212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rosestruct Trivial { 973212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose Trivial(int x) : value(x) {} 1073212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose int value; 1173212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose}; 1273212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 1373212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rosestruct NonTrivial : public Trivial { 1473212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose NonTrivial(int x) : Trivial(x) {} 1573212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose ~NonTrivial(); 1673212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose}; 1773212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 1873212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 1973212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan RoseTrivial getTrivial() { 2073212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose return Trivial(42); // no-warning 2173212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose} 2273212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 2373212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Roseconst Trivial &getTrivialRef() { 24a0e6e6dd37f4acee8477c106d5e5679de015d120Jordan Rose return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'Trivial' returned to caller}} 2573212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose} 2673212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 2773212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 2873212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan RoseNonTrivial getNonTrivial() { 2973212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose return NonTrivial(42); // no-warning 3073212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose} 3173212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 3273212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Roseconst NonTrivial &getNonTrivialRef() { 33a0e6e6dd37f4acee8477c106d5e5679de015d120Jordan Rose return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'NonTrivial' returned to caller}} 3473212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose} 3573212dff6437d409e0c1b779fdcac2f4f98ca8b0Jordan Rose 369f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rosenamespace rdar13265460 { 379f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose struct TrivialSubclass : public Trivial { 389f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose TrivialSubclass(int x) : Trivial(x), anotherValue(-x) {} 399f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose int anotherValue; 409f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose }; 419f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose 429f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose TrivialSubclass getTrivialSub() { 439f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose TrivialSubclass obj(1); 449f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose obj.value = 42; 459f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose obj.anotherValue = -42; 469f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose return obj; 479f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose } 489f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose 495e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose void testImmediate() { 509f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose TrivialSubclass obj = getTrivialSub(); 519f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose 529f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose clang_analyzer_eval(obj.value == 42); // expected-warning{{TRUE}} 539f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose clang_analyzer_eval(obj.anotherValue == -42); // expected-warning{{TRUE}} 549f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose 559f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose clang_analyzer_eval(getTrivialSub().value == 42); // expected-warning{{TRUE}} 569f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose clang_analyzer_eval(getTrivialSub().anotherValue == -42); // expected-warning{{TRUE}} 579f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose } 585e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 595e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose void testMaterializeTemporaryExpr() { 605e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const TrivialSubclass &ref = getTrivialSub(); 615e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose clang_analyzer_eval(ref.value == 42); // expected-warning{{TRUE}} 625e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 635e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Trivial &baseRef = getTrivialSub(); 645e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose clang_analyzer_eval(baseRef.value == 42); // expected-warning{{TRUE}} 655e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose } 669f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose} 679f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose 68eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rosenamespace rdar13281951 { 69eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose struct Derived : public Trivial { 70eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose Derived(int value) : Trivial(value), value2(-value) {} 71eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose int value2; 72eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose }; 73eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose 74eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose void test() { 75eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose Derived obj(1); 76eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose obj.value = 42; 77eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose const Trivial * const &pointerRef = &obj; 78eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose clang_analyzer_eval(pointerRef->value == 42); // expected-warning{{TRUE}} 79eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose } 80eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose} 81eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose 826376703eb3325fe41233aed234fde81164af42a1Jordan Rosenamespace compound_literals { 836376703eb3325fe41233aed234fde81164af42a1Jordan Rose struct POD { 846376703eb3325fe41233aed234fde81164af42a1Jordan Rose int x, y; 856376703eb3325fe41233aed234fde81164af42a1Jordan Rose }; 866376703eb3325fe41233aed234fde81164af42a1Jordan Rose struct HasCtor { 876376703eb3325fe41233aed234fde81164af42a1Jordan Rose HasCtor(int x, int y) : x(x), y(y) {} 886376703eb3325fe41233aed234fde81164af42a1Jordan Rose int x, y; 896376703eb3325fe41233aed234fde81164af42a1Jordan Rose }; 906376703eb3325fe41233aed234fde81164af42a1Jordan Rose struct HasDtor { 916376703eb3325fe41233aed234fde81164af42a1Jordan Rose int x, y; 926376703eb3325fe41233aed234fde81164af42a1Jordan Rose ~HasDtor(); 936376703eb3325fe41233aed234fde81164af42a1Jordan Rose }; 946376703eb3325fe41233aed234fde81164af42a1Jordan Rose struct HasCtorDtor { 956376703eb3325fe41233aed234fde81164af42a1Jordan Rose HasCtorDtor(int x, int y) : x(x), y(y) {} 966376703eb3325fe41233aed234fde81164af42a1Jordan Rose ~HasCtorDtor(); 976376703eb3325fe41233aed234fde81164af42a1Jordan Rose int x, y; 986376703eb3325fe41233aed234fde81164af42a1Jordan Rose }; 996376703eb3325fe41233aed234fde81164af42a1Jordan Rose 1006376703eb3325fe41233aed234fde81164af42a1Jordan Rose void test() { 1016376703eb3325fe41233aed234fde81164af42a1Jordan Rose clang_analyzer_eval(((POD){1, 42}).y == 42); // expected-warning{{TRUE}} 1026376703eb3325fe41233aed234fde81164af42a1Jordan Rose clang_analyzer_eval(((HasDtor){1, 42}).y == 42); // expected-warning{{TRUE}} 1036376703eb3325fe41233aed234fde81164af42a1Jordan Rose 1046376703eb3325fe41233aed234fde81164af42a1Jordan Rose#if __cplusplus >= 201103L 1056376703eb3325fe41233aed234fde81164af42a1Jordan Rose clang_analyzer_eval(((HasCtor){1, 42}).y == 42); // expected-warning{{TRUE}} 1066376703eb3325fe41233aed234fde81164af42a1Jordan Rose 1076376703eb3325fe41233aed234fde81164af42a1Jordan Rose // FIXME: should be TRUE, but we don't inline the constructors of 1086376703eb3325fe41233aed234fde81164af42a1Jordan Rose // temporaries because we can't model their destructors yet. 1096376703eb3325fe41233aed234fde81164af42a1Jordan Rose clang_analyzer_eval(((HasCtorDtor){1, 42}).y == 42); // expected-warning{{UNKNOWN}} 1106376703eb3325fe41233aed234fde81164af42a1Jordan Rose#endif 1116376703eb3325fe41233aed234fde81164af42a1Jordan Rose } 1126376703eb3325fe41233aed234fde81164af42a1Jordan Rose} 1136376703eb3325fe41233aed234fde81164af42a1Jordan Rose 114062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rosenamespace destructors { 115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines struct Dtor { 116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ~Dtor(); 117176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines }; 118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines extern bool coin(); 119176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines extern bool check(const Dtor &); 120062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose 121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testPR16664andPR18159Crash() { 1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Regression test: we used to assert here when tmp dtors are enabled. 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // PR16664 and PR18159 124062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose if (coin() && (coin() || coin() || check(Dtor()))) { 125062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose Dtor(); 126062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose } 127062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose } 128062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose 12995ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath#ifdef TEMPORARY_DTORS 13095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath struct NoReturnDtor { 13195ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath ~NoReturnDtor() __attribute__((noreturn)); 13295ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath }; 13395ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 13495ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath void noReturnTemp(int *x) { 13595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath if (! x) NoReturnDtor(); 13695ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath *x = 47; // no warning 13795ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath } 13895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 13995ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath void noReturnInline(int **x) { 14095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath NoReturnDtor(); 14195ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath } 14295ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 14395ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath void callNoReturn() { 14495ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath int *x; 14595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath noReturnInline(&x); 14695ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath *x = 47; // no warning 14795ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath } 14895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 14995ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath extern bool check(const NoReturnDtor &); 15095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 15195ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath void testConsistencyIf(int i) { 152062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose if (i != 5) 153062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose return; 154062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose if (i == 5 && (i == 4 || check(NoReturnDtor()) || i == 5)) { 15595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath clang_analyzer_eval(true); // no warning, unreachable code 15695ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath } 15795ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath } 15895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 15995ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath void testConsistencyTernary(int i) { 16095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath (i == 5 && (i == 4 || check(NoReturnDtor()) || i == 5)) ? 1 : 0; 16195ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 16295ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath clang_analyzer_eval(true); // expected-warning{{TRUE}} 16395ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 16495ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath if (i != 5) 16595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath return; 16695ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 16795ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath (i == 5 && (i == 4 || check(NoReturnDtor()) || i == 5)) ? 1 : 0; 16895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 16995ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath clang_analyzer_eval(true); // no warning, unreachable code 17095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath } 17195ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 1726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Regression test: we used to assert here. 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // PR16664 and PR18159 17495ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath void testConsistencyNested(int i) { 17595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath extern bool compute(bool); 1766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 177dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling if (i == 5 && (i == 4 || i == 5 || check(NoReturnDtor()))) 1786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines clang_analyzer_eval(true); // expected-warning{{TRUE}} 1796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 18095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath if (i == 5 && (i == 4 || i == 5 || check(NoReturnDtor()))) 1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines clang_analyzer_eval(true); // expected-warning{{TRUE}} 18295ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 18395ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath if (i != 5) 18495ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath return; 18595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 18695ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath if (compute(i == 5 && 18795ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath (i == 4 || compute(true) || 18895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath compute(i == 5 && (i == 4 || check(NoReturnDtor()))))) || 18995ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath i != 4) { 1906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines clang_analyzer_eval(true); // expected-warning{{TRUE}} 191062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose } 19295ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 19395ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath if (compute(i == 5 && 19495ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath (i == 4 || i == 4 || 19595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath compute(i == 5 && (i == 4 || check(NoReturnDtor()))))) || 19695ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath i != 4) { 197176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 19895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath } 1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // PR16664 and PR18159 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void testConsistencyNestedSimple(bool value) { 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (value) { 204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!value || check(NoReturnDtor())) { 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // PR16664 and PR18159 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void testConsistencyNestedComplex(bool value) { 212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (value) { 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!value || !value || check(NoReturnDtor())) { 214176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // PR16664 and PR18159 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void testConsistencyNestedWarning(bool value) { 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (value) { 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!value || value || check(NoReturnDtor())) { 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines clang_analyzer_eval(true); // expected-warning{{TRUE}} 224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 227176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // PR16664 and PR18159 228176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testConsistencyNestedComplexMidBranch(bool value) { 229176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (value) { 230176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!value || !value || check(NoReturnDtor()) || value) { 231176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 232176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 233176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 234176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 235176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 236176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // PR16664 and PR18159 237176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testConsistencyNestedComplexNestedBranch(bool value) { 238176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (value) { 239176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!value || (!value || check(NoReturnDtor()) || value)) { 240176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 241176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 242176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 243176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 244176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 245176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // PR16664 and PR18159 246176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testConsistencyNestedVariableModification(bool value) { 247176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool other = true; 248176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (value) { 249176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!other || !value || (other = false) || check(NoReturnDtor()) || 250176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines !other) { 251176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 252176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 253176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 254176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 255176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 256176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testTernaryNoReturnTrueBranch(bool value) { 257176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (value) { 258176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool b = value && (value ? check(NoReturnDtor()) : true); 259176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 260176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 261176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 262176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testTernaryNoReturnFalseBranch(bool value) { 263176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (value) { 264176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool b = !value && !value ? true : check(NoReturnDtor()); 265176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 266176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 267176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 268176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testTernaryIgnoreNoreturnBranch(bool value) { 269176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (value) { 270176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool b = !value && !value ? check(NoReturnDtor()) : true; 271176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // expected-warning{{TRUE}} 272176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 273176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 274176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testTernaryTrueBranchReached(bool value) { 275176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines value ? clang_analyzer_warnIfReached() : // expected-warning{{REACHABLE}} 276176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines check(NoReturnDtor()); 277176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 278176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testTernaryFalseBranchReached(bool value) { 279176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines value ? check(NoReturnDtor()) : 280176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 281176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 282176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 283176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testLoop() { 284176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (int i = 0; i < 10; ++i) { 285176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (i < 3 && (i >= 2 || check(NoReturnDtor()))) { 286176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 287176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 288176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 289176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 290176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 291176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool testRecursiveFrames(bool isInner) { 292176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (isInner || 293176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (clang_analyzer_warnIfReached(), false) || // expected-warning{{REACHABLE}} 294176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines check(NoReturnDtor()) || 295176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines testRecursiveFrames(true)) { 296176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 297176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 298176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 299176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testRecursiveFramesStart() { testRecursiveFrames(false); } 300176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 301176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testLambdas() { 302a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar []() { check(NoReturnDtor()); } != nullptr || check(Dtor()); 303176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 304176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 305176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testGnuExpressionStatements(int v) { 306176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ({ ++v; v == 10 || check(NoReturnDtor()); v == 42; }) || v == 23; 307176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 308176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 309176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ({ ++v; check(NoReturnDtor()); v == 42; }) || v == 23; 310176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // no warning, unreachable code 311176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 312176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 313176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testGnuExpressionStatementsDestructionPoint(int v) { 314176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // In normal context, the temporary destructor runs at the end of the full 315176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // statement, thus the last statement is reached. 316176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (++v, check(NoReturnDtor()), v == 42), 317176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 318176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 319176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // GNU expression statements execute temporary destructors within the 320176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // blocks, thus the last statement is not reached. 321176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ({ ++v; check(NoReturnDtor()); v == 42; }), 322176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // no warning, unreachable code 323176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 324176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 325176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testMultipleTemporaries(bool value) { 326176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (value) { 327176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Find a way to verify construction order. 328176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // ~Dtor should run before ~NoReturnDtor() because construction order is 329176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // guaranteed by comma operator. 330176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!value || check((NoReturnDtor(), Dtor())) || value) { 331176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_eval(true); // no warning, unreachable code 332176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 333176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 334176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 335651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void testBinaryOperatorShortcut(bool value) { 3376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (value) { 3386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (false && false && check(NoReturnDtor()) && true) { 3396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines clang_analyzer_eval(true); 3406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 344176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testIfAtEndOfLoop() { 345176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines int y = 0; 346176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines while (true) { 347176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (y > 0) { 348176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 349176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 350176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ++y; 351176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Test that the CFG gets hooked up correctly when temporary destructors 352176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // are handled after a statically known branch condition. 353176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (true) (void)0; else (void)check(NoReturnDtor()); 354176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 355176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 356176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 357176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testTernaryAtEndOfLoop() { 358176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines int y = 0; 359176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines while (true) { 360176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (y > 0) { 361176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 362176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 363176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ++y; 364176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Test that the CFG gets hooked up correctly when temporary destructors 365176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // are handled after a statically known branch condition. 366176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines true ? (void)0 : (void)check(NoReturnDtor()); 367176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 368176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 369176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 370176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testNoReturnInComplexCondition() { 371176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines check(Dtor()) && 372176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (check(NoReturnDtor()) || check(NoReturnDtor())) && check(Dtor()); 373176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 374176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 375176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 376176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testSequencingOfConditionalTempDtors(bool b) { 377176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines b || (check(Dtor()), check(NoReturnDtor())); 378176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 379176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 380176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 381176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testSequencingOfConditionalTempDtors2(bool b) { 382176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (b || check(Dtor())), check(NoReturnDtor()); 383176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // no warning, unreachable code 384176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 385176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 386176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testSequencingOfConditionalTempDtorsWithinBinaryOperators(bool b) { 387176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines b || (check(Dtor()) + check(NoReturnDtor())); 388176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 389176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 390176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 391176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void f(Dtor d = Dtor()); 392176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testDefaultParameters() { 393176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines f(); 394176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 395176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 396176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines struct DefaultParam { 397176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DefaultParam(int, const Dtor& d = Dtor()); 398176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ~DefaultParam(); 399176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines }; 400176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testDefaultParamConstructorsInLoops() { 401176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines while (true) { 402176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: This exact pattern triggers the temporary cleanup logic 403176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // to fail when adding a 'clean' state. 404176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DefaultParam(42); 405176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DefaultParam(42); 406176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 407176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 408176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void testDefaultParamConstructorsInTernariesInLoops(bool value) { 409176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines while (true) { 410176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: This exact pattern triggers the temporary cleanup logic 411176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // to visit the bind-temporary logic with a state that already has that 412176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // temporary marked as executed. 413176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines value ? DefaultParam(42) : DefaultParam(42); 414176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 415176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 41695ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath#endif // TEMPORARY_DTORS 417062ef6e6d956b8873e33fe84574c7630d2829d3dJordan Rose} 41876b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath 41976b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labathvoid testStaticMaterializeTemporaryExpr() { 42076b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath static const Trivial &ref = getTrivial(); 42176b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath clang_analyzer_eval(ref.value == 42); // expected-warning{{TRUE}} 42276b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath 42376b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath static const Trivial &directRef = Trivial(42); 42476b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath clang_analyzer_eval(directRef.value == 42); // expected-warning{{TRUE}} 42576b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath 42699b3cc6ec4fbcd887b632dcb7147ef472d83fc37Pavel Labath#if __has_feature(cxx_thread_local) 42776b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath thread_local static const Trivial &threadRef = getTrivial(); 42876b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath clang_analyzer_eval(threadRef.value == 42); // expected-warning{{TRUE}} 42976b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath 43076b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath thread_local static const Trivial &threadDirectRef = Trivial(42); 43176b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath clang_analyzer_eval(threadDirectRef.value == 42); // expected-warning{{TRUE}} 43276b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath#endif 43376b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath} 4346ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath 4356ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labathnamespace PR16629 { 4366ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath struct A { 4376ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath explicit A(int* p_) : p(p_) {} 4386ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath int* p; 4396ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath }; 4406ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath 4416ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath extern void escape(const A*[]); 4426ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath extern void check(int); 4436ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath 4446ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath void callEscape(const A& a) { 4456ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath const A* args[] = { &a }; 4466ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath escape(args); 4476ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath } 4486ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath 4496ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath void testNoWarning() { 4506ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath int x; 4516ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath callEscape(A(&x)); 4526ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath check(x); // Analyzer used to give a "x is uninitialized warning" here 4536ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath } 4546ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath 4556ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath void set(const A*a[]) { 4566ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath *a[0]->p = 47; 4576ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath } 4586ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath 4596ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath void callSet(const A& a) { 4606ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath const A* args[] = { &a }; 4616ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath set(args); 4626ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath } 4636ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath 4646ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath void testConsistency() { 4656ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath int x; 4666ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath callSet(A(&x)); 4676ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath clang_analyzer_eval(x == 47); // expected-warning{{TRUE}} 4686ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath } 4696ebe9df900b79fd56a4db03b4f8aa6a180307a9dPavel Labath} 470