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 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 { 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 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 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 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 } 122