Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 // RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-undefined-compare %s
      3 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-tautological-compare -Wtautological-undefined-compare %s
      4 // RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-compare %s
      5 
      6 void test1(int &x) {
      7   if (x == 1) { }
      8   if (&x == 0) { }
      9   // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     10   if (&x != 0) { }
     11   // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     12 }
     13 
     14 class test2 {
     15   test2() : x(y) {}
     16 
     17   void foo() {
     18     if (this == 0) { }
     19     // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     20     if (this != 0) { }
     21     // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     22   }
     23 
     24   void bar() {
     25     if (x == 1) { }
     26     if (&x == 0) { }
     27     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     28     if (&x != 0) { }
     29     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     30   }
     31 
     32   int &x;
     33   int y;
     34 };
     35 
     36 namespace function_return_reference {
     37   int& get_int();
     38   // expected-note@-1 4{{'get_int' returns a reference}}
     39   class B {
     40   public:
     41     static int &stat();
     42     // expected-note@-1 4{{'stat' returns a reference}}
     43     int &get();
     44     // expected-note@-1 8{{'get' returns a reference}}
     45   };
     46 
     47   void test() {
     48     if (&get_int() == 0) {}
     49     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     50     if (&(get_int()) == 0) {}
     51     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     52 
     53     if (&get_int() != 0) {}
     54     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     55     if (&(get_int()) != 0) {}
     56     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     57 
     58     if (&B::stat() == 0) {}
     59     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     60     if (&(B::stat()) == 0) {}
     61     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     62 
     63     if (&B::stat() != 0) {}
     64     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     65     if (&(B::stat()) != 0) {}
     66     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     67 
     68     B b;
     69     if (&b.get() == 0) {}
     70     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     71     if (&(b.get()) == 0) {}
     72     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     73 
     74     if (&b.get() != 0) {}
     75     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     76     if (&(b.get()) != 0) {}
     77     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     78 
     79     B* b_ptr = &b;
     80     if (&b_ptr->get() == 0) {}
     81     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     82     if (&(b_ptr->get()) == 0) {}
     83     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     84 
     85     if (&b_ptr->get() != 0) {}
     86     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     87     if (&(b_ptr->get()) != 0) {}
     88     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     89 
     90     int& (B::*m_ptr)() = &B::get;
     91     if (&(b.*m_ptr)() == 0) {}
     92     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     93     if (&((b.*m_ptr)()) == 0) {}
     94     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
     95 
     96     if (&(b.*m_ptr)() != 0) {}
     97     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
     98     if (&((b.*m_ptr)()) != 0) {}
     99     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
    100 
    101     int& (*f_ptr)() = &get_int;
    102     if (&(*f_ptr)() == 0) {}
    103     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
    104     if (&((*f_ptr)()) == 0) {}
    105     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
    106 
    107     if (&(*f_ptr)() != 0) {}
    108     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
    109     if (&((*f_ptr)()) != 0) {}
    110     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
    111   }
    112 }
    113 
    114 namespace macros {
    115   #define assert(x) if (x) {}
    116 
    117   void test(int &x) {
    118     assert(&x != 0);
    119     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
    120     assert(&x == 0);
    121     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
    122     assert(&x != 0 && "Expecting valid reference");
    123     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
    124     assert(&x == 0 && "Expecting invalid reference");
    125     // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
    126   }
    127 
    128   class S {
    129     void test() {
    130       assert(this != 0);
    131       // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to true}}
    132       assert(this == 0);
    133       // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false}}
    134       assert(this != 0 && "Expecting valid reference");
    135       // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to true}}
    136       assert(this == 0 && "Expecting invalid reference");
    137       // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false}}
    138     }
    139   };
    140 }
    141