Clang Project

clang_source_code/test/CXX/stmt.stmt/stmt.select/stmt.if/p2.cpp
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.
7namespace 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
28namespace 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
40namespace 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  void h() {
50    if constexpr (4.3) {} // expected-error{{conversion from 'double' to 'bool' is not allowed in a converted constant expression}}
51    constexpr void *p = nullptr;
52    if constexpr (p) {} // expected-error{{conversion from 'void *const' to 'bool' is not allowed in a converted constant expression}}
53  }
54}
55
56namespace generic_lambda {
57  // Substituting for T produces a hard error here, even if substituting for
58  // the type of x would remove the error.
59  template<typename T> void f() {
60    [](auto x) {
61      if constexpr (sizeof(T) == 1 && sizeof(x) == 1)
62        T::error(); // expected-error 2{{'::'}}
63    } (0);
64  }
65
66  template<typename T> void g() {
67    [](auto x) {
68      if constexpr (sizeof(T) == 1)
69        if constexpr (sizeof(x) == 1)
70          T::error(); // expected-error {{'::'}}
71    } (0);
72  }
73
74  void use() {
75    f<int>(); // expected-note {{instantiation of}}
76    f<char>(); // expected-note {{instantiation of}}
77    g<int>(); // ok
78    g<char>(); // expected-note {{instantiation of}}
79  }
80}
81
82namespace potentially_discarded_branch_target {
83  void in_switch(int n) {
84    switch (n)
85      case 4: if constexpr(sizeof(n) == 4) return;
86    if constexpr(sizeof(n) == 4)
87      switch (n) case 4: return;
88    switch (n) {
89      if constexpr (sizeof(n) == 4) // expected-note 2{{constexpr if}}
90        case 4: return; // expected-error {{cannot jump}}
91      else
92        default: break; // expected-error {{cannot jump}}
93    }
94  }
95
96  template<typename T>
97  void in_switch_tmpl(int n) {
98    switch (n) {
99      if constexpr (sizeof(T) == 4) // expected-note 2{{constexpr if}}
100        case 4: return; // expected-error {{cannot jump}}
101      else
102        default: break; // expected-error {{cannot jump}}
103    }
104  }
105
106  void goto_scope(int n) {
107    goto foo; // expected-error {{cannot jump}}
108    if constexpr(sizeof(n) == 4) // expected-note {{constexpr if}}
109      foo: return;
110bar:
111    if constexpr(sizeof(n) == 4)
112      goto bar; // ok
113  }
114
115  template<typename T>
116  void goto_scope(int n) {
117    goto foo; // expected-error {{cannot jump}}
118    if constexpr(sizeof(n) == 4) // expected-note {{constexpr if}}
119      foo: return;
120bar:
121    if constexpr(sizeof(n) == 4)
122      goto bar; // ok
123  }
124
125  void goto_redef(int n) {
126a:  if constexpr(sizeof(n) == 4) // expected-error {{redefinition}} expected-note {{constexpr if}}
127      a: goto a; // expected-note 2{{previous}}
128    else
129      a: goto a; // expected-error {{redefinition}} expected-error {{cannot jump}}
130  }
131
132  void evil_things() {
133    goto evil_label; // expected-error {{cannot jump}}
134    if constexpr (true || ({evil_label: false;})) {} // expected-note {{constexpr if}}
135
136    if constexpr (true) // expected-note {{constexpr if}}
137      goto surprise; // expected-error {{cannot jump}}
138    else
139      surprise: {}
140  }
141}
142#endif
143