1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s 2*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-bool-conversion %s 3*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion -Wundefined-bool-conversion %s 4*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -Wbool-conversion %s 5*67e74705SXin Li test1(int & x)6*67e74705SXin Livoid test1(int &x) { 7*67e74705SXin Li if (x == 1) { } 8*67e74705SXin Li if (&x) { } 9*67e74705SXin Li // 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*67e74705SXin Li 11*67e74705SXin Li if (!&x) { } 12*67e74705SXin Li // 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*67e74705SXin Li } 14*67e74705SXin Li 15*67e74705SXin Li class test2 { test2()16*67e74705SXin Li test2() : x(y) {} 17*67e74705SXin Li foo()18*67e74705SXin Li void foo() { 19*67e74705SXin Li if (this) { } 20*67e74705SXin Li // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}} 21*67e74705SXin Li 22*67e74705SXin Li if (!this) { } 23*67e74705SXin Li // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}} 24*67e74705SXin Li } 25*67e74705SXin Li bar()26*67e74705SXin Li void bar() { 27*67e74705SXin Li if (x == 1) { } 28*67e74705SXin Li if (&x) { } 29*67e74705SXin Li // 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*67e74705SXin Li 31*67e74705SXin Li if (!&x) { } 32*67e74705SXin Li // 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*67e74705SXin Li } 34*67e74705SXin Li 35*67e74705SXin Li int &x; 36*67e74705SXin Li int y; 37*67e74705SXin Li }; 38*67e74705SXin Li 39*67e74705SXin Li namespace function_return_reference { 40*67e74705SXin Li int& get_int(); 41*67e74705SXin Li // expected-note@-1 3{{'get_int' returns a reference}} 42*67e74705SXin Li class B { 43*67e74705SXin Li public: 44*67e74705SXin Li static int &stat(); 45*67e74705SXin Li // expected-note@-1 3{{'stat' returns a reference}} 46*67e74705SXin Li int &get(); 47*67e74705SXin Li // expected-note@-1 6{{'get' returns a reference}} 48*67e74705SXin Li }; 49*67e74705SXin Li test()50*67e74705SXin Li void test() { 51*67e74705SXin Li if (&get_int()) {} 52*67e74705SXin Li // 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*67e74705SXin Li if (&(get_int())) {} 54*67e74705SXin Li // 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*67e74705SXin Li if (!&get_int()) {} 56*67e74705SXin Li // 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*67e74705SXin Li 58*67e74705SXin Li if (&B::stat()) {} 59*67e74705SXin Li // 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*67e74705SXin Li if (&(B::stat())) {} 61*67e74705SXin Li // 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*67e74705SXin Li if (!&B::stat()) {} 63*67e74705SXin Li // 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*67e74705SXin Li 65*67e74705SXin Li B b; 66*67e74705SXin Li if (&b.get()) {} 67*67e74705SXin Li // 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*67e74705SXin Li if (&(b.get())) {} 69*67e74705SXin Li // 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*67e74705SXin Li if (!&b.get()) {} 71*67e74705SXin Li // 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*67e74705SXin Li 73*67e74705SXin Li B* b_ptr = &b; 74*67e74705SXin Li if (&b_ptr->get()) {} 75*67e74705SXin Li // 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*67e74705SXin Li if (&(b_ptr->get())) {} 77*67e74705SXin Li // 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*67e74705SXin Li if (!&b_ptr->get()) {} 79*67e74705SXin Li // 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*67e74705SXin Li 81*67e74705SXin Li int& (B::*m_ptr)() = &B::get; 82*67e74705SXin Li if (&(b.*m_ptr)()) {} 83*67e74705SXin Li // 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*67e74705SXin Li if (&((b.*m_ptr)())) {} 85*67e74705SXin Li // 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*67e74705SXin Li if (!&(b.*m_ptr)()) {} 87*67e74705SXin Li // 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*67e74705SXin Li 89*67e74705SXin Li int& (*f_ptr)() = &get_int; 90*67e74705SXin Li if (&(*f_ptr)()) {} 91*67e74705SXin Li // 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*67e74705SXin Li if (&((*f_ptr)())) {} 93*67e74705SXin Li // 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*67e74705SXin Li if (!&(*f_ptr)()) {} 95*67e74705SXin Li // 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*67e74705SXin Li } 97*67e74705SXin Li } 98*67e74705SXin Li 99*67e74705SXin Li namespace macros { 100*67e74705SXin Li #define assert(x) if (x) {} 101*67e74705SXin Li #define zero_on_null(x) ((x) ? *(x) : 0) 102*67e74705SXin Li test(int & x)103*67e74705SXin Li void test(int &x) { 104*67e74705SXin Li // TODO: warn on assert(&x) but not on zero_on_null(&x) 105*67e74705SXin Li zero_on_null(&x); 106*67e74705SXin Li assert(zero_on_null(&x)); 107*67e74705SXin Li assert(&x); 108*67e74705SXin Li 109*67e74705SXin Li assert(&x && "Expecting valid reference"); 110*67e74705SXin Li // 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*67e74705SXin Li } 112*67e74705SXin Li 113*67e74705SXin Li class S { test()114*67e74705SXin Li void test() { 115*67e74705SXin Li assert(this); 116*67e74705SXin Li 117*67e74705SXin Li assert(this && "Expecting invalid reference"); 118*67e74705SXin Li // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}} 119*67e74705SXin Li } 120*67e74705SXin Li }; 121*67e74705SXin Li } 122