From: Alex Lorenz Date: Fri, 27 Oct 2017 18:13:31 +0000 (+0000) Subject: [Sema] Fix an assert-on-invalid by avoiding function template specialisation X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1c09b76713c0a3521937e035b3ab4edef687e7ee;p=clang [Sema] Fix an assert-on-invalid by avoiding function template specialisation deduction for invalid functions The fabricated template parameters cause an assertion because their depth is invalid. rdar://34109988 Differential Revision: https://reviews.llvm.org/D37341 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316778 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 573c1af8d2..d68b430bae 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -8962,10 +8962,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, diag::ext_function_specialization_in_class : diag::err_function_specialization_in_class) << NewFD->getDeclName(); - } else if (CheckFunctionTemplateSpecialization(NewFD, - (HasExplicitTemplateArgs ? &TemplateArgs - : nullptr), - Previous)) + } else if (!NewFD->isInvalidDecl() && + CheckFunctionTemplateSpecialization( + NewFD, (HasExplicitTemplateArgs ? &TemplateArgs : nullptr), + Previous)) NewFD->setInvalidDecl(); // C++ [dcl.stc]p1: diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp index 74a25865aa..2c58fefa06 100644 --- a/test/SemaTemplate/deduction-crash.cpp +++ b/test/SemaTemplate/deduction-crash.cpp @@ -144,3 +144,20 @@ namespace var_template_partial_spec_incomplete { template int n; // expected-error +{{}} expected-note {{}} int k = n; } + +namespace deduceFunctionSpecializationForInvalidOutOfLineFunction { + +template +struct SourceSelectionRequirement { + template + OutputT evaluateSelectionRequirement(InputT &&Value) { + } +}; + +template +OutputT SourceSelectionRequirement:: +evaluateSelectionRequirement(InputT &&Value) { // expected-error {{cannot specialize a member of an unspecialized template}} + return Value; +} + +} diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp index c0c36808b4..e8165ac9ca 100644 --- a/test/SemaTemplate/explicit-specialization-member.cpp +++ b/test/SemaTemplate/explicit-specialization-member.cpp @@ -38,24 +38,20 @@ namespace PR18246 { template template - void Baz::bar() { // expected-note {{couldn't infer template argument 'N'}} + void Baz::bar() { } - // FIXME: We shouldn't try to match this against a prior declaration if - // template parameter matching failed. template - void Baz::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}} \ - // expected-error {{no function template matches}} + void Baz::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}} } } namespace PR19340 { template struct Helper { - template static void func(const T *m) {} // expected-note {{failed template argument deduction}} + template static void func(const T *m) {} }; -template void Helper::func<2>() {} // expected-error {{cannot specialize a member}} \ - // expected-error {{no function template matches}} +template void Helper::func<2>() {} // expected-error {{cannot specialize a member}} } namespace SpecLoc {