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