260 lines · cpp
1// RUN: %clang_cc1 -std=c++1z -verify %s2// RUN: %clang_cc1 -std=c++1z -verify %s -DUNDEFINED3 4#ifdef UNDEFINED5// "used but not defined" errors don't get produced if we have more interesting6// errors.7namespace std_example {8 template <typename T, typename... Rest> void g(T &&p, Rest &&... rs) {9 // use p10 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 required18 int f() {19 if constexpr (true)20 return 0;21 else if (x())22 return x();23 else24 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 else36 return -x();37 }38}39#else40namespace ccce {41 42 struct S {43 };44 void f() {45 if (5) {}46 if constexpr (5) {47 }48 }49 template<int N> void g() {50 if constexpr (N) {51 }52 }53 template void g<5>();54 void h() {55 if constexpr (4.3) { //expected-warning {{implicit conversion from 'double' to 'bool' changes value}}56 }57 constexpr void *p = nullptr;58 if constexpr (p) {59 }60 }61 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}}64 }65 if constexpr (b) { // expected-error {{constexpr if condition is not a constant expression}} expected-note {{cannot be used in a constant expression}}66 }67 if constexpr (s) { // expected-error {{value of type 'S' is not contextually convertible to 'bool'}}68 }69 70 constexpr S constexprS;71 if constexpr (constexprS) { // expected-error {{value of type 'const S' is not contextually convertible to 'bool'}}72 }73 }74}75 76namespace generic_lambda {77 // Substituting for T produces a hard error here, even if substituting for78 // 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);85 }86 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);94 }95 96 void use() {97 f<int>(); // expected-note {{instantiation of}}98 f<char>(); // expected-note {{instantiation of}}99 g<int>(); // ok100 g<char>(); // expected-note {{instantiation of}}101 }102}103 104namespace 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 else114 default: break; // expected-error {{cannot jump}}115 }116 }117 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 else124 default: break; // expected-error {{cannot jump}}125 }126 }127 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;132bar:133 if constexpr(sizeof(n) == 4)134 goto bar; // ok135 }136 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;142bar:143 if constexpr(sizeof(n) == 4)144 goto bar; // ok145 }146 147 void goto_redef(int n) {148a: if constexpr(sizeof(n) == 4) // expected-error {{redefinition}} expected-note {{constexpr if}}149 a: goto a; // expected-note 2{{previous}}150 else151 a: goto a; // expected-error {{redefinition}} expected-error {{cannot jump}}152 }153 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}}158 159 if constexpr (true) // expected-note {{constexpr if}}160 goto surprise; // expected-error {{cannot jump}}161 else162 surprise: {}163 }164}165 166namespace deduced_return_type_in_discareded_statement {167 168template <typename T>169auto a(const T &t) {170 return t;171}172 173void f() {174 if constexpr (false) {175 a(a(0));176 }177}178} // namespace deduced_return_type_in_discareded_statement179 180namespace GH140449 {181 182template <typename T>183int f() {184 T *ptr;185 return 0;186}187 188template <typename T>189constexpr int g() {190 T *ptr; // expected-error{{'ptr' declared as a pointer to a reference of type 'int &'}}191 return 0;192}193 194template <typename T>195auto h() {196 T *ptr; // expected-error{{'ptr' declared as a pointer to a reference of type 'int &'}}197 return 0;198}199 200void test() {201 if constexpr (false) {202 int x = f<int &>();203 constexpr int y = g<int &>();204 // expected-error@-1 {{constexpr variable 'y' must be initialized by a constant expression}} \205 // expected-note@-1{{in instantiation of function template specialization}}206 int z = h<int &>();207 // expected-note@-1{{in instantiation of function template specialization}}208 209 }210}211 212void regression() {213 if constexpr (false) {214 auto lam = []() { return 0; };215 1 | lam(); // expected-warning {{unused}}216 }217}218 219}220 221namespace GH146063 {222template <typename>223struct A {224 static_assert([]() constexpr { return true; }());225};226 227void f1() {228 if constexpr (false) {229 A<int> a;230 }231}232 233void f2() {234 if constexpr (false) {235 static_assert([]{});236 // expected-warning@-1 {{address of lambda function pointer conversion operator will always evaluate to 'true'}}237 }238}239 240}241 242namespace GH153884 {243 bool f1() {244 auto f = [](auto) { return true; };245 if constexpr (0)246 return f(1);247 return false;248 }249 bool f2() {250 auto f = [](auto x) { if (x) return 1.5; else return "wat"; };251 // expected-error@-1 {{'auto' in return type deduced as 'const char *' here but deduced as 'double' in earlier return statement}}252 if constexpr (0)253 return f(1);254 // expected-note@-1 {{in instantiation of function template specialization 'GH153884::f2()}}255 return false;256 }257}258 259#endif260