Home | History | Annotate | Download | only in stmt.if
      1 // RUN: %clang_cc1 -std=c++1z -verify %s
      2 // RUN: %clang_cc1 -std=c++1z -verify %s -DUNDEFINED
      3 
      4 #ifdef UNDEFINED
      5 // "used but not defined" errors don't get produced if we have more interesting
      6 // errors.
      7 namespace std_example {
      8   template <typename T, typename... Rest> void g(T &&p, Rest &&... rs) {
      9     // use p
     10     if constexpr(sizeof...(rs) > 0)
     11       g(rs...);
     12   }
     13   void use_g() {
     14     g(1, 2, 3);
     15   }
     16 
     17   static int x(); // no definition of x required
     18   int f() {
     19     if constexpr (true)
     20       return 0;
     21     else if (x())
     22       return x();
     23     else
     24       return -x();
     25   }
     26 }
     27 
     28 namespace odr_use_in_selected_arm {
     29   static int x(); // expected-warning {{is not defined}}
     30   int f() {
     31     if constexpr (false)
     32       return 0;
     33     else if (x()) // expected-note {{here}}
     34       return x();
     35     else
     36       return -x();
     37   }
     38 }
     39 #else
     40 namespace ccce {
     41   void f() {
     42     if (5) {}
     43     if constexpr (5) {} // expected-error {{cannot be narrowed}}
     44   }
     45   template<int N> void g() {
     46     if constexpr (N) {} // expected-error {{cannot be narrowed}}
     47   }
     48   template void g<5>(); // expected-note {{instantiation of}}
     49 }
     50 
     51 namespace generic_lambda {
     52   // Substituting for T produces a hard error here, even if substituting for
     53   // the type of x would remove the error.
     54   template<typename T> void f() {
     55     [](auto x) {
     56       if constexpr (sizeof(T) == 1 && sizeof(x) == 1)
     57         T::error(); // expected-error 2{{'::'}}
     58     } (0);
     59   }
     60 
     61   template<typename T> void g() {
     62     [](auto x) {
     63       if constexpr (sizeof(T) == 1)
     64         if constexpr (sizeof(x) == 1)
     65           T::error(); // expected-error {{'::'}}
     66     } (0);
     67   }
     68 
     69   void use() {
     70     f<int>(); // expected-note {{instantiation of}}
     71     f<char>(); // expected-note {{instantiation of}}
     72     g<int>(); // ok
     73     g<char>(); // expected-note {{instantiation of}}
     74   }
     75 }
     76 
     77 namespace potentially_discarded_branch_target {
     78   void in_switch(int n) {
     79     switch (n)
     80       case 4: if constexpr(sizeof(n) == 4) return;
     81     if constexpr(sizeof(n) == 4)
     82       switch (n) case 4: return;
     83     switch (n) {
     84       if constexpr (sizeof(n) == 4) // expected-note 2{{constexpr if}}
     85         case 4: return; // expected-error {{cannot jump}}
     86       else
     87         default: break; // expected-error {{cannot jump}}
     88     }
     89   }
     90 
     91   template<typename T>
     92   void in_switch_tmpl(int n) {
     93     switch (n) {
     94       if constexpr (sizeof(T) == 4) // expected-note 2{{constexpr if}}
     95         case 4: return; // expected-error {{cannot jump}}
     96       else
     97         default: break; // expected-error {{cannot jump}}
     98     }
     99   }
    100 
    101   void goto_scope(int n) {
    102     goto foo; // expected-error {{cannot jump}}
    103     if constexpr(sizeof(n) == 4) // expected-note {{constexpr if}}
    104       foo: return;
    105 bar:
    106     if constexpr(sizeof(n) == 4)
    107       goto bar; // ok
    108   }
    109 
    110   template<typename T>
    111   void goto_scope(int n) {
    112     goto foo; // expected-error {{cannot jump}}
    113     if constexpr(sizeof(n) == 4) // expected-note {{constexpr if}}
    114       foo: return;
    115 bar:
    116     if constexpr(sizeof(n) == 4)
    117       goto bar; // ok
    118   }
    119 
    120   void goto_redef(int n) {
    121 a:  if constexpr(sizeof(n) == 4) // expected-error {{redefinition}} expected-note {{constexpr if}}
    122       a: goto a; // expected-note 2{{previous}}
    123     else
    124       a: goto a; // expected-error {{redefinition}} expected-error {{cannot jump}}
    125   }
    126 
    127   void evil_things() {
    128     goto evil_label; // expected-error {{cannot jump}}
    129     if constexpr (true || ({evil_label: false;})) {} // expected-note {{constexpr if}}
    130 
    131     if constexpr (true) // expected-note {{constexpr if}}
    132       goto surprise; // expected-error {{cannot jump}}
    133     else
    134       surprise: {}
    135   }
    136 }
    137 #endif
    138