inline.cpp revision 9584f67b6da17283a31dedf0a1cab2d83a3d121c
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
74