Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 // Reachability tests have to come first because they get suppressed
      4 // if any errors have occurred.
      5 namespace test5 {
      6   struct A {
      7     __attribute__((noreturn)) void fail();
      8     void nofail();
      9   } a;
     10 
     11   int &test1() {
     12     a.nofail();
     13   } // expected-warning {{control reaches end of non-void function}}
     14 
     15   int &test2() {
     16     a.fail();
     17   }
     18 }
     19 
     20 namespace destructor_tests {
     21   __attribute__((noreturn)) void fail();
     22 
     23   struct A {
     24     ~A() __attribute__((noreturn)) { fail(); }
     25   };
     26   struct B {
     27     B() {}
     28     ~B() __attribute__((noreturn)) { fail(); }
     29   };
     30   struct C : A {};
     31   struct D : B {};
     32   struct E : virtual A {};
     33   struct F : A, virtual B {};
     34   struct G : E {};
     35   struct H : virtual D {};
     36   struct I : A {};
     37   struct J : I {};
     38   struct K : virtual A {};
     39   struct L : K {};
     40   struct M : virtual C {};
     41   struct N : M {};
     42   struct O { N n; };
     43 
     44   __attribute__((noreturn)) void test_1() { A a; }
     45   __attribute__((noreturn)) void test_2() { B b; }
     46   __attribute__((noreturn)) void test_3() { C c; }
     47   __attribute__((noreturn)) void test_4() { D d; }
     48   __attribute__((noreturn)) void test_5() { E e; }
     49   __attribute__((noreturn)) void test_6() { F f; }
     50   __attribute__((noreturn)) void test_7() { G g; }
     51   __attribute__((noreturn)) void test_8() { H h; }
     52   __attribute__((noreturn)) void test_9() { I i; }
     53   __attribute__((noreturn)) void test_10() { J j; }
     54   __attribute__((noreturn)) void test_11() { K k; }
     55   __attribute__((noreturn)) void test_12() { L l; }
     56   __attribute__((noreturn)) void test_13() { M m; }
     57   __attribute__((noreturn)) void test_14() { N n; }
     58   __attribute__((noreturn)) void test_15() { O o; }
     59 
     60   __attribute__((noreturn)) void test_16() { const A& a = A(); }
     61   __attribute__((noreturn)) void test_17() { const B& b = B(); }
     62   __attribute__((noreturn)) void test_18() { const C& c = C(); }
     63   __attribute__((noreturn)) void test_19() { const D& d = D(); }
     64   __attribute__((noreturn)) void test_20() { const E& e = E(); }
     65   __attribute__((noreturn)) void test_21() { const F& f = F(); }
     66   __attribute__((noreturn)) void test_22() { const G& g = G(); }
     67   __attribute__((noreturn)) void test_23() { const H& h = H(); }
     68   __attribute__((noreturn)) void test_24() { const I& i = I(); }
     69   __attribute__((noreturn)) void test_25() { const J& j = J(); }
     70   __attribute__((noreturn)) void test_26() { const K& k = K(); }
     71   __attribute__((noreturn)) void test_27() { const L& l = L(); }
     72   __attribute__((noreturn)) void test_28() { const M& m = M(); }
     73   __attribute__((noreturn)) void test_29() { const N& n = N(); }
     74   __attribute__((noreturn)) void test_30() { const O& o = O(); }
     75 
     76   struct AA {};
     77   struct BB { BB() {} ~BB() {} };
     78   struct CC : AA {};
     79   struct DD : BB {};
     80   struct EE : virtual AA {};
     81   struct FF : AA, virtual BB {};
     82   struct GG : EE {};
     83   struct HH : virtual DD {};
     84   struct II : AA {};
     85   struct JJ : II {};
     86   struct KK : virtual AA {};
     87   struct LL : KK {};
     88   struct MM : virtual CC {};
     89   struct NN : MM {};
     90   struct OO { NN n; };
     91 
     92   __attribute__((noreturn)) void test_31() {
     93     AA a;
     94     BB b;
     95     CC c;
     96     DD d;
     97     EE e;
     98     FF f;
     99     GG g;
    100     HH h;
    101     II i;
    102     JJ j;
    103     KK k;
    104     LL l;
    105     MM m;
    106     NN n;
    107     OO o;
    108 
    109     const AA& aa = AA();
    110     const BB& bb = BB();
    111     const CC& cc = CC();
    112     const DD& dd = DD();
    113     const EE& ee = EE();
    114     const FF& ff = FF();
    115     const GG& gg = GG();
    116     const HH& hh = HH();
    117     const II& ii = II();
    118     const JJ& jj = JJ();
    119     const KK& kk = KK();
    120     const LL& ll = LL();
    121     const MM& mm = MM();
    122     const NN& nn = NN();
    123     const OO& oo = OO();
    124   }  // expected-warning {{function declared 'noreturn' should not return}}
    125 
    126   struct P {
    127     ~P() __attribute__((noreturn)) { fail(); }
    128     void foo() {}
    129   };
    130   struct Q : P { };
    131   __attribute__((noreturn)) void test31() {
    132     P().foo();
    133   }
    134   __attribute__((noreturn)) void test32() {
    135     Q().foo();
    136   }
    137 
    138   struct R {
    139     A a[5];
    140   };
    141   __attribute__((noreturn)) void test33() {
    142     R r;
    143   }
    144 
    145   // FIXME: Code flow analysis does not preserve information about non-null
    146   // pointers, so it can't determine that this function is noreturn.
    147   __attribute__((noreturn)) void test34() {
    148     A *a = new A;
    149     delete a;
    150   }  // expected-warning {{function declared 'noreturn' should not return}}
    151 
    152   struct S {
    153     virtual ~S();
    154   };
    155   struct T : S {
    156     __attribute__((noreturn)) ~T();
    157   };
    158 
    159   // FIXME: Code flow analysis does not preserve information about non-null
    160   // pointers or derived class pointers,  so it can't determine that this
    161   // function is noreturn.
    162   __attribute__((noreturn)) void test35() {
    163     S *s = new T;
    164     delete s;
    165   }  // expected-warning {{function declared 'noreturn' should not return}}
    166 }
    167 
    168 // PR5620
    169 void f0() __attribute__((__noreturn__));
    170 void f1(void (*)());
    171 void f2() { f1(f0); }
    172 
    173 // Taking the address of a noreturn function
    174 void test_f0a() {
    175   void (*fp)() = f0;
    176   void (*fp1)() __attribute__((noreturn)) = f0;
    177 }
    178 
    179 // Taking the address of an overloaded noreturn function
    180 void f0(int) __attribute__((__noreturn__));
    181 
    182 void test_f0b() {
    183   void (*fp)() = f0;
    184   void (*fp1)() __attribute__((noreturn)) = f0;
    185 }
    186 
    187 // No-returned function pointers
    188 typedef void (* noreturn_fp)() __attribute__((noreturn));
    189 
    190 void f3(noreturn_fp); // expected-note{{candidate function}}
    191 
    192 void test_f3() {
    193   f3(f0); // okay
    194   f3(f2); // expected-error{{no matching function for call}}
    195 }
    196 
    197 
    198 class xpto {
    199   int blah() __attribute__((noreturn));
    200 };
    201 
    202 int xpto::blah() {
    203   return 3; // expected-warning {{function 'blah' declared 'noreturn' should not return}}
    204 }
    205 
    206 // PR12948
    207 
    208 namespace PR12948 {
    209   template<int>
    210   void foo() __attribute__((__noreturn__));
    211 
    212   template<int>
    213   void foo() {
    214     while (1) continue;
    215   }
    216 
    217   void bar() __attribute__((__noreturn__));
    218 
    219   void bar() {
    220     foo<0>();
    221   }
    222 
    223 
    224   void baz() __attribute__((__noreturn__));
    225   typedef void voidfn();
    226   voidfn baz;
    227 
    228   template<typename> void wibble()  __attribute__((__noreturn__));
    229   template<typename> voidfn wibble;
    230 }
    231 
    232 // PR15291
    233 // Overload resolution per over.over should allow implicit noreturn adjustment.
    234 namespace PR15291 {
    235   __attribute__((noreturn)) void foo(int) {}
    236   __attribute__((noreturn)) void foo(double) {}
    237 
    238   template <typename T>
    239   __attribute__((noreturn)) void bar(T) {}
    240 
    241   void baz(int) {}
    242   void baz(double) {}
    243 
    244   template <typename T>
    245   void qux(T) {}
    246 
    247   // expected-note@+5 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
    248   // expected-note@+4 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
    249   // expected-note@+3 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
    250   // expected-note@+2 {{candidate function [with T = void (*)(int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
    251   // expected-note@+1 {{candidate function [with T = void (int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
    252   template <typename T> void accept_T(T) {}
    253 
    254   // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
    255   void accept_fptr(void (*f)(int)) {
    256     f(42);
    257   }
    258 
    259   // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
    260   // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
    261   void accept_noreturn_fptr(void __attribute__((noreturn)) (*f)(int)) {
    262     f(42);
    263   }
    264 
    265   typedef void (*fptr_t)(int);
    266   typedef void __attribute__((noreturn)) (*fptr_noreturn_t)(int);
    267 
    268   // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'fptr_t' (aka 'void (*)(int)') for 1st argument}}
    269   void accept_fptr_t(fptr_t f) {
    270     f(42);
    271   }
    272 
    273   // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
    274   // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
    275   void accept_fptr_noreturn_t(fptr_noreturn_t f) {
    276     f(42);
    277   }
    278 
    279   // Stripping noreturn should work if everything else is correct.
    280   void strip_noreturn() {
    281     accept_fptr(foo);
    282     accept_fptr(bar<int>);
    283     accept_fptr(bar<double>); // expected-error {{no matching function for call to 'accept_fptr'}}
    284 
    285     accept_fptr_t(foo);
    286     accept_fptr_t(bar<int>);
    287     accept_fptr_t(bar<double>); // expected-error {{no matching function for call to 'accept_fptr_t'}}
    288 
    289     accept_T<void __attribute__((noreturn)) (*)(int)>(foo);
    290     accept_T<void __attribute__((noreturn)) (*)(int)>(bar<int>);
    291     accept_T<void __attribute__((noreturn)) (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
    292 
    293     accept_T<void (*)(int)>(foo);
    294     accept_T<void (*)(int)>(bar<int>);
    295     accept_T<void (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
    296 
    297     accept_T<void (int)>(foo);
    298     accept_T<void (int)>(bar<int>);
    299     accept_T<void (int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
    300   }
    301 
    302   // Introducing noreturn should not work.
    303   void introduce_noreturn() {
    304     accept_noreturn_fptr(baz); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}}
    305     accept_noreturn_fptr(qux<int>); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}}
    306 
    307     accept_fptr_noreturn_t(baz); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}}
    308     accept_fptr_noreturn_t(qux<int>); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}}
    309 
    310     accept_T<void __attribute__((noreturn)) (*)(int)>(baz); // expected-error {{no matching function for call to 'accept_T'}}
    311     accept_T<void __attribute__((noreturn)) (*)(int)>(qux<int>); // expected-error {{no matching function for call to 'accept_T'}}
    312   }
    313 }
    314