inline.cpp revision b6d2bea04801cb66263de2f3fe99ef8e1dcd9f53
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
2
3void clang_analyzer_eval(bool);
4void clang_analyzer_checkInlined(bool);
5
6class A {
7public:
8  int getZero() { return 0; }
9  virtual int getNum() { return 0; }
10};
11
12void test(A &a) {
13  clang_analyzer_eval(a.getZero() == 0); // expected-warning{{TRUE}}
14  clang_analyzer_eval(a.getNum() == 0); // expected-warning{{UNKNOWN}}
15
16  A copy(a);
17  clang_analyzer_eval(copy.getZero() == 0); // expected-warning{{TRUE}}
18  clang_analyzer_eval(copy.getNum() == 0); // expected-warning{{TRUE}}
19}
20
21
22class One : public A {
23public:
24  virtual int getNum() { return 1; }
25};
26
27void testPathSensitivity(int x) {
28  A a;
29  One b;
30
31  A *ptr;
32  switch (x) {
33  case 0:
34    ptr = &a;
35    break;
36  case 1:
37    ptr = &b;
38    break;
39  default:
40    return;
41  }
42
43  // This should be true on both branches.
44  clang_analyzer_eval(ptr->getNum() == x); // expected-warning {{TRUE}}
45}
46
47
48namespace PureVirtualParent {
49  class Parent {
50  public:
51    virtual int pureVirtual() const = 0;
52    int callVirtual() const {
53      return pureVirtual();
54    }
55  };
56
57  class Child : public Parent {
58  public:
59    virtual int pureVirtual() const {
60      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
61      return 42;
62    }
63  };
64
65  void testVirtual() {
66    Child x;
67
68    clang_analyzer_eval(x.pureVirtual() == 42); // expected-warning{{TRUE}}
69    clang_analyzer_eval(x.callVirtual() == 42); // expected-warning{{TRUE}}
70  }
71}
72
73
74namespace PR13569 {
75  class Parent {
76  protected:
77    int m_parent;
78    virtual int impl() const = 0;
79
80    Parent() : m_parent(0) {}
81
82  public:
83    int interface() const {
84      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
85      return impl();
86    }
87  };
88
89  class Child : public Parent {
90  protected:
91    virtual int impl() const {
92      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
93      return m_parent + m_child;
94    }
95
96  public:
97    Child() : m_child(0) {}
98
99    int m_child;
100  };
101
102  void testVirtual() {
103    Child x;
104    x.m_child = 42;
105
106    // Don't crash when inlining and devirtualizing.
107    x.interface();
108  }
109}
110
111
112