diff mbox

[C++] PR 53856

Message ID 5601ACA0.3010405@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Sept. 22, 2015, 7:31 p.m. UTC
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.carlini@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.carlini@oracle.com>

	PR c++/53856
	* g++.dg/template/defarg19.C: New.
	* g++.dg/template/defarg20.C: Likewise.

Comments

Jason Merrill Sept. 24, 2015, 1:24 p.m. UTC | #1
On 09/22/2015 03:31 PM, Paolo Carlini wrote:
>      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");

Why not handle this below, with the other code that sets 
last_level_to_check?

Jason
diff mbox

Patch

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 = { };