Clang Project

clang_source_code/test/Analysis/this-pointer.cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config widen-loops=true -analyzer-disable-retry-exhausted -verify %s
2
3void clang_analyzer_eval(bool);
4void clang_analyzer_dump(int);
5
6// 'this' pointer is not an lvalue, we should not invalidate it.
7namespace this_pointer_after_loop_widen {
8class A {
9public:
10  A() {
11    int count = 10;
12    do {
13    } while (count--);
14  }
15};
16
17void goo(A a);
18void test_temporary_object() {
19  goo(A()); // no-crash
20}
21
22struct B {
23  int mem;
24  B() : mem(0) {
25    for (int i = 0; i < 10; ++i) {
26    }
27    mem = 0;
28  }
29};
30
31void test_ctor() {
32  B b;
33  clang_analyzer_eval(b.mem == 0); // expected-warning{{TRUE}}
34}
35
36struct C {
37  int mem;
38  C() : mem(0) {}
39  void set() {
40    for (int i = 0; i < 10; ++i) {
41    }
42    mem = 10;
43  }
44};
45
46void 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
53struct D {
54  int mem;
55  D() : mem(0) {}
56  void set() {
57    for (int i = 0; i < 10; ++i) {
58    }
59    mem = 10;
60  }
61};
62
63void 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
70struct E {
71  int mem;
72  E() : mem(0) {}
73  void set() {
74    for (int i = 0; i < 10; ++i) {
75    }
76    setAux();
77  }
78  void setAux() {
79    this->mem = 10;
80  }
81};
82
83void 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