blob: c9150e8ca5946a3ab713bd9372285f89d42aba01 [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;
Jordan Rose28117be2013-04-15 22:03:38 +000011
12 A *getPtr();
13 typedef A * (A::*MemberFnPointer)(void);
Jordan Rose01564392012-08-23 23:01:43 +000014};
15
16void testConditionalUse() {
17 A obj;
18
19 obj.m_ptr = &obj;
20 clang_analyzer_eval(obj.m_ptr); // expected-warning{{TRUE}}
21 clang_analyzer_eval(&A::m_ptr); // expected-warning{{TRUE}}
22 clang_analyzer_eval(obj); // expected-warning{{TRUE}}
23
24 obj.m_ptr = 0;
25 clang_analyzer_eval(obj.m_ptr); // expected-warning{{FALSE}}
26 clang_analyzer_eval(A::MemberPointer(0)); // expected-warning{{FALSE}}
27 clang_analyzer_eval(obj); // expected-warning{{FALSE}}
Jordan Rose28117be2013-04-15 22:03:38 +000028
29 clang_analyzer_eval(&A::getPtr); // expected-warning{{TRUE}}
30 clang_analyzer_eval(A::MemberFnPointer(0)); // expected-warning{{FALSE}}
31}
32
33
34void testComparison() {
35 clang_analyzer_eval(&A::getPtr == &A::getPtr); // expected-warning{{TRUE}}
36
37 // FIXME: Should be TRUE.
38 clang_analyzer_eval(&A::m_ptr == &A::m_ptr); // expected-warning{{UNKNOWN}}
39}
40
41namespace PR15742 {
42 template <class _T1, class _T2> struct A {
43 A (const _T1 &, const _T2 &);
44 };
45
46 typedef void *NPIdentifier;
47
48 template <class T> class B {
49 public:
50 typedef A<NPIdentifier, bool (T::*) (const NPIdentifier *, unsigned,
51 NPIdentifier *)> MethodMapMember;
52 };
53
54 class C : public B<C> {
55 public:
56 bool Find(const NPIdentifier *, unsigned, NPIdentifier *);
57 };
58
59 void InitStaticData () {
60 C::MethodMapMember(0, &C::Find); // don't crash
61 }
Jordan Rose01564392012-08-23 23:01:43 +000062}
63
64// ---------------
65// FALSE NEGATIVES
66// ---------------
67
68bool testDereferencing() {
69 A obj;
70 obj.m_ptr = 0;
71
72 A::MemberPointer member = &A::m_ptr;
73
74 // FIXME: Should be TRUE.
75 clang_analyzer_eval(obj.*member == 0); // expected-warning{{UNKNOWN}}
76
77 member = 0;
78
79 // FIXME: Should emit a null dereference.
80 return obj.*member; // no-warning
81}