[cfe-commits] r124345 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.param/p1.cpp
Douglas Gregor
dgregor at apple.com
Wed Jan 26 17:40:18 PST 2011
Author: dgregor
Date: Wed Jan 26 19:40:17 2011
New Revision: 124345
URL: http://llvm.org/viewvc/llvm-project?rev=124345&view=rev
Log:
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>.
Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/CXX/temp/temp.param/p1.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=124345&r1=124344&r2=124345&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jan 26 19:40:17 2011
@@ -1149,6 +1149,7 @@
if (OldParams)
OldParam = OldParams->begin();
+ bool RemoveDefaultArguments = false;
for (TemplateParameterList::iterator NewParam = NewParams->begin(),
NewParamEnd = NewParams->end();
NewParam != NewParamEnd; ++NewParam) {
@@ -1317,13 +1318,14 @@
} 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 @@
++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;
}
Modified: cfe/trunk/test/CXX/temp/temp.param/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p1.cpp?rev=124345&r1=124344&r2=124345&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.param/p1.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.param/p1.cpp Wed Jan 26 19:40:17 2011
@@ -4,3 +4,9 @@
template<template<> class C> class D; // expected-error{{template template parameter must have its own template parameters}}
+struct A {};
+template<class M,
+ class T = A, // expected-note{{previous default template argument defined here}}
+ class C> // expected-error{{template parameter missing a default argument}}
+class X0 {}; // expected-note{{template is declared here}}
+X0<int> x0; // expected-error{{too few template arguments for class template 'X0'}}
More information about the cfe-commits
mailing list