1// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
2
3void clang_analyzer_eval(bool);
4
5class A {
6  int x;
7public:
8  A();
9};
10
11A::A() : x(0) {
12  clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
13}
14
15
16class DirectMember {
17  int x;
18public:
19  DirectMember(int value) : x(value) {}
20
21  int getX() { return x; }
22};
23
24void testDirectMember() {
25  DirectMember obj(3);
26  clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
27}
28
29
30class IndirectMember {
31  struct {
32    int x;
33  };
34public:
35  IndirectMember(int value) : x(value) {}
36
37  int getX() { return x; }
38};
39
40void testIndirectMember() {
41  IndirectMember obj(3);
42  clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
43}
44
45
46struct DelegatingConstructor {
47  int x;
48  DelegatingConstructor(int y) { x = y; }
49  DelegatingConstructor() : DelegatingConstructor(42) {}
50};
51
52void testDelegatingConstructor() {
53  DelegatingConstructor obj;
54  clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}}
55}
56
57
58struct RefWrapper {
59  RefWrapper(int *p) : x(*p) {}
60  RefWrapper(int &r) : x(r) {}
61  int &x;
62};
63
64void testReferenceMember() {
65  int *p = 0;
66  RefWrapper X(p); // expected-warning@-7 {{Dereference of null pointer}}
67}
68
69void testReferenceMember2() {
70  int *p = 0;
71  RefWrapper X(*p); // expected-warning {{Forming reference to null pointer}}
72}
73
74
75extern "C" char *strdup(const char *);
76
77class StringWrapper {
78  char *str;
79public:
80  StringWrapper(const char *input) : str(strdup(input)) {} // no-warning
81};
82
83
84// PR15070 - Constructing a type containing a non-POD array mistakenly
85// tried to perform a bind instead of relying on the CXXConstructExpr,
86// which caused a cast<> failure in RegionStore.
87namespace DefaultConstructorWithCleanups {
88  class Element {
89  public:
90    int value;
91
92    class Helper {
93    public:
94      ~Helper();
95    };
96    Element(Helper h = Helper());
97  };
98  class Wrapper {
99  public:
100    Element arr[2];
101
102    Wrapper();
103  };
104
105  Wrapper::Wrapper() /* initializers synthesized */ {}
106
107  int test() {
108    Wrapper w;
109    return w.arr[0].value; // no-warning
110  }
111}
112
113namespace DefaultMemberInitializers {
114  struct Wrapper {
115    int value = 42;
116
117    Wrapper() {}
118    Wrapper(int x) : value(x) {}
119    Wrapper(bool) {}
120  };
121
122  void test() {
123    Wrapper w1;
124    clang_analyzer_eval(w1.value == 42); // expected-warning{{TRUE}}
125
126    Wrapper w2(50);
127    clang_analyzer_eval(w2.value == 50); // expected-warning{{TRUE}}
128
129    Wrapper w3(false);
130    clang_analyzer_eval(w3.value == 42); // expected-warning{{TRUE}}
131  }
132
133  struct StringWrapper {
134    const char s[4] = "abc";
135    const char *p = "xyz";
136
137    StringWrapper(bool) {}
138  };
139
140  void testString() {
141    StringWrapper w(true);
142    clang_analyzer_eval(w.s[1] == 'b'); // expected-warning{{TRUE}}
143    clang_analyzer_eval(w.p[1] == 'y'); // expected-warning{{TRUE}}
144  }
145}
146