[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
This commit is contained in:
Alex Lorenz 2017-10-27 18:13:31 +00:00
parent d64b9c663c
commit 1c09b76713
3 changed files with 25 additions and 12 deletions

View File

@ -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:

View File

@ -144,3 +144,20 @@ namespace var_template_partial_spec_incomplete {
template<typename T, typename U = void> int n<T *>; // expected-error +{{}} expected-note {{}}
int k = n<void *>;
}
namespace deduceFunctionSpecializationForInvalidOutOfLineFunction {
template <typename InputT, typename OutputT>
struct SourceSelectionRequirement {
template<typename T>
OutputT evaluateSelectionRequirement(InputT &&Value) {
}
};
template <typename InputT, typename OutputT>
OutputT SourceSelectionRequirement<InputT, OutputT>::
evaluateSelectionRequirement<void>(InputT &&Value) { // expected-error {{cannot specialize a member of an unspecialized template}}
return Value;
}
}

View File

@ -38,24 +38,20 @@ namespace PR18246 {
template<typename T>
template<int N>
void Baz<T>::bar() { // expected-note {{couldn't infer template argument 'N'}}
void Baz<T>::bar() {
}
// FIXME: We shouldn't try to match this against a prior declaration if
// template parameter matching failed.
template<typename T>
void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}} \
// expected-error {{no function template matches}}
void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}}
}
}
namespace PR19340 {
template<typename T> struct Helper {
template<int N> static void func(const T *m) {} // expected-note {{failed template argument deduction}}
template<int N> static void func(const T *m) {}
};
template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \
// expected-error {{no function template matches}}
template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}}
}
namespace SpecLoc {