1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s 2*f4a2713aSLionel Sambuc 3*f4a2713aSLionel Sambuc void clang_analyzer_eval(bool); 4*f4a2713aSLionel Sambuc 5*f4a2713aSLionel Sambuc struct A { 6*f4a2713aSLionel Sambuc // This conversion operator allows implicit conversion to bool but not to other integer types. 7*f4a2713aSLionel Sambuc typedef A * (A::*MemberPointer); operator MemberPointerA8*f4a2713aSLionel Sambuc operator MemberPointer() const { return m_ptr ? &A::m_ptr : 0; } 9*f4a2713aSLionel Sambuc 10*f4a2713aSLionel Sambuc A *m_ptr; 11*f4a2713aSLionel Sambuc 12*f4a2713aSLionel Sambuc A *getPtr(); 13*f4a2713aSLionel Sambuc typedef A * (A::*MemberFnPointer)(void); 14*f4a2713aSLionel Sambuc }; 15*f4a2713aSLionel Sambuc testConditionalUse()16*f4a2713aSLionel Sambucvoid testConditionalUse() { 17*f4a2713aSLionel Sambuc A obj; 18*f4a2713aSLionel Sambuc 19*f4a2713aSLionel Sambuc obj.m_ptr = &obj; 20*f4a2713aSLionel Sambuc clang_analyzer_eval(obj.m_ptr); // expected-warning{{TRUE}} 21*f4a2713aSLionel Sambuc clang_analyzer_eval(&A::m_ptr); // expected-warning{{TRUE}} 22*f4a2713aSLionel Sambuc clang_analyzer_eval(obj); // expected-warning{{TRUE}} 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel Sambuc obj.m_ptr = 0; 25*f4a2713aSLionel Sambuc clang_analyzer_eval(obj.m_ptr); // expected-warning{{FALSE}} 26*f4a2713aSLionel Sambuc clang_analyzer_eval(A::MemberPointer(0)); // expected-warning{{FALSE}} 27*f4a2713aSLionel Sambuc clang_analyzer_eval(obj); // expected-warning{{FALSE}} 28*f4a2713aSLionel Sambuc 29*f4a2713aSLionel Sambuc clang_analyzer_eval(&A::getPtr); // expected-warning{{TRUE}} 30*f4a2713aSLionel Sambuc clang_analyzer_eval(A::MemberFnPointer(0)); // expected-warning{{FALSE}} 31*f4a2713aSLionel Sambuc } 32*f4a2713aSLionel Sambuc 33*f4a2713aSLionel Sambuc testComparison()34*f4a2713aSLionel Sambucvoid testComparison() { 35*f4a2713aSLionel Sambuc clang_analyzer_eval(&A::getPtr == &A::getPtr); // expected-warning{{TRUE}} 36*f4a2713aSLionel Sambuc clang_analyzer_eval(&A::getPtr == 0); // expected-warning{{FALSE}} 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel Sambuc // FIXME: Should be TRUE. 39*f4a2713aSLionel Sambuc clang_analyzer_eval(&A::m_ptr == &A::m_ptr); // expected-warning{{UNKNOWN}} 40*f4a2713aSLionel Sambuc } 41*f4a2713aSLionel Sambuc 42*f4a2713aSLionel Sambuc namespace PR15742 { 43*f4a2713aSLionel Sambuc template <class _T1, class _T2> struct A { 44*f4a2713aSLionel Sambuc A (const _T1 &, const _T2 &); 45*f4a2713aSLionel Sambuc }; 46*f4a2713aSLionel Sambuc 47*f4a2713aSLionel Sambuc typedef void *NPIdentifier; 48*f4a2713aSLionel Sambuc 49*f4a2713aSLionel Sambuc template <class T> class B { 50*f4a2713aSLionel Sambuc public: 51*f4a2713aSLionel Sambuc typedef A<NPIdentifier, bool (T::*) (const NPIdentifier *, unsigned, 52*f4a2713aSLionel Sambuc NPIdentifier *)> MethodMapMember; 53*f4a2713aSLionel Sambuc }; 54*f4a2713aSLionel Sambuc 55*f4a2713aSLionel Sambuc class C : public B<C> { 56*f4a2713aSLionel Sambuc public: 57*f4a2713aSLionel Sambuc bool Find(const NPIdentifier *, unsigned, NPIdentifier *); 58*f4a2713aSLionel Sambuc }; 59*f4a2713aSLionel Sambuc InitStaticData()60*f4a2713aSLionel Sambuc void InitStaticData () { 61*f4a2713aSLionel Sambuc C::MethodMapMember(0, &C::Find); // don't crash 62*f4a2713aSLionel Sambuc } 63*f4a2713aSLionel Sambuc } 64*f4a2713aSLionel Sambuc 65*f4a2713aSLionel Sambuc // --------------- 66*f4a2713aSLionel Sambuc // FALSE NEGATIVES 67*f4a2713aSLionel Sambuc // --------------- 68*f4a2713aSLionel Sambuc testDereferencing()69*f4a2713aSLionel Sambucbool testDereferencing() { 70*f4a2713aSLionel Sambuc A obj; 71*f4a2713aSLionel Sambuc obj.m_ptr = 0; 72*f4a2713aSLionel Sambuc 73*f4a2713aSLionel Sambuc A::MemberPointer member = &A::m_ptr; 74*f4a2713aSLionel Sambuc 75*f4a2713aSLionel Sambuc // FIXME: Should be TRUE. 76*f4a2713aSLionel Sambuc clang_analyzer_eval(obj.*member == 0); // expected-warning{{UNKNOWN}} 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc member = 0; 79*f4a2713aSLionel Sambuc 80*f4a2713aSLionel Sambuc // FIXME: Should emit a null dereference. 81*f4a2713aSLionel Sambuc return obj.*member; // no-warning 82*f4a2713aSLionel Sambuc } 83