1 // 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 
test1(int & x)6 void 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 
15 class test2 {
test2()16   test2() : x(y) {}
17 
foo()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 
bar()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 
39 namespace 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 
test()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 }
98 
99 namespace macros {
100   #define assert(x) if (x) {}
101   #define zero_on_null(x) ((x) ? *(x) : 0)
102 
test(int & x)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 {
test()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 }
122