[PATCH] D17215: [Sema] Fix PR14211 Crash for explicit instantiation of overloaded template function within class template
don hinton via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 5 17:19:07 PDT 2017
hintonda updated this revision to Diff 101482.
hintonda added a comment.
Fixes PR14211.
Since getMostSpecialized only handles FunctionTemplateDecl matches,
keep track of non-FunctionTemplateDecl matches and only call
getMostSpecialized if no non-FunctionTemplateDecl matches are found.
Added tests.
https://reviews.llvm.org/D17215
Files:
lib/Sema/SemaTemplate.cpp
test/CXX/temp/temp.decls/temp.mem/p5.cpp
Index: test/CXX/temp/temp.decls/temp.mem/p5.cpp
===================================================================
--- test/CXX/temp/temp.decls/temp.mem/p5.cpp
+++ test/CXX/temp/temp.decls/temp.mem/p5.cpp
@@ -77,3 +77,16 @@
x0.operator float *();
x0c.operator const char*();
}
+
+namespace PR14211 {
+template <class U> struct X {
+ void foo(U){}
+ template <class T> void foo(T){}
+
+ template <class T> void bar(T){}
+ void bar(U){}
+};
+
+template void X<int>::foo(int);
+template void X<int>::bar(int);
+}
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -8956,6 +8956,7 @@
// instantiated from the member definition associated with its class
// template.
UnresolvedSet<8> Matches;
+ FunctionDecl *NonTemplateMatch = nullptr;
AttributeList *Attr = D.getDeclSpec().getAttributes().getList();
TemplateSpecCandidateSet FailedCandidates(D.getIdentifierLoc());
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
@@ -8966,12 +8967,22 @@
QualType Adjusted = adjustCCAndNoReturn(R, Method->getType(),
/*AdjustExceptionSpec*/true);
if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) {
- Matches.clear();
-
+ if (!Method->getPrimaryTemplate()) {
+ // FIXME: Can this assert ever happen? Needs a test.
+ assert(!NonTemplateMatch && "Multiple NonTemplateMatches");
+ NonTemplateMatch = Method;
+ continue;
+ }
Matches.addDecl(Method, P.getAccess());
+
+ // FIXME: Can this ever be true? Even so, should it really be a
+ // break? Needs a test.
if (Method->getTemplateSpecializationKind() == TSK_Undeclared)
break;
+ continue;
}
+ // FIXME: Would this be considered an almost match as well?
+ continue;
}
}
@@ -9012,19 +9023,22 @@
Matches.addDecl(Specialization, P.getAccess());
}
- // 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;
+ FunctionDecl *Specialization = NonTemplateMatch;
+ if (!Specialization) {
+ // 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;
- // 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.101482.patch
Type: text/x-patch
Size: 3498 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170606/98c84749/attachment.bin>
More information about the cfe-commits
mailing list