pointer-to-member.cpp revision 0156439a3d718ea0ef5922c38d189a60829c8a86
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -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 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} 45