diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2013-10-08 16:58:52 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2013-10-08 16:58:52 +0000 |
commit | 3b05e20031bcd9fbdc4f65ef1ada3e887f9daeaf (patch) | |
tree | 836211894d6d830d2de875527e50f5d5d5800f4a /clang/lib/AST/ASTDiagnostic.cpp | |
parent | 22d6ac7e9a8180157044a33732c23125aa99fcb5 (diff) | |
download | bcm5719-llvm-3b05e20031bcd9fbdc4f65ef1ada3e887f9daeaf.tar.gz bcm5719-llvm-3b05e20031bcd9fbdc4f65ef1ada3e887f9daeaf.zip |
Fix an edge case in the template differ with default arguments.
In the test case one type is coming from a typedef with no default arg, the
other has the default arg. Taking the default arg from the typedef crashes, so
always use the real template paramter declaration. PR17510.
llvm-svn: 192202
Diffstat (limited to 'clang/lib/AST/ASTDiagnostic.cpp')
-rw-r--r-- | clang/lib/AST/ASTDiagnostic.cpp | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index eb22632c937..fce8f64b332 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -831,8 +831,10 @@ class TemplateDiff { void DiffTemplate(const TemplateSpecializationType *FromTST, const TemplateSpecializationType *ToTST) { // Begin descent into diffing template tree. - TemplateParameterList *Params = + TemplateParameterList *ParamsFrom = FromTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); + TemplateParameterList *ParamsTo = + ToTST->getTemplateName().getAsTemplateDecl()->getTemplateParameters(); unsigned TotalArgs = 0; for (TSTiterator FromIter(Context, FromTST), ToIter(Context, ToTST); !FromIter.isEnd() || !ToIter.isEnd(); ++TotalArgs) { @@ -841,15 +843,18 @@ class TemplateDiff { // Get the parameter at index TotalArgs. If index is larger // than the total number of parameters, then there is an // argument pack, so re-use the last parameter. - NamedDecl *ParamND = Params->getParam( - (TotalArgs < Params->size()) ? TotalArgs - : Params->size() - 1); + unsigned ParamIndex = std::min(TotalArgs, ParamsFrom->size() - 1); + NamedDecl *ParamND = ParamsFrom->getParam(ParamIndex); + // Handle Types if (TemplateTypeParmDecl *DefaultTTPD = dyn_cast<TemplateTypeParmDecl>(ParamND)) { QualType FromType, ToType; FromType = GetType(FromIter, DefaultTTPD); - ToType = GetType(ToIter, DefaultTTPD); + // A forward declaration can have no default arg but the actual class + // can, don't mix up iterators and get the original parameter. + ToType = GetType( + ToIter, cast<TemplateTypeParmDecl>(ParamsTo->getParam(ParamIndex))); Tree.SetNode(FromType, ToType); Tree.SetDefault(FromIter.isEnd() && !FromType.isNull(), ToIter.isEnd() && !ToType.isNull()); |