[clang] 017b504 - [clang] Don't lose track of explicit specializations of member function templates (#111267)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 7 12:46:32 PDT 2024


Author: Matheus Izvekov
Date: 2024-10-07T16:46:27-03:00
New Revision: 017b504b462ce7d4938f704a1f10118ead347d3d

URL: https://github.com/llvm/llvm-project/commit/017b504b462ce7d4938f704a1f10118ead347d3d
DIFF: https://github.com/llvm/llvm-project/commit/017b504b462ce7d4938f704a1f10118ead347d3d.diff

LOG: [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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaTemplateInstantiate.cpp
    clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9762db9209b79a..6c0245ce660251 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -473,6 +473,8 @@ Bug Fixes to C++ Support
 - Fixed an issue deducing non-type template arguments of reference type. (#GH73460)
 - Fixed an issue in constraint evaluation, where type constraints on the lambda expression
   containing outer unexpanded parameters were not correctly expanded. (#GH101754)
+- Fixes crashes with function template member specializations, and increases
+  conformance of explicit instantiation behaviour with MSVC. (#GH111266)
 - Fixed a bug in constraint expression comparison where the ``sizeof...`` expression was not handled properly
   in certain friend declarations. (#GH93099)
 

diff  --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 898255ff7c6a32..4ce47d8c1ee761 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -4206,18 +4206,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
         if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
           continue;
 
-        MemberSpecializationInfo *MSInfo =
-            Function->getMemberSpecializationInfo();
-        assert(MSInfo && "No member specialization information?");
-        if (MSInfo->getTemplateSpecializationKind()
-                                                 == TSK_ExplicitSpecialization)
+        TemplateSpecializationKind PrevTSK =
+            Function->getTemplateSpecializationKind();
+        if (PrevTSK == TSK_ExplicitSpecialization)
           continue;
 
-        if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
-                                                   Function,
-                                        MSInfo->getTemplateSpecializationKind(),
-                                              MSInfo->getPointOfInstantiation(),
-                                                   SuppressNew) ||
+        if (CheckSpecializationInstantiationRedecl(
+                PointOfInstantiation, TSK, Function, PrevTSK,
+                Function->getPointOfInstantiation(), SuppressNew) ||
             SuppressNew)
           continue;
 

diff  --git a/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp b/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp
index e1f3ab37ad947c..aacc092c2c66ca 100644
--- a/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp
+++ b/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp
@@ -156,7 +156,13 @@ namespace UsesThis {
     auto h<int>() -> decltype(this); // expected-error {{'this' cannot be used in a static member function declaration}}
   };
 
-  template struct A<int>; // expected-note 3{{in instantiation of}}
+  template struct A<int>; // expected-note {{in instantiation of}}
+  template<> template<> void A<int>::f<int>();
+  template<> template<> void A<int>::g<int>();
+  void test1() {
+    A<int>().f<int>(); // expected-note {{in instantiation of}}
+    A<int>().g<int>(); // expected-note {{in instantiation of}}
+  }
 
   template <typename T>
   struct Foo {
@@ -390,7 +396,12 @@ namespace UsesThis {
     }
   };
 
-  template struct D<int>; // expected-note 2{{in instantiation of}}
+  template struct D<int>;
+
+  void test2() {
+    D<int>().non_static_spec(0); // expected-note {{in instantiation of}}
+    D<int>().static_spec(0); // expected-note {{in instantiation of}}
+  }
 
   template<typename T>
   struct E : T {
@@ -574,6 +585,23 @@ namespace UsesThis {
     }
   };
 
-  template struct E<B>; // expected-note 2{{in instantiation of}}
+  template struct E<B>;
 
+  void test3() {
+    E<B>().non_static_spec(0); // expected-note {{in instantiation of}}
+    E<B>().static_spec(0); // expected-note {{in instantiation of}}
+  }
 }
+
+namespace GH111266 {
+  template<class T> struct S {
+    template<int> auto foo();
+    template<> auto foo<1>() {
+      return [](auto x) { return x; };
+    }
+  };
+  template struct S<void>;
+  void test() {
+    S<void>().foo<1>();
+  }
+} // namespace GH111266


        


More information about the cfe-commits mailing list