aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-27 01:40:17 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-27 01:40:17 +0000
commitfd1a8fd240c8067e286e3881aac2bd8b700517d3 (patch)
tree9a8b0c12298b2913f285a28dae640dd4c5797f42 /lib/Sema/SemaTemplate.cpp
parent944aa60777e6ea1015c9423107f7925f6d91f4a0 (diff)
When we run into a template parameter that should have a default
argument but doesn't (because previous template parameters had default arguments), clear out all of the default arguments so that we maintain the invariant that a template parameter has a default argument only if subsequence template parameters also have default arguments. Fixes a crash-on-invalid <rdar://problem/8913649>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124345 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index eed41cc396..1d2de0fb52 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1149,6 +1149,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
if (OldParams)
OldParam = OldParams->begin();
+ bool RemoveDefaultArguments = false;
for (TemplateParameterList::iterator NewParam = NewParams->begin(),
NewParamEnd = NewParams->end();
NewParam != NewParamEnd; ++NewParam) {
@@ -1317,13 +1318,14 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
} else if (MissingDefaultArg) {
// C++ [temp.param]p11:
// If a template-parameter of a class template has a default
- // template-argument, each subsequent template- parameter shall either
+ // template-argument, each subsequent template-parameter shall either
// have a default template-argument supplied or be a template parameter
// pack.
Diag((*NewParam)->getLocation(),
diag::err_template_param_default_arg_missing);
Diag(PreviousDefaultArgLoc, diag::note_template_param_prev_default_arg);
Invalid = true;
+ RemoveDefaultArguments = true;
}
// If we have an old template parameter list that we're merging
@@ -1332,6 +1334,22 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
++OldParam;
}
+ // We were missing some default arguments at the end of the list, so remove
+ // all of the default arguments.
+ if (RemoveDefaultArguments) {
+ for (TemplateParameterList::iterator NewParam = NewParams->begin(),
+ NewParamEnd = NewParams->end();
+ NewParam != NewParamEnd; ++NewParam) {
+ if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*NewParam))
+ TTP->removeDefaultArgument();
+ else if (NonTypeTemplateParmDecl *NTTP
+ = dyn_cast<NonTypeTemplateParmDecl>(*NewParam))
+ NTTP->removeDefaultArgument();
+ else
+ cast<TemplateTemplateParmDecl>(*NewParam)->removeDefaultArgument();
+ }
+ }
+
return Invalid;
}