From: Douglas Gregor Date: Thu, 13 Sep 2012 21:01:57 +0000 (+0000) Subject: Don't perform template argument deduction against invalid templates; X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae19fbba559d8199d1f2b7154863180b0ae22ac7;p=clang Don't perform template argument deduction against invalid templates; it's likely to lead to a crash later on. Fixes PR12933 / . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163838 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 73d80d92da..3c4271a853 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5280,6 +5280,8 @@ public: enum TemplateDeductionResult { /// \brief Template argument deduction was successful. TDK_Success = 0, + /// \brief The declaration was invalid; do nothing. + TDK_Invalid, /// \brief Template argument deduction exceeded the maximum template /// instantiation depth (which has already been diagnosed). TDK_InstantiationDepth, diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index ec64665516..b607ab63b4 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -555,6 +555,7 @@ static MakeDeductionFailureInfo(ASTContext &Context, Result.Data = 0; switch (TDK) { case Sema::TDK_Success: + case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: @@ -597,6 +598,7 @@ static MakeDeductionFailureInfo(ASTContext &Context, void OverloadCandidate::DeductionFailureInfo::Destroy() { switch (static_cast(Result)) { case Sema::TDK_Success: + case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_TooManyArguments: @@ -637,6 +639,7 @@ TemplateParameter OverloadCandidate::DeductionFailureInfo::getTemplateParameter() { switch (static_cast(Result)) { case Sema::TDK_Success: + case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: @@ -664,6 +667,7 @@ TemplateArgumentList * OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() { switch (static_cast(Result)) { case Sema::TDK_Success: + case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: @@ -688,6 +692,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() { const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() { switch (static_cast(Result)) { case Sema::TDK_Success: + case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_TooManyArguments: @@ -713,6 +718,7 @@ const TemplateArgument * OverloadCandidate::DeductionFailureInfo::getSecondArg() { switch (static_cast(Result)) { case Sema::TDK_Success: + case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_Incomplete: case Sema::TDK_TooManyArguments: @@ -8555,6 +8561,7 @@ RankDeductionFailure(const OverloadCandidate::DeductionFailureInfo &DFI) { case Sema::TDK_Success: llvm_unreachable("TDK_success while diagnosing bad deduction"); + case Sema::TDK_Invalid: case Sema::TDK_Incomplete: return 1; diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index b236f2861e..5b13f70e54 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2165,6 +2165,9 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, const TemplateArgumentList &TemplateArgs, TemplateDeductionInfo &Info) { + if (Partial->isInvalidDecl()) + return TDK_Invalid; + // C++ [temp.class.spec.match]p2: // A partial specialization matches a given actual template // argument list if the template arguments of the partial @@ -3015,6 +3018,9 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, llvm::ArrayRef Args, FunctionDecl *&Specialization, TemplateDeductionInfo &Info) { + if (FunctionTemplate->isInvalidDecl()) + return TDK_Invalid; + FunctionDecl *Function = FunctionTemplate->getTemplatedDecl(); // C++ [temp.deduct.call]p1: @@ -3271,6 +3277,9 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, QualType ArgFunctionType, FunctionDecl *&Specialization, TemplateDeductionInfo &Info) { + if (FunctionTemplate->isInvalidDecl()) + return TDK_Invalid; + FunctionDecl *Function = FunctionTemplate->getTemplatedDecl(); TemplateParameterList *TemplateParams = FunctionTemplate->getTemplateParameters(); @@ -3330,6 +3339,9 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, QualType ToType, CXXConversionDecl *&Specialization, TemplateDeductionInfo &Info) { + if (FunctionTemplate->isInvalidDecl()) + return TDK_Invalid; + CXXConversionDecl *Conv = cast(FunctionTemplate->getTemplatedDecl()); QualType FromType = Conv->getConversionType(); diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp index cf3899f5ed..ab5e465680 100644 --- a/test/SemaTemplate/deduction-crash.cpp +++ b/test/SemaTemplate/deduction-crash.cpp @@ -2,7 +2,7 @@ // Note that the error count below doesn't matter. We just want to // make sure that the parser doesn't crash. -// CHECK: 13 errors +// CHECK: 15 errors // PR7511 template @@ -87,3 +87,15 @@ void register_object_imp ( ) { cout << endl<1>; } + +// PR12933 +namespacae PR12933 { + template + template + void function(S a, T b) {} + + int main() { + function(0, 1); + return 0; + } +}