mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 16:06:40 +00:00
113 lines
2.6 KiB
C++
113 lines
2.6 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 %s
|
|
|
|
namespace t1 {
|
|
template<int N> struct A {
|
|
template<class C> friend auto cica(const A<N-1>&, C) {
|
|
return N;
|
|
}
|
|
};
|
|
|
|
template<> struct A<0> {
|
|
template<class C> friend auto cica(const A<0>&, C);
|
|
// expected-note@-1 {{declared here}}
|
|
};
|
|
|
|
void test() {
|
|
cica(A<0>{}, 0);
|
|
// expected-error@-1 {{function 'cica<int>' with deduced return type cannot be used before it is defined}}
|
|
|
|
(void)A<1>{};
|
|
cica(A<0>{}, 0);
|
|
}
|
|
} // namespace t1
|
|
namespace t2 {
|
|
template<int N> struct A {
|
|
template<class C> friend auto cica(const A<N-1>&, C) {
|
|
return N;
|
|
}
|
|
};
|
|
|
|
template<> struct A<0> {
|
|
template<class C> friend auto cica(const A<0>&, C);
|
|
};
|
|
|
|
template <int N, class = decltype(cica(A<N>{}, nullptr))>
|
|
void MakeCica();
|
|
// expected-note@-1 {{candidate function}}
|
|
|
|
template <int N> void MakeCica(A<N+1> = {});
|
|
// expected-note@-1 {{candidate function}}
|
|
|
|
void test() {
|
|
MakeCica<0>();
|
|
|
|
MakeCica<0>();
|
|
// expected-error@-1 {{call to 'MakeCica' is ambiguous}}
|
|
}
|
|
} // namespace t2
|
|
namespace t3 {
|
|
template<int N> struct A {
|
|
template<class C> friend auto cica(const A<N-1>&, C) {
|
|
return N-1;
|
|
}
|
|
};
|
|
|
|
template<> struct A<0> {
|
|
template<class C> friend auto cica(const A<0>&, C);
|
|
};
|
|
|
|
template <int N, class AT, class = decltype(cica(AT{}, nullptr))>
|
|
static constexpr bool MakeCica(int);
|
|
|
|
template <int N, class AT>
|
|
static constexpr bool MakeCica(short, A<N+1> = {});
|
|
|
|
template <int N, class AT = A<N>, class Val = decltype(MakeCica<N, AT>(0))>
|
|
static constexpr bool has_cica = Val{};
|
|
|
|
constexpr bool cica2 = has_cica<0> || has_cica<0>;
|
|
} // namespace t3
|
|
namespace t4 {
|
|
template<int N> struct A {
|
|
template<class C> friend auto cica(const A<N-1>&, C);
|
|
};
|
|
|
|
template<> struct A<0> {
|
|
template<class C> friend auto cica(const A<0>&, C) {
|
|
C a;
|
|
}
|
|
};
|
|
|
|
template struct A<1>;
|
|
|
|
void test() {
|
|
cica(A<0>{}, 0);
|
|
}
|
|
} // namespace t4
|
|
namespace regression1 {
|
|
template <class> class A;
|
|
|
|
template <class T> [[gnu::abi_tag("TAG")]] void foo(A<T>);
|
|
|
|
template <class> struct A {
|
|
friend void foo <>(A);
|
|
};
|
|
|
|
template struct A<int>;
|
|
|
|
template <class T> [[gnu::abi_tag("TAG")]] void foo(A<T>) {}
|
|
|
|
template void foo<int>(A<int>);
|
|
} // namespace regression1
|
|
namespace regression2 {
|
|
template <class> struct A {
|
|
template <class T> static void f() {
|
|
A<int>::f<T>();
|
|
}
|
|
};
|
|
template <> template <class T> void A<int>::f() {
|
|
static_assert(__is_same(T, long));
|
|
}
|
|
template void A<void>::f<long>();
|
|
} // namespace regression2
|