Skip to content

Commit 9b808a4

Browse files
committed
[NFC] [Modules] Add a test case for selecting specializations with aliased template args
This a test for #76774. In the review comments, we're concerning about the case that ODRHash may produce the different hash values for semantical same template arguments. For example, if the template argument in a specialization is not qualified and the semantical same template argument in the instantiation point is qualified, we should be able to select that template specialization. And this patch tests this behavior: we should be able to select the correct specialization with semantical same template arguments.
1 parent b3037ae commit 9b808a4

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Testing that the compiler can select the correct template specialization
2+
// from different template aliasing.
3+
//
4+
// RUN: rm -rf %t
5+
// RUN: split-file %s %t
6+
// RUN: cd %t
7+
//
8+
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
9+
// RUN: %clang_cc1 -std=c++20 %t/b.cpp -fprebuilt-module-path=%t \
10+
// RUN: -fsyntax-only -verify
11+
12+
//--- a.cppm
13+
14+
// For template type parameters
15+
export module a;
16+
export template <class C>
17+
struct S {
18+
static constexpr bool selected = false;
19+
};
20+
21+
export struct A {};
22+
23+
export template <>
24+
struct S<A> {
25+
static constexpr bool selected = true;
26+
};
27+
28+
export using B = A;
29+
30+
// For template template parameters
31+
32+
export template <template<typename> typename C>
33+
struct V {
34+
static constexpr bool selected = false;
35+
};
36+
37+
export template <>
38+
struct V<S> {
39+
static constexpr bool selected = true;
40+
};
41+
42+
// For template non type parameters
43+
export template <int X>
44+
struct Numbers {
45+
static constexpr bool selected = false;
46+
static constexpr int value = X;
47+
};
48+
49+
export template<>
50+
struct Numbers<43> {
51+
static constexpr bool selected = true;
52+
static constexpr int value = 43;
53+
};
54+
55+
export template <const int *>
56+
struct Pointers {
57+
static constexpr bool selected = false;
58+
};
59+
60+
export int IntegralValue = 0;
61+
export template<>
62+
struct Pointers<&IntegralValue> {
63+
static constexpr bool selected = true;
64+
};
65+
66+
export template <void *>
67+
struct NullPointers {
68+
static constexpr bool selected = false;
69+
};
70+
71+
export template<>
72+
struct NullPointers<nullptr> {
73+
static constexpr bool selected = true;
74+
};
75+
76+
export template<int (&)[5]>
77+
struct Array {
78+
static constexpr bool selected = false;
79+
};
80+
81+
export int array[5];
82+
export template<>
83+
struct Array<array> {
84+
static constexpr bool selected = true;
85+
};
86+
87+
//--- b.cpp
88+
// expected-no-diagnostics
89+
import a;
90+
91+
// Testing for different qualifiers
92+
static_assert(S<B>::selected);
93+
static_assert(S<::B>::selected);
94+
static_assert(::S<B>::selected);
95+
static_assert(::S<::B>::selected);
96+
typedef A C;
97+
static_assert(S<C>::selected);
98+
static_assert(S<::C>::selected);
99+
static_assert(::S<C>::selected);
100+
static_assert(::S<::C>::selected);
101+
102+
namespace D {
103+
C getAType();
104+
typedef C E;
105+
}
106+
107+
static_assert(S<D::E>::selected);
108+
static_assert(S<decltype(D::getAType())>::selected);
109+
110+
// Testing we can select the correct specialization for different
111+
// template template argument alising.
112+
113+
static_assert(V<S>::selected);
114+
static_assert(V<::S>::selected);
115+
static_assert(::V<S>::selected);
116+
static_assert(::V<::S>::selected);
117+
118+
// Testing for template non type parameters
119+
static_assert(Numbers<43>::selected);
120+
static_assert(Numbers<21 * 2 + 1>::selected);
121+
static_assert(Numbers<42 + 1>::selected);
122+
static_assert(Numbers<44 - 1>::selected);
123+
static_assert(Numbers<Numbers<43>::value>::selected);
124+
static_assert(!Numbers<44>::selected);
125+
126+
static_assert(Pointers<&IntegralValue>::selected);
127+
static_assert(!Pointers<nullptr>::selected);
128+
static_assert(NullPointers<nullptr>::selected);
129+
static_assert(!NullPointers<(void*)&IntegralValue>::selected);
130+
131+
static_assert(Array<array>::selected);
132+
int another_array[5];
133+
static_assert(!Array<another_array>::selected);

0 commit comments

Comments
 (0)