blob: 508a3a5da76a915ff6f0726b51eb8cbf5fdf4783 [file] [log] [blame]
// RUN: %clang_cc1 -fsyntax-only -Wno-c++11-narrowing -Wno-literal-conversion -std=c++20 -verify %s
namespace test1 {
template <typename T>
struct Foo { T t; };
template <typename U>
using Bar = Foo<U>;
Bar s = {1};
} // namespace test1
namespace test2 {
template <typename X, typename Y>
struct XYpair {
X x;
Y y;
};
// A tricky explicit deduction guide that swapping X and Y.
template <typename X, typename Y>
XYpair(X, Y) -> XYpair<Y, X>;
template <typename U, typename V>
using AliasXYpair = XYpair<U, V>;
AliasXYpair xy = {1.1, 2}; // XYpair<int, double>
static_assert(__is_same(decltype(xy.x), int));
static_assert(__is_same(decltype(xy.y), double));
} // namespace test2
namespace test3 {
template <typename T, class>
struct container {
// test with default arguments.
container(T a, T b = T());
};
template <class T>
using vector = container<T, int>;
vector v(0, 0);
} // namespace test3
namespace test4 {
// Explicit deduction guide.
template <class T>
struct X {
T t;
X(T);
};
template <class T>
X(T) -> X<double>;
template <class T>
using AX = X<T>;
AX s = {1};
static_assert(__is_same(decltype(s.t), double)); // explicit one is picked.
} // namespace test4
namespace test5 {
template <int B>
struct Foo {};
// Template parameter pack
template <int... C>
using AF = Foo<1>;
auto a = AF{};
} // namespace test5
namespace test6 {
// non-type template argument.
template <typename T, bool B = false>
struct Foo {
Foo(T);
};
template <typename T>
using AF = Foo<T, 1>;
AF b{0};
} // namespace test6
namespace test7 {
template <typename T>
struct Foo {
Foo(T);
};
// using alias chain.
template <typename U>
using AF1 = Foo<U>;
template <typename K>
using AF2 = AF1<K>;
AF2 b = 1;
} // namespace test7
namespace test8 {
template <typename T, int N>
struct Foo {
Foo(T const (&)[N]);
};
template <typename X, int Y>
using Bar = Foo<X, Y>;
Bar s = {{1}};
} // namespace test8
namespace test9 {
template <typename T, int N>
struct Foo {
Foo(T const (&)[N]);
};
template <typename X, int Y>
using Bar = Foo<X, sizeof(X)>;
// FIXME: we should reject this case? GCC rejects it, MSVC accepts it.
Bar s = {{1}};
} // namespace test9
namespace test10 {
template <typename T>
struct Foo {
template <typename U>
Foo(U);
};
template <typename U>
Foo(U) -> Foo<U*>;
template <typename K>
using A = Foo<K>;
A a(2); // Foo<int*>
} // namespace test10
namespace test11 {
struct A {};
template<class T> struct Foo { T c; };
template<class X, class Y=A> using AFoo = Foo<Y>;
AFoo s = {1};
} // namespace test11
namespace test12 {
// no crash on null access attribute
template<typename X>
struct Foo {
template<typename K>
struct Bar {
Bar(K);
};
template<typename U>
using ABar = Bar<U>;
void test() { ABar k = 2; }
};
void func(Foo<int> s) {
s.test();
}
} // namespace test12
namespace test13 {
template <typename... Ts>
struct Foo {
Foo(Ts...);
};
template <typename... Ts>
using AFoo = Foo<Ts...>;
auto b = AFoo{};
} // namespace test13
namespace test14 {
template<typename T>
concept IsInt = __is_same(decltype(T()), int);
template<IsInt T, int N>
struct Foo {
Foo(T const (&)[N]);
};
template <int K>
using Bar = Foo<double, K>; // expected-note {{constraints not satisfied for class template 'Foo'}}
// expected-note@-1 {{candidate template ignored: could not match}}
double abc[3];
Bar s2 = {abc}; // expected-error {{no viable constructor or deduction guide for deduction }}
} // namespace test14
namespace test15 {
template <class T> struct Foo { Foo(T); };
template<class V> using AFoo = Foo<V *>;
template<typename> concept False = false;
template<False W> using BFoo = AFoo<W>;
int i = 0;
AFoo a1(&i); // OK, deduce Foo<int *>
// FIXME: we should reject this case as the W is not deduced from the deduced
// type Foo<int *>.
BFoo b2(&i);
} // namespace test15
namespace test16 {
struct X { X(int); X(const X&); };
template<class T>
struct Foo {
T t;
Foo(T t) : t(t) {}
};
template<class T>
using AFoo = Foo<T>;
int i = 0;
AFoo s{i};
static_assert(__is_same(decltype(s.t), int));
// explicit deduction guide.
Foo(int) -> Foo<X>;
AFoo s2{i};
// FIXME: the type should be X because of the above explicit deduction guide.
static_assert(__is_same(decltype(s2.t), int));
} // namespace test16
namespace test17 {
template <typename T>
struct Foo { T t; };
// CTAD for alias templates only works for the RHS of the alias of form of
// [typename] [nested-name-specifier] [template] simple-template-id
template <typename U>
using AFoo = Foo<U>*; // expected-note {{template is declared here}}
AFoo s = {1}; // expected-error {{alias template 'AFoo' requires template arguments; argument deduction only allowed for}}
} // namespace test17
namespace test18 {
template<typename T>
concept False = false; // expected-note {{because 'false' evaluated to false}}
template <typename T> struct Foo { T t; };
template<typename T> requires False<T> // expected-note {{because 'int' does not satisfy 'False'}}
Foo(T) -> Foo<int>;
template <typename U>
using Bar = Foo<U>; // expected-note {{could not match 'Foo<type-parameter-0-0>' against 'int'}} \
// expected-note {{candidate template ignored: constraints not satisfied}} \
// expected-note {{candidate function template not viable}}
Bar s = {1}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
} // namespace test18
// GH85406, verify no crash on invalid alias templates.
namespace test19 {
template <typename T>
class Foo {};
template <typename T>
template <typename K>
using Bar2 = Foo<K>; // expected-error {{extraneous template parameter list in alias template declaration}}
Bar2 b = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
} // namespace test19
// GH85385
namespace test20 {
template <template <typename> typename T>
struct K {};
template <typename U>
class Foo {};
// Verify that template template type parameter TTP is referenced/used in the
// template arguments of the RHS.
template <template<typename> typename TTP>
using Bar = Foo<K<TTP>>; // expected-note {{candidate template ignored: could not match 'Foo<K<>>' against 'int'}}
template <class T>
class Container {};
Bar t = Foo<K<Container>>();
Bar s = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of}}
} // namespace test20
namespace test21 {
template <typename T, unsigned N>
struct Array { const T member[N]; };
template <unsigned N>
using String = Array<char, N>;
// Verify no crash on constructing the aggregate deduction guides.
String s("hello");
} // namespace test21
// GH89013
namespace test22 {
class Base {};
template <typename T>
class Derived final : public Base {};
template <typename T, typename D>
requires __is_base_of(Base, D)
struct Foo {
explicit Foo(D) {}
};
template <typename U>
using AFoo = Foo<int, Derived<U>>;
AFoo a(Derived<int>{});
} // namespace test22