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 // PR5620
     21 void f0() __attribute__((__noreturn__));
     22 void f1(void (*)());
     23 void f2() { f1(f0); }
     24 
     25 // Taking the address of a noreturn function
     26 void test_f0a() {
     27   void (*fp)() = f0;
     28   void (*fp1)() __attribute__((noreturn)) = f0;
     29 }
     30 
     31 // Taking the address of an overloaded noreturn function
     32 void f0(int) __attribute__((__noreturn__));
     33 
     34 void test_f0b() {
     35   void (*fp)() = f0;
     36   void (*fp1)() __attribute__((noreturn)) = f0;
     37 }
     38 
     39 // No-returned function pointers
     40 typedef void (* noreturn_fp)() __attribute__((noreturn));
     41 
     42 void f3(noreturn_fp); // expected-note{{candidate function}}
     43 
     44 void test_f3() {
     45   f3(f0); // okay
     46   f3(f2); // expected-error{{no matching function for call}}
     47 }
     48 
     49 
     50 class xpto {
     51   int blah() __attribute__((noreturn));
     52 };
     53 
     54 int xpto::blah() {
     55   return 3; // expected-warning {{function 'blah' declared 'noreturn' should not return}}
     56 }
     57 
     58 // PR12948
     59 
     60 namespace PR12948 {
     61   template<int>
     62   void foo() __attribute__((__noreturn__));
     63 
     64   template<int>
     65   void foo() {
     66     while (1) continue;
     67   }
     68 
     69   void bar() __attribute__((__noreturn__));
     70 
     71   void bar() {
     72     foo<0>();
     73   }
     74 
     75 
     76   void baz() __attribute__((__noreturn__));
     77   typedef void voidfn();
     78   voidfn baz;
     79 
     80   template<typename> void wibble()  __attribute__((__noreturn__));
     81   template<typename> voidfn wibble;
     82 }
     83 
     84 // PR15291
     85 // Overload resolution per over.over should allow implicit noreturn adjustment.
     86 namespace PR15291 {
     87   __attribute__((noreturn)) void foo(int) {}
     88   __attribute__((noreturn)) void foo(double) {}
     89 
     90   template <typename T>
     91   __attribute__((noreturn)) void bar(T) {}
     92 
     93   void baz(int) {}
     94   void baz(double) {}
     95 
     96   template <typename T>
     97   void qux(T) {}
     98 
     99   // 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}}
    100   // 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}}
    101   // 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}}
    102   // expected-note@+2 {{candidate function [with T = void (*)(int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
    103   // expected-note@+1 {{candidate function [with T = void (int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
    104   template <typename T> void accept_T(T) {}
    105 
    106   // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
    107   void accept_fptr(void (*f)(int)) {
    108     f(42);
    109   }
    110 
    111   // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
    112   // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
    113   void accept_noreturn_fptr(void __attribute__((noreturn)) (*f)(int)) {
    114     f(42);
    115   }
    116 
    117   typedef void (*fptr_t)(int);
    118   typedef void __attribute__((noreturn)) (*fptr_noreturn_t)(int);
    119 
    120   // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'fptr_t' (aka 'void (*)(int)') for 1st argument}}
    121   void accept_fptr_t(fptr_t f) {
    122     f(42);
    123   }
    124 
    125   // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
    126   // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
    127   void accept_fptr_noreturn_t(fptr_noreturn_t f) {
    128     f(42);
    129   }
    130 
    131   // Stripping noreturn should work if everything else is correct.
    132   void strip_noreturn() {
    133     accept_fptr(foo);
    134     accept_fptr(bar<int>);
    135     accept_fptr(bar<double>); // expected-error {{no matching function for call to 'accept_fptr'}}
    136 
    137     accept_fptr_t(foo);
    138     accept_fptr_t(bar<int>);
    139     accept_fptr_t(bar<double>); // expected-error {{no matching function for call to 'accept_fptr_t'}}
    140 
    141     accept_T<void __attribute__((noreturn)) (*)(int)>(foo);
    142     accept_T<void __attribute__((noreturn)) (*)(int)>(bar<int>);
    143     accept_T<void __attribute__((noreturn)) (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
    144 
    145     accept_T<void (*)(int)>(foo);
    146     accept_T<void (*)(int)>(bar<int>);
    147     accept_T<void (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
    148 
    149     accept_T<void (int)>(foo);
    150     accept_T<void (int)>(bar<int>);
    151     accept_T<void (int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
    152   }
    153 
    154   // Introducing noreturn should not work.
    155   void introduce_noreturn() {
    156     accept_noreturn_fptr(baz); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}}
    157     accept_noreturn_fptr(qux<int>); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}}
    158 
    159     accept_fptr_noreturn_t(baz); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}}
    160     accept_fptr_noreturn_t(qux<int>); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}}
    161 
    162     accept_T<void __attribute__((noreturn)) (*)(int)>(baz); // expected-error {{no matching function for call to 'accept_T'}}
    163     accept_T<void __attribute__((noreturn)) (*)(int)>(qux<int>); // expected-error {{no matching function for call to 'accept_T'}}
    164   }
    165 }
    166