[AMDGPU][AsmParser][NFC] Get rid of custom default operand handlers.
[llvm-project.git] / clang / test / CXX / temp / temp.deduct / p9.cpp
blob23bcd2a1892e7a6ae2baa9477c94264a5ef2c512
1 // RUN: %clang_cc1 -std=c++20 -verify %s
2 // [temp.deduct.p9]
3 // A lambda-expression appearing in a function type or a template parameter is
4 // not considered part of the immediate context for the purposes of template
5 // argument deduction.
6 // [Note: The intent is to avoid requiring implementations to deal with
7 // substitution failure involving arbitrary statements.]
8 template <class T>
9 auto f(T) -> decltype([]() { T::invalid; } ());
10 void f(...);
11 void test_f() {
12 f(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
13 // expected-note@-1 {{while substituting deduced template arguments}}
14 // expected-note@-5 {{while substituting into a lambda expression here}}
17 template <class T, unsigned = sizeof([]() { T::invalid; })>
18 void g(T);
19 void g(...);
20 void test_g() {
21 g(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}}
22 // expected-note@-4 {{in instantiation of default argument}}
23 // expected-note@-2 {{while substituting deduced template arguments}}
24 // expected-note@-7 {{while substituting into a lambda expression here}}
27 template <class T>
28 auto h(T) -> decltype([x = T::invalid]() { });
29 void h(...);
30 void test_h() {
31 h(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
32 // expected-note@-1 {{while substituting deduced template arguments}}
33 // expected-note@-5 {{while substituting into a lambda expression here}}
36 template <class T>
37 auto i(T) -> decltype([]() -> typename T::invalid { });
38 void i(...);
39 void test_i() {
40 i(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
41 // expected-note@-1 {{while substituting deduced template arguments}}
42 // expected-note@-5 {{while substituting into a lambda expression here}}
46 // In this example, the lambda itself is not part of an immediate context, but
47 // substitution to the lambda expression succeeds, producing dependent
48 // `decltype(x.invalid)`. The call to the lambda, however, is in the immediate context
49 // and it produces a SFINAE failure. Hence, we pick the second overload
50 // and don't produce any errors.
51 template <class T>
52 auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // #1
53 void j(...); // #2
54 void test_j() {
55 j(0); // deduction fails on #1, calls #2.