blob: 84dfe30646ddd9246db8091224effa51f8d7edb0 [file] [log] [blame]
Anna Zaksbfa9ab82013-01-24 23:15:30 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
Jordan Rose01564392012-08-23 23:01:43 +00002
3void clang_analyzer_eval(bool);
4
5struct A {
6 // This conversion operator allows implicit conversion to bool but not to other integer types.
7 typedef A * (A::*MemberPointer);
8 operator MemberPointer() const { return m_ptr ? &A::m_ptr : 0; }
9
10 A *m_ptr;
11};
12
13void testConditionalUse() {
14 A obj;
15
16 obj.m_ptr = &obj;
17 clang_analyzer_eval(obj.m_ptr); // expected-warning{{TRUE}}
18 clang_analyzer_eval(&A::m_ptr); // expected-warning{{TRUE}}
19 clang_analyzer_eval(obj); // expected-warning{{TRUE}}
20
21 obj.m_ptr = 0;
22 clang_analyzer_eval(obj.m_ptr); // expected-warning{{FALSE}}
23 clang_analyzer_eval(A::MemberPointer(0)); // expected-warning{{FALSE}}
24 clang_analyzer_eval(obj); // expected-warning{{FALSE}}
25}
26
27// ---------------
28// FALSE NEGATIVES
29// ---------------
30
31bool testDereferencing() {
32 A obj;
33 obj.m_ptr = 0;
34
35 A::MemberPointer member = &A::m_ptr;
36
37 // FIXME: Should be TRUE.
38 clang_analyzer_eval(obj.*member == 0); // expected-warning{{UNKNOWN}}
39
40 member = 0;
41
42 // FIXME: Should emit a null dereference.
43 return obj.*member; // no-warning
44}