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 | |
| 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
| -rw-r--r-- | clang/lib/AST/ASTDiagnostic.cpp | 15 | ||||
| -rw-r--r-- | clang/test/Misc/diag-template-diffing.cpp | 18 |
2 files changed, 27 insertions, 6 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()); diff --git a/clang/test/Misc/diag-template-diffing.cpp b/clang/test/Misc/diag-template-diffing.cpp index 722ce98ecff..46807070c7c 100644 --- a/clang/test/Misc/diag-template-diffing.cpp +++ b/clang/test/Misc/diag-template-diffing.cpp @@ -1051,8 +1051,24 @@ namespace DependentInt { } } +namespace PR17510 { +class Atom; + +template <typename T> class allocator; +template <typename T, typename A> class vector; + +typedef vector<const Atom *, allocator<const Atom *> > AtomVector; + +template <typename T, typename A = allocator<const Atom *> > class vector {}; + +void foo() { + vector<Atom *> v; + AtomVector v2(v); + // CHECK-ELIDE-NOTREE: no known conversion from 'vector<class PR17510::Atom *, [...]>' to 'const vector<const class PR17510::Atom *, [...]>' +} +} + // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated. // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated. // CHECK-NOELIDE-TREE: {{[0-9]*}} errors generated. - |

