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:
Douglas Gregor 2012-09-13 21:01:57 +00:00
parent 4d9ae56a45
commit c5c01a60c2
4 changed files with 34 additions and 1 deletions

View File

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

View File

@ -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<Sema::TemplateDeductionResult>(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<Sema::TemplateDeductionResult>(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<Sema::TemplateDeductionResult>(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<Sema::TemplateDeductionResult>(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<Sema::TemplateDeductionResult>(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;

View File

@ -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<Expr *> 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<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl());
QualType FromType = Conv->getConversionType();

View File

@ -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<a>
@ -87,3 +87,15 @@ void register_object_imp ( )
{
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;
}
}