Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CXX / stmt.stmt / stmt.select / stmt.if / p2.cpp
blob55af13bfc0ef3a02fa495f5d90a9720b13e4efc8
1 // RUN: %clang_cc1 -std=c++1z -verify %s
2 // RUN: %clang_cc1 -std=c++1z -verify %s -DUNDEFINED
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...);
13 void use_g() {
14 g(1, 2, 3);
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();
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();
39 #else
40 namespace ccce {
42 struct S {
44 void f() {
45 if (5) {}
46 if constexpr (5) {
49 template<int N> void g() {
50 if constexpr (N) {
53 template void g<5>();
54 void h() {
55 if constexpr (4.3) { //expected-warning {{implicit conversion from 'double' to 'bool' changes value}}
57 constexpr void *p = nullptr;
58 if constexpr (p) {
62 void not_constant(int b, S s) { // expected-note 2{{declared here}}
63 if constexpr (bool(b)) { // expected-error {{constexpr if condition is not a constant expression}} expected-note {{cannot be used in a constant expression}}
65 if constexpr (b) { // expected-error {{constexpr if condition is not a constant expression}} expected-note {{cannot be used in a constant expression}}
67 if constexpr (s) { // expected-error {{value of type 'S' is not contextually convertible to 'bool'}}
70 constexpr S constexprS;
71 if constexpr (constexprS) { // expected-error {{value of type 'const S' is not contextually convertible to 'bool'}}
76 namespace generic_lambda {
77 // Substituting for T produces a hard error here, even if substituting for
78 // the type of x would remove the error.
79 template<typename T> void f() {
80 [](auto x) {
81 if constexpr (sizeof(T) == 1 && sizeof(x) == 1)
82 T::error(); // expected-error 2{{'::'}}
83 // expected-note@-3 2{{while substituting into a lambda expression here}}
84 } (0);
87 template<typename T> void g() {
88 [](auto x) {
89 if constexpr (sizeof(T) == 1)
90 if constexpr (sizeof(x) == 1)
91 T::error(); // expected-error {{'::'}}
92 // expected-note@-4 {{while substituting into a lambda expression here}}
93 } (0);
96 void use() {
97 f<int>(); // expected-note {{instantiation of}}
98 f<char>(); // expected-note {{instantiation of}}
99 g<int>(); // ok
100 g<char>(); // expected-note {{instantiation of}}
104 namespace potentially_discarded_branch_target {
105 void in_switch(int n) {
106 switch (n)
107 case 4: if constexpr(sizeof(n) == 4) return;
108 if constexpr(sizeof(n) == 4)
109 switch (n) case 4: return;
110 switch (n) {
111 if constexpr (sizeof(n) == 4) // expected-note 2{{constexpr if}}
112 case 4: return; // expected-error {{cannot jump}}
113 else
114 default: break; // expected-error {{cannot jump}}
118 template<typename T>
119 void in_switch_tmpl(int n) {
120 switch (n) {
121 if constexpr (sizeof(T) == 4) // expected-note 2{{constexpr if}}
122 case 4: return; // expected-error {{cannot jump}}
123 else
124 default: break; // expected-error {{cannot jump}}
128 void goto_scope(int n) {
129 goto foo; // expected-error {{cannot jump}}
130 if constexpr(sizeof(n) == 4) // expected-note {{constexpr if}}
131 foo: return;
132 bar:
133 if constexpr(sizeof(n) == 4)
134 goto bar; // ok
137 template<typename T>
138 void goto_scope(int n) {
139 goto foo; // expected-error {{cannot jump}}
140 if constexpr(sizeof(n) == 4) // expected-note {{constexpr if}}
141 foo: return;
142 bar:
143 if constexpr(sizeof(n) == 4)
144 goto bar; // ok
147 void goto_redef(int n) {
148 a: if constexpr(sizeof(n) == 4) // expected-error {{redefinition}} expected-note {{constexpr if}}
149 a: goto a; // expected-note 2{{previous}}
150 else
151 a: goto a; // expected-error {{redefinition}} expected-error {{cannot jump}}
154 void evil_things() {
155 goto evil_label; // expected-error {{cannot jump}}
156 if constexpr (true || ({evil_label: false;})) {} // expected-note {{constexpr if}} \
157 // expected-note {{jump enters a statement expression}}
159 if constexpr (true) // expected-note {{constexpr if}}
160 goto surprise; // expected-error {{cannot jump}}
161 else
162 surprise: {}
166 namespace deduced_return_type_in_discareded_statement {
168 template <typename T>
169 auto a(const T &t) {
170 return t;
173 void f() {
174 if constexpr (false) {
175 a(a(0));
178 } // namespace deduced_return_type_in_discareded_statement
180 #endif