blob: 1aa456553599c876577da38b3db900588087f0c1 [file] [log] [blame]
Richard Smith9ca5c422011-10-13 22:29:44 +00001// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
Nicholas Allegracbd13bc2019-09-17 01:43:33 +00002// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
Richard Smithf721e052020-07-09 14:11:21 -07003// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
Andy Gibbsc6e68da2012-10-19 12:44:48 +00004// expected-no-diagnostics
Douglas Gregor5c80a27b2009-11-25 18:55:14 +00005
6// Test default template arguments for function templates.
7template<typename T = int>
8void f0();
9
10template<typename T>
11void f0();
12
13void g0() {
14 f0(); // okay!
15}
16
17template<typename T, int N = T::value>
18int &f1(T);
19
20float &f1(...);
21
22struct HasValue {
23 static const int value = 17;
24};
25
26void g1() {
27 float &fr = f1(15);
28 int &ir = f1(HasValue());
29}
David Majnemer89189202013-08-28 23:48:32 +000030
31namespace PR16689 {
32 template <typename T1, typename T2> class tuple {
33 public:
34 template <typename = T2>
35 constexpr tuple() {}
36 };
37 template <class X, class... Y> struct a : public X {
38 using X::X;
39 };
40 auto x = a<tuple<int, int> >();
41}
42
43namespace PR16975 {
44 template <typename...> struct is {
45 constexpr operator bool() const { return false; }
46 };
47
48 template <typename... Types>
49 struct bar {
50 template <typename T,
51 bool = is<Types...>()>
52 bar(T);
53 };
54
Richard Smithd6a15082017-01-07 00:48:55 +000055 bar<> foo{0};
56
David Majnemer89189202013-08-28 23:48:32 +000057 struct baz : public bar<> {
58 using bar::bar;
59 };
60
61 baz data{0};
62}
John McCall32791cc2016-01-06 22:34:54 +000063
64// rdar://23810407
65// An IRGen failure due to a symbol collision due to a default argument
66// being instantiated twice. Credit goes to Richard Smith for this
67// reduction to a -fsyntax-only failure.
68namespace rdar23810407 {
69 // Instantiating the default argument multiple times will produce two
70 // different lambda types and thus instantiate this function multiple
71 // times, which will produce conflicting extern variable declarations.
72 template<typename T> int f(T t) {
73 extern T rdar23810407_variable;
74 return 0;
75 }
76 template<typename T> int g(int a = f([] {}));
77 void test() {
78 g<int>();
79 g<int>();
80 }
81}
Manman Renc445d382016-02-24 23:05:43 +000082
83// rdar://problem/24480205
84namespace PR13986 {
85 constexpr unsigned Dynamic = 0;
86 template <unsigned> class A { template <unsigned = Dynamic> void m_fn1(); };
87 class Test {
88 ~Test() {}
89 A<1> m_target;
90 };
91}
Volodymyr Sapsai4fbaa622017-09-21 19:54:12 +000092
93// rdar://problem/34167492
94// Template B is instantiated during checking if defaulted A copy constructor
95// is constexpr. For this we check if S<int> copy constructor is constexpr. And
96// for this we check S constructor template with default argument that mentions
97// template B. In turn, template instantiation triggers checking defaulted
98// members exception spec. The problem is that it checks defaulted members not
99// for instantiated class only, but all defaulted members so far. In this case
100// we try to check exception spec for A default constructor which requires
101// initializer for the field _a. But initializers are added after constexpr
102// check so we reject the code because cannot find _a initializer.
103namespace rdar34167492 {
104 template <typename T> struct B { using type = bool; };
105
106 template <typename T> struct S {
107 S() noexcept;
108
109 template <typename U, typename B<U>::type = true>
110 S(const S<U>&) noexcept;
111 };
112
113 class A {
114 A() noexcept = default;
115 A(const A&) noexcept = default;
116 S<int> _a{};
117 };
118}
Nicholas Allegracbd13bc2019-09-17 01:43:33 +0000119
Richard Smitha5569f02020-07-09 14:57:30 -0700120namespace use_of_earlier_param {
121 template<typename T> void f(T a, int = decltype(a)());
122 void g() { f(0); }
123}
124
Nicholas Allegracbd13bc2019-09-17 01:43:33 +0000125#if __cplusplus >= 201402L
126namespace lambda {
127 // Verify that a default argument in a lambda can refer to the type of a
128 // previous `auto` argument without crashing.
129 template <class T>
130 void bar() {
131 (void) [](auto c, int x = sizeof(decltype(c))) {};
132 }
133 void foo() {
134 bar<int>();
135 }
Richard Smithf721e052020-07-09 14:11:21 -0700136
137#if __cplusplus >= 202002L
138 // PR46648: ensure we don't reject this by triggering default argument
139 // instantiation spuriously.
140 auto x = []<typename T>(T x = 123) {};
141 void y() { x(nullptr); }
142
143 template<int A> struct X {
144 template<int B> constexpr int f() {
145 auto l = []<int C>(int n = A + B + C) { return n; };
146 return l.template operator()<3>();
147 }
148 };
149 static_assert(X<100>().f<20>() == 123);
150
151 template<> template<int B> constexpr int X<200>::f() {
152 auto l = []<int C>(int n = 300 + B + C) { return n; };
153 return l.template operator()<1>();
154 }
155 static_assert(X<200>().f<20>() == 321);
156
157 template<> template<> constexpr int X<300>::f<20>() {
158 auto l = []<int C>(int n = 450 + C) { return n; };
159 return l.template operator()<6>();
160 }
161 static_assert(X<300>().f<20>() == 456);
162#endif
Nicholas Allegracbd13bc2019-09-17 01:43:33 +0000163} // namespace lambda
164#endif