Home | History | Annotate | Download | only in SemaCXX
      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