Skip to content

Commit 017b504

Browse files
authored
[clang] Don't lose track of explicit specializations of member function templates (#111267)
When instantiating a class template, we would lose track of function template explicit specializations, marking them with the wrong specialization kind. This would lead to improperly using the explcit specialization arguments to instantiate the function body. This also better matches MSVC on the behaviour of explicitly vs implicitly instantiating these. Fixes #111266
1 parent e0b840a commit 017b504

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ Bug Fixes to C++ Support
473473
- Fixed an issue deducing non-type template arguments of reference type. (#GH73460)
474474
- Fixed an issue in constraint evaluation, where type constraints on the lambda expression
475475
containing outer unexpanded parameters were not correctly expanded. (#GH101754)
476+
- Fixes crashes with function template member specializations, and increases
477+
conformance of explicit instantiation behaviour with MSVC. (#GH111266)
476478
- Fixed a bug in constraint expression comparison where the ``sizeof...`` expression was not handled properly
477479
in certain friend declarations. (#GH93099)
478480

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4206,18 +4206,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
42064206
if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
42074207
continue;
42084208

4209-
MemberSpecializationInfo *MSInfo =
4210-
Function->getMemberSpecializationInfo();
4211-
assert(MSInfo && "No member specialization information?");
4212-
if (MSInfo->getTemplateSpecializationKind()
4213-
== TSK_ExplicitSpecialization)
4209+
TemplateSpecializationKind PrevTSK =
4210+
Function->getTemplateSpecializationKind();
4211+
if (PrevTSK == TSK_ExplicitSpecialization)
42144212
continue;
42154213

4216-
if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
4217-
Function,
4218-
MSInfo->getTemplateSpecializationKind(),
4219-
MSInfo->getPointOfInstantiation(),
4220-
SuppressNew) ||
4214+
if (CheckSpecializationInstantiationRedecl(
4215+
PointOfInstantiation, TSK, Function, PrevTSK,
4216+
Function->getPointOfInstantiation(), SuppressNew) ||
42214217
SuppressNew)
42224218
continue;
42234219

clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,13 @@ namespace UsesThis {
156156
auto h<int>() -> decltype(this); // expected-error {{'this' cannot be used in a static member function declaration}}
157157
};
158158

159-
template struct A<int>; // expected-note 3{{in instantiation of}}
159+
template struct A<int>; // expected-note {{in instantiation of}}
160+
template<> template<> void A<int>::f<int>();
161+
template<> template<> void A<int>::g<int>();
162+
void test1() {
163+
A<int>().f<int>(); // expected-note {{in instantiation of}}
164+
A<int>().g<int>(); // expected-note {{in instantiation of}}
165+
}
160166

161167
template <typename T>
162168
struct Foo {
@@ -390,7 +396,12 @@ namespace UsesThis {
390396
}
391397
};
392398

393-
template struct D<int>; // expected-note 2{{in instantiation of}}
399+
template struct D<int>;
400+
401+
void test2() {
402+
D<int>().non_static_spec(0); // expected-note {{in instantiation of}}
403+
D<int>().static_spec(0); // expected-note {{in instantiation of}}
404+
}
394405

395406
template<typename T>
396407
struct E : T {
@@ -574,6 +585,23 @@ namespace UsesThis {
574585
}
575586
};
576587

577-
template struct E<B>; // expected-note 2{{in instantiation of}}
588+
template struct E<B>;
578589

590+
void test3() {
591+
E<B>().non_static_spec(0); // expected-note {{in instantiation of}}
592+
E<B>().static_spec(0); // expected-note {{in instantiation of}}
593+
}
579594
}
595+
596+
namespace GH111266 {
597+
template<class T> struct S {
598+
template<int> auto foo();
599+
template<> auto foo<1>() {
600+
return [](auto x) { return x; };
601+
}
602+
};
603+
template struct S<void>;
604+
void test() {
605+
S<void>().foo<1>();
606+
}
607+
} // namespace GH111266

0 commit comments

Comments
 (0)