123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
- // RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
- // expected-no-diagnostics
- // Test default template arguments for function templates.
- template<typename T = int>
- void f0();
- template<typename T>
- void f0();
- void g0() {
- f0(); // okay!
- }
- template<typename T, int N = T::value>
- int &f1(T);
- float &f1(...);
- struct HasValue {
- static const int value = 17;
- };
- void g1() {
- float &fr = f1(15);
- int &ir = f1(HasValue());
- }
- namespace PR16689 {
- template <typename T1, typename T2> class tuple {
- public:
- template <typename = T2>
- constexpr tuple() {}
- };
- template <class X, class... Y> struct a : public X {
- using X::X;
- };
- auto x = a<tuple<int, int> >();
- }
- namespace PR16975 {
- template <typename...> struct is {
- constexpr operator bool() const { return false; }
- };
- template <typename... Types>
- struct bar {
- template <typename T,
- bool = is<Types...>()>
- bar(T);
- };
- bar<> foo{0};
- struct baz : public bar<> {
- using bar::bar;
- };
- baz data{0};
- }
- // rdar://23810407
- // An IRGen failure due to a symbol collision due to a default argument
- // being instantiated twice. Credit goes to Richard Smith for this
- // reduction to a -fsyntax-only failure.
- namespace rdar23810407 {
- // Instantiating the default argument multiple times will produce two
- // different lambda types and thus instantiate this function multiple
- // times, which will produce conflicting extern variable declarations.
- template<typename T> int f(T t) {
- extern T rdar23810407_variable;
- return 0;
- }
- template<typename T> int g(int a = f([] {}));
- void test() {
- g<int>();
- g<int>();
- }
- }
- // rdar://problem/24480205
- namespace PR13986 {
- constexpr unsigned Dynamic = 0;
- template <unsigned> class A { template <unsigned = Dynamic> void m_fn1(); };
- class Test {
- ~Test() {}
- A<1> m_target;
- };
- }
- // rdar://problem/34167492
- // Template B is instantiated during checking if defaulted A copy constructor
- // is constexpr. For this we check if S<int> copy constructor is constexpr. And
- // for this we check S constructor template with default argument that mentions
- // template B. In turn, template instantiation triggers checking defaulted
- // members exception spec. The problem is that it checks defaulted members not
- // for instantiated class only, but all defaulted members so far. In this case
- // we try to check exception spec for A default constructor which requires
- // initializer for the field _a. But initializers are added after constexpr
- // check so we reject the code because cannot find _a initializer.
- namespace rdar34167492 {
- template <typename T> struct B { using type = bool; };
- template <typename T> struct S {
- S() noexcept;
- template <typename U, typename B<U>::type = true>
- S(const S<U>&) noexcept;
- };
- class A {
- A() noexcept = default;
- A(const A&) noexcept = default;
- S<int> _a{};
- };
- }
- #if __cplusplus >= 201402L
- namespace lambda {
- // Verify that a default argument in a lambda can refer to the type of a
- // previous `auto` argument without crashing.
- template <class T>
- void bar() {
- (void) [](auto c, int x = sizeof(decltype(c))) {};
- }
- void foo() {
- bar<int>();
- }
- } // namespace lambda
- #endif
|