diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-07-19 20:40:20 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-07-19 20:40:20 +0000 |
commit | 0b75dc5fa2e0552e7c9f3250e3487cf73dacd32b (patch) | |
tree | db97575c2f0bd735f9201d0e297b90129ab75327 /clang/lib/Sema/SemaTemplate.cpp | |
parent | bc093ea0033d01f86724893d8fecd1b35792ebf4 (diff) | |
download | bcm5719-llvm-0b75dc5fa2e0552e7c9f3250e3487cf73dacd32b.tar.gz bcm5719-llvm-0b75dc5fa2e0552e7c9f3250e3487cf73dacd32b.zip |
[Sema] Diagnose an invalid dependent function template specialization
Previously, clang marked the specialization as invalid without emitting a
diagnostic. This lead to an assert in CodeGen.
rdar://41806724
Differential revision: https://reviews.llvm.org/D49085
llvm-svn: 337497
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 935264cb8cc..dd116326711 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -8003,17 +8003,34 @@ Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, // the correct context. DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext(); LookupResult::Filter F = Previous.makeFilter(); + enum DiscardReason { NotAFunctionTemplate, NotAMemberOfEnclosing }; + SmallVector<std::pair<DiscardReason, Decl *>, 8> DiscardedCandidates; while (F.hasNext()) { NamedDecl *D = F.next()->getUnderlyingDecl(); - if (!isa<FunctionTemplateDecl>(D) || - !FDLookupContext->InEnclosingNamespaceSetOf( - D->getDeclContext()->getRedeclContext())) + if (!isa<FunctionTemplateDecl>(D)) { F.erase(); + DiscardedCandidates.push_back(std::make_pair(NotAFunctionTemplate, D)); + continue; + } + + if (!FDLookupContext->InEnclosingNamespaceSetOf( + D->getDeclContext()->getRedeclContext())) { + F.erase(); + DiscardedCandidates.push_back(std::make_pair(NotAMemberOfEnclosing, D)); + continue; + } } F.done(); - // Should this be diagnosed here? - if (Previous.empty()) return true; + if (Previous.empty()) { + Diag(FD->getLocation(), + diag::err_dependent_function_template_spec_no_match); + for (auto &P : DiscardedCandidates) + Diag(P.second->getLocation(), + diag::note_dependent_function_template_spec_discard_reason) + << P.first; + return true; + } FD->setDependentTemplateSpecialization(Context, Previous.asUnresolvedSet(), ExplicitTemplateArgs); |