[clang] fe4c9b3 - [clang] Remove libstdc++ friend template hack

Nathan Sidwell via cfe-commits cfe-commits at lists.llvm.org
Mon May 3 04:20:40 PDT 2021


Author: Nathan Sidwell
Date: 2021-05-03T04:19:30-07:00
New Revision: fe4c9b3cb0c3c0cac6b63de3b47a86e31559bb6d

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

LOG: [clang] Remove libstdc++ friend template hack

this hack is for a now-unsupported version of libstdc++

Differential Revision: https://reviews.llvm.org/D101392

Added: 
    

Modified: 
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/SemaCXX/libstdcxx_map_base_hack.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index cd0f13b9e32ed..1d572054e5fb7 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1518,48 +1518,18 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
       return nullptr;
     }
 
-    bool AdoptedPreviousTemplateParams = false;
     if (PrevClassTemplate) {
-      bool Complain = true;
-
-      // HACK: libstdc++ 4.2.1 contains an ill-formed friend class
-      // template for struct std::tr1::__detail::_Map_base, where the
-      // template parameters of the friend declaration don't match the
-      // template parameters of the original declaration. In this one
-      // case, we don't complain about the ill-formed friend
-      // declaration.
-      if (isFriend && Pattern->getIdentifier() &&
-          Pattern->getIdentifier()->isStr("_Map_base") &&
-          DC->isNamespace() &&
-          cast<NamespaceDecl>(DC)->getIdentifier() &&
-          cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__detail")) {
-        DeclContext *DCParent = DC->getParent();
-        if (DCParent->isNamespace() &&
-            cast<NamespaceDecl>(DCParent)->getIdentifier() &&
-            cast<NamespaceDecl>(DCParent)->getIdentifier()->isStr("tr1")) {
-          if (cast<Decl>(DCParent)->isInStdNamespace())
-            Complain = false;
-        }
-      }
-
       TemplateParameterList *PrevParams
         = PrevClassTemplate->getMostRecentDecl()->getTemplateParameters();
 
       // Make sure the parameter lists match.
-      if (!SemaRef.TemplateParameterListsAreEqual(InstParams, PrevParams,
-                                                  Complain,
-                                                  Sema::TPL_TemplateMatch)) {
-        if (Complain)
-          return nullptr;
-
-        AdoptedPreviousTemplateParams = true;
-        InstParams = PrevParams;
-      }
+      if (!SemaRef.TemplateParameterListsAreEqual(InstParams, PrevParams, true,
+                                                  Sema::TPL_TemplateMatch))
+        return nullptr;
 
       // Do some additional validation, then merge default arguments
       // from the existing declarations.
-      if (!AdoptedPreviousTemplateParams &&
-          SemaRef.CheckTemplateParameterList(InstParams, PrevParams,
+      if (SemaRef.CheckTemplateParameterList(InstParams, PrevParams,
                                              Sema::TPC_ClassTemplate))
         return nullptr;
     }

diff  --git a/clang/test/SemaCXX/libstdcxx_map_base_hack.cpp b/clang/test/SemaCXX/libstdcxx_map_base_hack.cpp
index a556281fc0f86..3662f667c0009 100644
--- a/clang/test/SemaCXX/libstdcxx_map_base_hack.cpp
+++ b/clang/test/SemaCXX/libstdcxx_map_base_hack.cpp
@@ -1,25 +1,27 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // libstdc++ 4.2.x contains a bug where a friend struct template
 // declaration for std::tr1::__detail::_Map base has 
diff erent
-// template arguments than the real declaration. Clang has an
-// egregious hack to work around this problem, since we can't modify
-// all of the world's libstdc++'s.
+// template arguments than the real declaration.
 
-namespace std { namespace tr1 { namespace __detail {
-  template<typename _Key, typename _Value, typename _Ex, bool __unique,
-	   typename _Hashtable>
-    struct _Map_base { };
+// We no longer contain the hack to workaround the problem.  Verify that
+// std::tr1::__detail::Map_base is not a unique and special snowflake.
 
+namespace std { namespace tr1 { namespace __detail {
+template <typename _Key, typename _Value, typename _Ex, bool __unique,
+          // expected-note at -1{{previous template declaration}}
+          typename _Hashtable>
+struct _Map_base {};
 } } } 
 
 namespace std { namespace tr1 {
   template<typename T>
   struct X1 {
-    template<typename _Key2, typename _Pair, typename _Hashtable>
+    template <typename _Key2, typename _Pair, typename _Hashtable>
+    // expected-error at -1{{too few template parameters}}
     friend struct __detail::_Map_base;
   };
 
 } }
 
-std::tr1::X1<int> x1i;
+std::tr1::X1<int> x1i; // expected-note{{in instantiation}}


        


More information about the cfe-commits mailing list