Hi,

today I noticed that the accepts-invalid half this bug report is already fixed in 5+, but the rejects-valid second half is still an issue: I think we can easily use CLASSTYPE_IS_TEMPLATE on current_class_type to skip members of non-template classes. Tested x86_64-linux.

Thanks,
Paolo.

////////////////////////
/cp
2015-09-22  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/53856
        * pt.c (check_default_tmpl_args): Per [temp.param]/9, do not
        reject default template arguments in out of class definitions
        of members of non-template classes.

/testsuite
2015-09-22  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/53856
        * g++.dg/template/defarg19.C: New.
        * g++.dg/template/defarg20.C: Likewise.
Index: cp/pt.c
===================================================================
--- cp/pt.c     (revision 228020)
+++ cp/pt.c     (working copy)
@@ -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;
Index: testsuite/g++.dg/template/defarg19.C
===================================================================
--- testsuite/g++.dg/template/defarg19.C        (revision 0)
+++ testsuite/g++.dg/template/defarg19.C        (working copy)
@@ -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 = { };
Index: testsuite/g++.dg/template/defarg20.C
===================================================================
--- testsuite/g++.dg/template/defarg20.C        (revision 0)
+++ testsuite/g++.dg/template/defarg20.C        (working copy)
@@ -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 = { };

Reply via email to