Don't perform template argument deduction against invalid templates;
it's likely to lead to a crash later on. Fixes PR12933 / <rdar://problem/11525335>. llvm-svn: 163838
This commit is contained in:
parent
4d9ae56a45
commit
c5c01a60c2
|
@ -5280,6 +5280,8 @@ public:
|
||||||
enum TemplateDeductionResult {
|
enum TemplateDeductionResult {
|
||||||
/// \brief Template argument deduction was successful.
|
/// \brief Template argument deduction was successful.
|
||||||
TDK_Success = 0,
|
TDK_Success = 0,
|
||||||
|
/// \brief The declaration was invalid; do nothing.
|
||||||
|
TDK_Invalid,
|
||||||
/// \brief Template argument deduction exceeded the maximum template
|
/// \brief Template argument deduction exceeded the maximum template
|
||||||
/// instantiation depth (which has already been diagnosed).
|
/// instantiation depth (which has already been diagnosed).
|
||||||
TDK_InstantiationDepth,
|
TDK_InstantiationDepth,
|
||||||
|
|
|
@ -555,6 +555,7 @@ static MakeDeductionFailureInfo(ASTContext &Context,
|
||||||
Result.Data = 0;
|
Result.Data = 0;
|
||||||
switch (TDK) {
|
switch (TDK) {
|
||||||
case Sema::TDK_Success:
|
case Sema::TDK_Success:
|
||||||
|
case Sema::TDK_Invalid:
|
||||||
case Sema::TDK_InstantiationDepth:
|
case Sema::TDK_InstantiationDepth:
|
||||||
case Sema::TDK_TooManyArguments:
|
case Sema::TDK_TooManyArguments:
|
||||||
case Sema::TDK_TooFewArguments:
|
case Sema::TDK_TooFewArguments:
|
||||||
|
@ -597,6 +598,7 @@ static MakeDeductionFailureInfo(ASTContext &Context,
|
||||||
void OverloadCandidate::DeductionFailureInfo::Destroy() {
|
void OverloadCandidate::DeductionFailureInfo::Destroy() {
|
||||||
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
||||||
case Sema::TDK_Success:
|
case Sema::TDK_Success:
|
||||||
|
case Sema::TDK_Invalid:
|
||||||
case Sema::TDK_InstantiationDepth:
|
case Sema::TDK_InstantiationDepth:
|
||||||
case Sema::TDK_Incomplete:
|
case Sema::TDK_Incomplete:
|
||||||
case Sema::TDK_TooManyArguments:
|
case Sema::TDK_TooManyArguments:
|
||||||
|
@ -637,6 +639,7 @@ TemplateParameter
|
||||||
OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
|
OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
|
||||||
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
||||||
case Sema::TDK_Success:
|
case Sema::TDK_Success:
|
||||||
|
case Sema::TDK_Invalid:
|
||||||
case Sema::TDK_InstantiationDepth:
|
case Sema::TDK_InstantiationDepth:
|
||||||
case Sema::TDK_TooManyArguments:
|
case Sema::TDK_TooManyArguments:
|
||||||
case Sema::TDK_TooFewArguments:
|
case Sema::TDK_TooFewArguments:
|
||||||
|
@ -664,6 +667,7 @@ TemplateArgumentList *
|
||||||
OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
|
OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
|
||||||
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
||||||
case Sema::TDK_Success:
|
case Sema::TDK_Success:
|
||||||
|
case Sema::TDK_Invalid:
|
||||||
case Sema::TDK_InstantiationDepth:
|
case Sema::TDK_InstantiationDepth:
|
||||||
case Sema::TDK_TooManyArguments:
|
case Sema::TDK_TooManyArguments:
|
||||||
case Sema::TDK_TooFewArguments:
|
case Sema::TDK_TooFewArguments:
|
||||||
|
@ -688,6 +692,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
|
||||||
const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
|
const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
|
||||||
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
||||||
case Sema::TDK_Success:
|
case Sema::TDK_Success:
|
||||||
|
case Sema::TDK_Invalid:
|
||||||
case Sema::TDK_InstantiationDepth:
|
case Sema::TDK_InstantiationDepth:
|
||||||
case Sema::TDK_Incomplete:
|
case Sema::TDK_Incomplete:
|
||||||
case Sema::TDK_TooManyArguments:
|
case Sema::TDK_TooManyArguments:
|
||||||
|
@ -713,6 +718,7 @@ const TemplateArgument *
|
||||||
OverloadCandidate::DeductionFailureInfo::getSecondArg() {
|
OverloadCandidate::DeductionFailureInfo::getSecondArg() {
|
||||||
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
|
||||||
case Sema::TDK_Success:
|
case Sema::TDK_Success:
|
||||||
|
case Sema::TDK_Invalid:
|
||||||
case Sema::TDK_InstantiationDepth:
|
case Sema::TDK_InstantiationDepth:
|
||||||
case Sema::TDK_Incomplete:
|
case Sema::TDK_Incomplete:
|
||||||
case Sema::TDK_TooManyArguments:
|
case Sema::TDK_TooManyArguments:
|
||||||
|
@ -8555,6 +8561,7 @@ RankDeductionFailure(const OverloadCandidate::DeductionFailureInfo &DFI) {
|
||||||
case Sema::TDK_Success:
|
case Sema::TDK_Success:
|
||||||
llvm_unreachable("TDK_success while diagnosing bad deduction");
|
llvm_unreachable("TDK_success while diagnosing bad deduction");
|
||||||
|
|
||||||
|
case Sema::TDK_Invalid:
|
||||||
case Sema::TDK_Incomplete:
|
case Sema::TDK_Incomplete:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
|
@ -2165,6 +2165,9 @@ Sema::TemplateDeductionResult
|
||||||
Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
|
Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
|
||||||
const TemplateArgumentList &TemplateArgs,
|
const TemplateArgumentList &TemplateArgs,
|
||||||
TemplateDeductionInfo &Info) {
|
TemplateDeductionInfo &Info) {
|
||||||
|
if (Partial->isInvalidDecl())
|
||||||
|
return TDK_Invalid;
|
||||||
|
|
||||||
// C++ [temp.class.spec.match]p2:
|
// C++ [temp.class.spec.match]p2:
|
||||||
// A partial specialization matches a given actual template
|
// A partial specialization matches a given actual template
|
||||||
// argument list if the template arguments of the partial
|
// argument list if the template arguments of the partial
|
||||||
|
@ -3015,6 +3018,9 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
|
||||||
llvm::ArrayRef<Expr *> Args,
|
llvm::ArrayRef<Expr *> Args,
|
||||||
FunctionDecl *&Specialization,
|
FunctionDecl *&Specialization,
|
||||||
TemplateDeductionInfo &Info) {
|
TemplateDeductionInfo &Info) {
|
||||||
|
if (FunctionTemplate->isInvalidDecl())
|
||||||
|
return TDK_Invalid;
|
||||||
|
|
||||||
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
|
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
|
||||||
|
|
||||||
// C++ [temp.deduct.call]p1:
|
// C++ [temp.deduct.call]p1:
|
||||||
|
@ -3271,6 +3277,9 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
|
||||||
QualType ArgFunctionType,
|
QualType ArgFunctionType,
|
||||||
FunctionDecl *&Specialization,
|
FunctionDecl *&Specialization,
|
||||||
TemplateDeductionInfo &Info) {
|
TemplateDeductionInfo &Info) {
|
||||||
|
if (FunctionTemplate->isInvalidDecl())
|
||||||
|
return TDK_Invalid;
|
||||||
|
|
||||||
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
|
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
|
||||||
TemplateParameterList *TemplateParams
|
TemplateParameterList *TemplateParams
|
||||||
= FunctionTemplate->getTemplateParameters();
|
= FunctionTemplate->getTemplateParameters();
|
||||||
|
@ -3330,6 +3339,9 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
|
||||||
QualType ToType,
|
QualType ToType,
|
||||||
CXXConversionDecl *&Specialization,
|
CXXConversionDecl *&Specialization,
|
||||||
TemplateDeductionInfo &Info) {
|
TemplateDeductionInfo &Info) {
|
||||||
|
if (FunctionTemplate->isInvalidDecl())
|
||||||
|
return TDK_Invalid;
|
||||||
|
|
||||||
CXXConversionDecl *Conv
|
CXXConversionDecl *Conv
|
||||||
= cast<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl());
|
= cast<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl());
|
||||||
QualType FromType = Conv->getConversionType();
|
QualType FromType = Conv->getConversionType();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// Note that the error count below doesn't matter. We just want to
|
// Note that the error count below doesn't matter. We just want to
|
||||||
// make sure that the parser doesn't crash.
|
// make sure that the parser doesn't crash.
|
||||||
// CHECK: 13 errors
|
// CHECK: 15 errors
|
||||||
|
|
||||||
// PR7511
|
// PR7511
|
||||||
template<a>
|
template<a>
|
||||||
|
@ -87,3 +87,15 @@ void register_object_imp ( )
|
||||||
{
|
{
|
||||||
cout << endl<1>;
|
cout << endl<1>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PR12933
|
||||||
|
namespacae PR12933 {
|
||||||
|
template<typename S>
|
||||||
|
template<typename T>
|
||||||
|
void function(S a, T b) {}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
function(0, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue