blob: 24099f79adc5e500d1afab481527dd90f705ef2a [file] [log] [blame]
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001// RUN: %clang_cc1 -fsyntax-only -verify %s
2// RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-bool-conversion %s
3// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion -Wundefined-bool-conversion %s
4// RUN: %clang_cc1 -fsyntax-only -verify -Wbool-conversion %s
5
6void test1(int &x) {
7 if (x == 1) { }
8 if (&x) { }
9 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
10
11 if (!&x) { }
12 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
13}
14
15class test2 {
16 test2() : x(y) {}
17
18 void foo() {
19 if (this) { }
20 // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
21
22 if (!this) { }
23 // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
24 }
25
26 void bar() {
27 if (x == 1) { }
28 if (&x) { }
29 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
30
31 if (!&x) { }
32 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
33 }
34
35 int &x;
36 int y;
37};
38
39namespace function_return_reference {
40 int& get_int();
41 // expected-note@-1 3{{'get_int' returns a reference}}
42 class B {
43 public:
44 static int &stat();
45 // expected-note@-1 3{{'stat' returns a reference}}
46 int &get();
47 // expected-note@-1 6{{'get' returns a reference}}
48 };
49
50 void test() {
51 if (&get_int()) {}
52 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
53 if (&(get_int())) {}
54 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
55 if (!&get_int()) {}
56 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
57
58 if (&B::stat()) {}
59 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
60 if (&(B::stat())) {}
61 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
62 if (!&B::stat()) {}
63 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
64
65 B b;
66 if (&b.get()) {}
67 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
68 if (&(b.get())) {}
69 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
70 if (!&b.get()) {}
71 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
72
73 B* b_ptr = &b;
74 if (&b_ptr->get()) {}
75 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
76 if (&(b_ptr->get())) {}
77 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
78 if (!&b_ptr->get()) {}
79 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
80
81 int& (B::*m_ptr)() = &B::get;
82 if (&(b.*m_ptr)()) {}
83 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
84 if (&((b.*m_ptr)())) {}
85 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
86 if (!&(b.*m_ptr)()) {}
87 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
88
89 int& (*f_ptr)() = &get_int;
90 if (&(*f_ptr)()) {}
91 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
92 if (&((*f_ptr)())) {}
93 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
94 if (!&(*f_ptr)()) {}
95 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
96 }
97}
Stephen Hines176edba2014-12-01 14:53:08 -080098
99namespace macros {
100 #define assert(x) if (x) {}
101 #define zero_on_null(x) ((x) ? *(x) : 0)
102
103 void test(int &x) {
104 // TODO: warn on assert(&x) but not on zero_on_null(&x)
105 zero_on_null(&x);
106 assert(zero_on_null(&x));
107 assert(&x);
108
109 assert(&x && "Expecting valid reference");
110 // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
111 }
112
113 class S {
114 void test() {
115 assert(this);
116
117 assert(this && "Expecting invalid reference");
118 // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
119 }
120 };
121}