llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)

<details>
<summary>Changes</summary>

Stop treating the member which a member specialization specializes as the 
pattern of the former.

Split off from https://github.com/llvm/llvm-project/pull/199528

---
Full diff: https://github.com/llvm/llvm-project/pull/199979.diff


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/AST/DeclCXX.cpp (+9-6) 
- (modified) clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp (-6) 
- (modified) clang/test/Modules/cxx-templates.cpp (+1-2) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fb70b83d6a7c4..73cc466355d36 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -651,6 +651,7 @@ Bug Fixes to C++ Support
 - Fixed a crash when diagnosing an invalid static member function with an 
explicit object parameter (#GH177741)
 - Clang incorrectly instantiated variable specializations outside of the 
immediate context. (#GH54439)
 - Fixed a crash when pack expansions are used as arguments for non-pack 
parameters of built-in templates. (#GH180307)
+- Fixed crash instantiating class member specializations.
 - Fix a problem where a substitution failure when evaluating a type requirement
   could directly make the program ill-formed.
 - Fix a problem where pack index expressions where incorrectly being regarded 
as equivalent.
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 2a58313b699e2..2de8ba8f484f4 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -2088,20 +2088,23 @@ const CXXRecordDecl 
*CXXRecordDecl::getTemplateInstantiationPattern() const {
   if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
     auto From = TD->getInstantiatedFrom();
     if (auto *CTD = dyn_cast_if_present<ClassTemplateDecl *>(From)) {
-      while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
-        if (NewCTD->isMemberSpecialization())
+      while (!CTD->isMemberSpecialization()) {
+        ClassTemplateDecl *D = CTD->getInstantiatedFromMemberTemplate();
+        if (!D)
           break;
-        CTD = NewCTD;
+        CTD = D;
       }
       return CTD->getTemplatedDecl();
     }
     if (auto *CTPSD =
             dyn_cast_if_present<ClassTemplatePartialSpecializationDecl *>(
                 From)) {
-      while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) {
-        if (NewCTPSD->isMemberSpecialization())
+      while (!CTPSD->isMemberSpecialization()) {
+        ClassTemplatePartialSpecializationDecl *D =
+            CTPSD->getInstantiatedFromMember();
+        if (!D)
           break;
-        CTPSD = NewCTPSD;
+        CTPSD = D;
       }
       return CTPSD;
     }
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp 
b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp
index b93562a60de57..af07024cb7af5 100644
--- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp
@@ -83,11 +83,8 @@ namespace Undefined {
   static_assert(A<short>::f<int>() == 1);
   static_assert(A<short>::x<int> == 1);
   static_assert(A<short>::x<int*> == 2);
-#if 0
-  // FIXME: crashes
   static_assert(A<short>::B<int>::y == 1);
   static_assert(A<short>::B<int*>::y == 2);
-#endif
 } // namespace Undefined
 
 namespace Defined {
@@ -337,8 +334,5 @@ namespace Dependent {
 
   static_assert(A<0>::f<2>() == 2);
   static_assert(A<0>::x<2> == 2);
-#if 0
-  // FIXME: crashes
   static_assert(A<0>::B<2>::y == 2);
-#endif
 } // namespace Dependent
diff --git a/clang/test/Modules/cxx-templates.cpp 
b/clang/test/Modules/cxx-templates.cpp
index 15f6091774424..e36511d8e315f 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -193,8 +193,7 @@ namespace hidden_specializations {
     cls<char*> uk4; // expected-error 1+{{partial specialization of 'cls<T *>' 
must be imported}} expected-error 1+{{definition of}}
     cls<void>::nested_cls unk1; // expected-error 1+{{explicit specialization 
of 'nested_cls' must be imported}} expected-error 1+{{definition of}}
     cls<void>::nested_cls_t<int> unk2; // expected-error 1+{{explicit 
specialization of 'nested_cls_t' must be imported}} expected-error 
1+{{definition of}}
-    // [email protected]:29 {{explicit specialization 
of 'nested_cls_t' must be imported}}
-    // expected-note@-2 {{in evaluation of exception specification}}
+    // expected-error@+1 1+{{definition of 'nested_cls_t' must be imported}}
     cls<void>::nested_cls_t<char> unk3; // expected-error 1+{{explicit 
specialization of 'nested_cls_t' must be imported}}
 
     // For enums, uses that would trigger instantiations of definitions are not

``````````

</details>


https://github.com/llvm/llvm-project/pull/199979
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to