1*525d4122SHenry Wong // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config widen-loops=true -analyzer-disable-retry-exhausted -verify %s 2*525d4122SHenry Wong 3*525d4122SHenry Wong void clang_analyzer_eval(bool); 4*525d4122SHenry Wong void clang_analyzer_dump(int); 5*525d4122SHenry Wong 6*525d4122SHenry Wong // 'this' pointer is not an lvalue, we should not invalidate it. 7*525d4122SHenry Wong namespace this_pointer_after_loop_widen { 8*525d4122SHenry Wong class A { 9*525d4122SHenry Wong public: A()10*525d4122SHenry Wong A() { 11*525d4122SHenry Wong int count = 10; 12*525d4122SHenry Wong do { 13*525d4122SHenry Wong } while (count--); 14*525d4122SHenry Wong } 15*525d4122SHenry Wong }; 16*525d4122SHenry Wong 17*525d4122SHenry Wong void goo(A a); test_temporary_object()18*525d4122SHenry Wongvoid test_temporary_object() { 19*525d4122SHenry Wong goo(A()); // no-crash 20*525d4122SHenry Wong } 21*525d4122SHenry Wong 22*525d4122SHenry Wong struct B { 23*525d4122SHenry Wong int mem; Bthis_pointer_after_loop_widen::B24*525d4122SHenry Wong B() : mem(0) { 25*525d4122SHenry Wong for (int i = 0; i < 10; ++i) { 26*525d4122SHenry Wong } 27*525d4122SHenry Wong mem = 0; 28*525d4122SHenry Wong } 29*525d4122SHenry Wong }; 30*525d4122SHenry Wong test_ctor()31*525d4122SHenry Wongvoid test_ctor() { 32*525d4122SHenry Wong B b; 33*525d4122SHenry Wong clang_analyzer_eval(b.mem == 0); // expected-warning{{TRUE}} 34*525d4122SHenry Wong } 35*525d4122SHenry Wong 36*525d4122SHenry Wong struct C { 37*525d4122SHenry Wong int mem; Cthis_pointer_after_loop_widen::C38*525d4122SHenry Wong C() : mem(0) {} setthis_pointer_after_loop_widen::C39*525d4122SHenry Wong void set() { 40*525d4122SHenry Wong for (int i = 0; i < 10; ++i) { 41*525d4122SHenry Wong } 42*525d4122SHenry Wong mem = 10; 43*525d4122SHenry Wong } 44*525d4122SHenry Wong }; 45*525d4122SHenry Wong test_method()46*525d4122SHenry Wongvoid test_method() { 47*525d4122SHenry Wong C c; 48*525d4122SHenry Wong clang_analyzer_eval(c.mem == 0); // expected-warning{{TRUE}} 49*525d4122SHenry Wong c.set(); 50*525d4122SHenry Wong clang_analyzer_eval(c.mem == 10); // expected-warning{{TRUE}} 51*525d4122SHenry Wong } 52*525d4122SHenry Wong 53*525d4122SHenry Wong struct D { 54*525d4122SHenry Wong int mem; Dthis_pointer_after_loop_widen::D55*525d4122SHenry Wong D() : mem(0) {} setthis_pointer_after_loop_widen::D56*525d4122SHenry Wong void set() { 57*525d4122SHenry Wong for (int i = 0; i < 10; ++i) { 58*525d4122SHenry Wong } 59*525d4122SHenry Wong mem = 10; 60*525d4122SHenry Wong } 61*525d4122SHenry Wong }; 62*525d4122SHenry Wong test_new()63*525d4122SHenry Wongvoid test_new() { 64*525d4122SHenry Wong D *d = new D; 65*525d4122SHenry Wong clang_analyzer_eval(d->mem == 0); // expected-warning{{TRUE}} 66*525d4122SHenry Wong d->set(); 67*525d4122SHenry Wong clang_analyzer_eval(d->mem == 10); // expected-warning{{TRUE}} 68*525d4122SHenry Wong } 69*525d4122SHenry Wong 70*525d4122SHenry Wong struct E { 71*525d4122SHenry Wong int mem; Ethis_pointer_after_loop_widen::E72*525d4122SHenry Wong E() : mem(0) {} setthis_pointer_after_loop_widen::E73*525d4122SHenry Wong void set() { 74*525d4122SHenry Wong for (int i = 0; i < 10; ++i) { 75*525d4122SHenry Wong } 76*525d4122SHenry Wong setAux(); 77*525d4122SHenry Wong } setAuxthis_pointer_after_loop_widen::E78*525d4122SHenry Wong void setAux() { 79*525d4122SHenry Wong this->mem = 10; 80*525d4122SHenry Wong } 81*525d4122SHenry Wong }; 82*525d4122SHenry Wong test_chained_method_call()83*525d4122SHenry Wongvoid test_chained_method_call() { 84*525d4122SHenry Wong E e; 85*525d4122SHenry Wong e.set(); 86*525d4122SHenry Wong clang_analyzer_eval(e.mem == 10); // expected-warning{{TRUE}} 87*525d4122SHenry Wong } 88*525d4122SHenry Wong } // namespace this_pointer_after_loop_widen 89