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