xref: /llvm-project/clang/test/Analysis/this-pointer.cpp (revision 525d4122c9ed09f50dee8683a14f4700cf5eb130)
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 Wong void 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 Wong void 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 Wong void 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 Wong void 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 Wong void 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