===================================================================
@@ -4793,8 +4793,8 @@ bool
check_default_tmpl_args (tree decl, tree parms, bool is_primary,
bool is_partial, int is_friend_decl)
{
- const char *msg;
- int last_level_to_check;
+ const char *msg = 0;
+ int last_level_to_check = 0; /* By default check everything. */
tree parm_level;
bool no_errors = true;
@@ -4940,6 +4940,13 @@ check_default_tmpl_args (tree decl, tree parms, bo
else if (is_partial)
msg = G_("default template arguments may not be used in "
"partial specializations");
+ else if (current_class_type && !CLASSTYPE_IS_TEMPLATE (current_class_type))
+ /* Per [temp.param]/9, "A default template-argument shall not be
+ specified in the template-parameter-lists of the definition of
+ a member of a class template that appears outside of the member's
+ class.", thus if we aren't handling a member of a class template
+ there is no need to examine the parameters. */
+ last_level_to_check = template_class_depth (current_class_type) + 1;
else
msg = G_("default argument for template parameter for class enclosing %qD");
@@ -4953,9 +4960,6 @@ check_default_tmpl_args (tree decl, tree parms, bo
Here the default argument for `S' has no bearing on the
declaration of `f'. */
last_level_to_check = template_class_depth (current_class_type) + 1;
- else
- /* Check everything. */
- last_level_to_check = 0;
for (parm_level = parms;
parm_level && TMPL_PARMS_DEPTH (parm_level) >= last_level_to_check;
===================================================================
@@ -0,0 +1,15 @@
+// PR c++/53856
+
+template<typename T>
+struct A
+{
+ struct B;
+};
+
+template<typename T = int>
+struct A<T>::B // { dg-error "default argument" }
+{
+ int i;
+};
+
+A<int>::B b = { };
===================================================================
@@ -0,0 +1,15 @@
+// PR c++/53856
+
+struct A
+{
+ template<typename T>
+ struct B;
+};
+
+template<typename T = int>
+struct A::B
+{
+ int i;
+};
+
+A::B<int> b = { };