[PATCH] D17215: [Sema] Fix PR14211 Crash for explicit instantiation of overloaded template function within class template

don hinton via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 15 10:14:45 PST 2016


hintonda updated this revision to Diff 47999.
hintonda added a comment.

- Renamed variables to make code self-documenting


http://reviews.llvm.org/D17215

Files:
  lib/Sema/SemaTemplate.cpp
  test/SemaCXX/pr14211-crash-on-invalid.cpp

Index: test/SemaCXX/pr14211-crash-on-invalid.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/pr14211-crash-on-invalid.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// Don't crash (PR14211).
+
+template<class T>
+struct X {
+  void bar(T t) {}
+  void foo(T t, int i) {}
+  template<class U>
+  void foo(T t, U i) {}
+};
+
+template class X<double>; // expected-note {{previous explicit instantiation is here}}
+template void X<double>::foo(double t, int i); // expected-error {{duplicate explicit instantiation of 'foo'}}
+template void X<double>::foo<int>(double t, int i);
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -7825,20 +7825,24 @@
   //   A member function [...] of a class template can be explicitly
   //  instantiated from the member definition associated with its class
   //  template.
-  UnresolvedSet<8> Matches;
+  UnresolvedSet<8> TemplateMatches;
+  FunctionDecl *NonTemplateMatch = nullptr;
   TemplateSpecCandidateSet FailedCandidates(D.getIdentifierLoc());
   for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
        P != PEnd; ++P) {
     NamedDecl *Prev = *P;
     if (!HasExplicitTemplateArgs) {
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) {
         QualType Adjusted = adjustCCAndNoReturn(R, Method->getType());
         if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) {
-          Matches.clear();
-
-          Matches.addDecl(Method, P.getAccess());
-          if (Method->getTemplateSpecializationKind() == TSK_Undeclared)
-            break;
+          if (Method->getPrimaryTemplate()){
+            TemplateMatches.clear();
+
+            TemplateMatches.addDecl(Method, P.getAccess());
+            if (Method->getTemplateSpecializationKind() == TSK_Undeclared)
+              break;
+          } else
+            NonTemplateMatch = Method;
         }
       }
     }
@@ -7862,22 +7866,25 @@
       continue;
     }
 
-    Matches.addDecl(Specialization, P.getAccess());
+    TemplateMatches.addDecl(Specialization, P.getAccess());
   }
 
+  FunctionDecl *Specialization = NonTemplateMatch;
   // Find the most specialized function template specialization.
-  UnresolvedSetIterator Result = getMostSpecialized(
-      Matches.begin(), Matches.end(), FailedCandidates,
-      D.getIdentifierLoc(),
-      PDiag(diag::err_explicit_instantiation_not_known) << Name,
-      PDiag(diag::err_explicit_instantiation_ambiguous) << Name,
-      PDiag(diag::note_explicit_instantiation_candidate));
-
-  if (Result == Matches.end())
-    return true;
+  if (!Specialization) {
+    UnresolvedSetIterator Result = getMostSpecialized(
+        TemplateMatches.begin(), TemplateMatches.end(), FailedCandidates,
+        D.getIdentifierLoc(),
+        PDiag(diag::err_explicit_instantiation_not_known) << Name,
+        PDiag(diag::err_explicit_instantiation_ambiguous) << Name,
+        PDiag(diag::note_explicit_instantiation_candidate));
+
+    if (Result == TemplateMatches.end())
+      return true;
 
-  // Ignore access control bits, we don't need them for redeclaration checking.
-  FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
+    // Ignore access control bits, we don't need them for redeclaration checking.
+    Specialization = cast<FunctionDecl>(*Result);
+  }
 
   // C++11 [except.spec]p4
   // In an explicit instantiation an exception-specification may be specified,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17215.47999.patch
Type: text/x-patch
Size: 3591 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160215/b0bf86a4/attachment.bin>


More information about the cfe-commits mailing list