blob: 37d04399b7b791a6ae9093e071c2b108e09dea5a [file] [log] [blame]
Anna Zaks6bab4ef2013-01-24 23:15:30 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
Jordan Rose434f1322012-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 Rose27ae8a22013-04-15 22:03:38 +000011
12 A *getPtr();
13 typedef A * (A::*MemberFnPointer)(void);
Jordan Rose434f1322012-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 Rose27ae8a22013-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}}
Jordan Rose00deddb2013-07-02 16:50:24 +000036 clang_analyzer_eval(&A::getPtr == 0); // expected-warning{{FALSE}}
Jordan Rose27ae8a22013-04-15 22:03:38 +000037
38 // FIXME: Should be TRUE.
39 clang_analyzer_eval(&A::m_ptr == &A::m_ptr); // expected-warning{{UNKNOWN}}
40}
41
42namespace PR15742 {
43 template <class _T1, class _T2> struct A {
44 A (const _T1 &, const _T2 &);
45 };
46
47 typedef void *NPIdentifier;
48
49 template <class T> class B {
50 public:
51 typedef A<NPIdentifier, bool (T::*) (const NPIdentifier *, unsigned,
52 NPIdentifier *)> MethodMapMember;
53 };
54
55 class C : public B<C> {
56 public:
57 bool Find(const NPIdentifier *, unsigned, NPIdentifier *);
58 };
59
60 void InitStaticData () {
61 C::MethodMapMember(0, &C::Find); // don't crash
62 }
Jordan Rose434f1322012-08-23 23:01:43 +000063}
64
65// ---------------
66// FALSE NEGATIVES
67// ---------------
68
69bool testDereferencing() {
70 A obj;
71 obj.m_ptr = 0;
72
73 A::MemberPointer member = &A::m_ptr;
74
75 // FIXME: Should be TRUE.
76 clang_analyzer_eval(obj.*member == 0); // expected-warning{{UNKNOWN}}
77
78 member = 0;
79
80 // FIXME: Should emit a null dereference.
81 return obj.*member; // no-warning
82}