pointer-to-member.cpp revision 28117be48de465bc2862a8f4aaab09338be5090b
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
2
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  A *getPtr();
13  typedef A * (A::*MemberFnPointer)(void);
14};
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}}
28
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  }
62}
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}
82