[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