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

don hinton via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 12 14:05:40 PST 2016


hintonda created this revision.
hintonda added reviewers: lvoufo, rjmccall.
hintonda added a subscriber: cfe-commits.

Fix PR14211

Only add FunctionDecl's that are actual template methods to the set of
matches passed to getMostSpecializied() -- otherwise it will
assert/crash.  If a match to a non-template method is found, save the
pointer and don't call getMostSpecialized().

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
@@ -7826,19 +7826,23 @@
   //  instantiated from the member definition associated with its class
   //  template.
   UnresolvedSet<8> Matches;
+  FunctionDecl *Specialization = 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 (cast<FunctionDecl>(Method)->getPrimaryTemplate()){
+            Matches.clear();
+
+            Matches.addDecl(Method, P.getAccess());
+            if (Method->getTemplateSpecializationKind() == TSK_Undeclared)
+              break;
+          } else
+            Specialization = Method;
         }
       }
     }
@@ -7866,18 +7870,20 @@
   }
 
   // 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(
+        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;
 
-  // 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.47856.patch
Type: text/x-patch
Size: 3268 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160212/0344ac16/attachment.bin>


More information about the cfe-commits mailing list