summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTDiagnostic.cpp
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2013-10-08 16:58:52 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2013-10-08 16:58:52 +0000
commit3b05e20031bcd9fbdc4f65ef1ada3e887f9daeaf (patch)
tree836211894d6d830d2de875527e50f5d5d5800f4a /clang/lib/AST/ASTDiagnostic.cpp
parent22d6ac7e9a8180157044a33732c23125aa99fcb5 (diff)
downloadbcm5719-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.cpp15
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());
OpenPOWER on IntegriCloud