1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
3 // expected-no-diagnostics
4 
5 // Test default template arguments for function templates.
6 template<typename T = int>
7 void f0();
8 
9 template<typename T>
10 void f0();
11 
g0()12 void g0() {
13   f0(); // okay!
14 }
15 
16 template<typename T, int N = T::value>
17 int &f1(T);
18 
19 float &f1(...);
20 
21 struct HasValue {
22   static const int value = 17;
23 };
24 
g1()25 void g1() {
26   float &fr = f1(15);
27   int &ir = f1(HasValue());
28 }
29 
30 namespace PR16689 {
31   template <typename T1, typename T2> class tuple {
32   public:
33       template <typename = T2>
tuple()34       constexpr tuple() {}
35   };
36   template <class X, class... Y> struct a : public X {
37     using X::X;
38   };
39   auto x = a<tuple<int, int> >();
40 }
41 
42 namespace PR16975 {
43   template <typename...> struct is {
operator boolPR16975::is44     constexpr operator bool() const { return false; }
45   };
46 
47   template <typename... Types>
48   struct bar {
49     template <typename T,
50               bool = is<Types...>()>
51     bar(T);
52   };
53 
54   bar<> foo{0};
55 
56   struct baz : public bar<> {
57     using bar::bar;
58   };
59 
60   baz data{0};
61 }
62 
63 // rdar://23810407
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.
f(T t)71   template<typename T> int f(T t) {
72     extern T rdar23810407_variable;
73     return 0;
74   }
__anon01b874940102null75   template<typename T> int g(int a = f([] {}));
test()76   void test() {
77     g<int>();
78     g<int>();
79   }
80 }
81 
82 // rdar://problem/24480205
83 namespace PR13986 {
84   constexpr unsigned Dynamic = 0;
85   template <unsigned> class A { template <unsigned = Dynamic> void m_fn1(); };
86   class Test {
~Test()87     ~Test() {}
88     A<1> m_target;
89   };
90 }
91 
92 // rdar://problem/34167492
93 // Template B is instantiated during checking if defaulted A copy constructor
94 // is constexpr. For this we check if S<int> copy constructor is constexpr. And
95 // for this we check S constructor template with default argument that mentions
96 // template B. In  turn, template instantiation triggers checking defaulted
97 // members exception spec. The problem is that it checks defaulted members not
98 // for instantiated class only, but all defaulted members so far. In this case
99 // we try to check exception spec for A default constructor which requires
100 // initializer for the field _a. But initializers are added after constexpr
101 // check so we reject the code because cannot find _a initializer.
102 namespace rdar34167492 {
103   template <typename T> struct B { using type = bool; };
104 
105   template <typename T> struct S {
106     S() noexcept;
107 
108     template <typename U, typename B<U>::type = true>
109     S(const S<U>&) noexcept;
110   };
111 
112   class A {
113     A() noexcept = default;
114     A(const A&) noexcept = default;
115     S<int> _a{};
116   };
117 }
118 
119 #if __cplusplus >= 201402L
120 namespace lambda {
121   // Verify that a default argument in a lambda can refer to the type of a
122   // previous `auto` argument without crashing.
123   template <class T>
bar()124   void bar() {
125     (void) [](auto c, int x = sizeof(decltype(c))) {};
126   }
foo()127   void foo() {
128     bar<int>();
129   }
130 } // namespace lambda
131 #endif
132