1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
3 // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
4 // expected-no-diagnostics
6 // Test default template arguments for function templates.
7 template<typename T
= int>
17 template<typename T
, int N
= T::value
>
23 static const int value
= 17;
28 int &ir
= f1(HasValue());
32 template <typename T1
, typename T2
> class tuple
{
34 template <typename
= T2
>
37 template <class X
, class... Y
> struct a
: public X
{
40 auto x
= a
<tuple
<int, int> >();
44 template <typename
...> struct is
{
45 constexpr operator bool() const { return false; }
48 template <typename
... Types
>
51 bool = is
<Types
...>()>
57 struct baz
: public bar
<> {
64 // An IRGen failure due to a symbol collision due to a default argument
65 // being instantiated twice. Credit goes to Richard Smith for this
66 // reduction to a -fsyntax-only failure.
67 namespace rdar23810407
{
68 // Instantiating the default argument multiple times will produce two
69 // different lambda types and thus instantiate this function multiple
70 // times, which will produce conflicting extern variable declarations.
71 template<typename T
> int f(T t
) {
72 extern T rdar23810407_variable
;
75 template<typename T
> int g(int a
= f([] {}));
83 constexpr unsigned Dynamic
= 0;
84 template <unsigned> class A
{ template <unsigned = Dynamic
> void m_fn1(); };
91 // Template B is instantiated during checking if defaulted A copy constructor
92 // is constexpr. For this we check if S<int> copy constructor is constexpr. And
93 // for this we check S constructor template with default argument that mentions
94 // template B. In turn, template instantiation triggers checking defaulted
95 // members exception spec. The problem is that it checks defaulted members not
96 // for instantiated class only, but all defaulted members so far. In this case
97 // we try to check exception spec for A default constructor which requires
98 // initializer for the field _a. But initializers are added after constexpr
99 // check so we reject the code because cannot find _a initializer.
100 namespace rdar34167492
{
101 template <typename T
> struct B
{ using type
= bool; };
103 template <typename T
> struct S
{
106 template <typename U
, typename B
<U
>::type
= true>
107 S(const S
<U
>&) noexcept
;
111 A() noexcept
= default;
112 A(const A
&) noexcept
= default;
117 namespace use_of_earlier_param
{
118 template<typename T
> void f(T a
, int = decltype(a
)());
122 #if __cplusplus >= 201402L
124 // Verify that a default argument in a lambda can refer to the type of a
125 // previous `auto` argument without crashing.
128 (void) [](auto c
, int x
= sizeof(decltype(c
))) {};
134 #if __cplusplus >= 202002L
135 // PR46648: ensure we don't reject this by triggering default argument
136 // instantiation spuriously.
137 auto x
= []<typename T
>(T x
= 123) {};
138 void y() { x(nullptr); }
140 template<int A
> struct X
{
141 template<int B
> constexpr int f() {
142 auto l
= []<int C
>(int n
= A
+ B
+ C
) { return n
; };
143 return l
.template operator()<3>();
146 static_assert(X
<100>().f
<20>() == 123);
148 template<> template<int B
> constexpr int X
<200>::f() {
149 auto l
= []<int C
>(int n
= 300 + B
+ C
) { return n
; };
150 return l
.template operator()<1>();
152 static_assert(X
<200>().f
<20>() == 321);
154 template<> template<> constexpr int X
<300>::f
<20>() {
155 auto l
= []<int C
>(int n
= 450 + C
) { return n
; };
156 return l
.template operator()<6>();
158 static_assert(X
<300>().f
<20>() == 456);
160 } // namespace lambda