public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ Patch] PR 53856
@ 2015-09-22 19:41 Paolo Carlini
  2015-09-24 13:33 ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Paolo Carlini @ 2015-09-22 19:41 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

[-- Attachment #1: Type: text/plain, Size: 321 bytes --]

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.

////////////////////////

[-- Attachment #2: CL_53856 --]
[-- Type: text/plain, Size: 393 bytes --]

/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.

[-- Attachment #3: patch_53856 --]
[-- Type: text/plain, Size: 2516 bytes --]

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [C++ Patch] PR 53856
  2015-09-22 19:41 [C++ Patch] PR 53856 Paolo Carlini
@ 2015-09-24 13:33 ` Jason Merrill
  2015-10-05 16:50   ` Paolo Carlini
  0 siblings, 1 reply; 6+ messages in thread
From: Jason Merrill @ 2015-09-24 13:33 UTC (permalink / raw)
  To: Paolo Carlini, gcc-patches

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [C++ Patch] PR 53856
  2015-09-24 13:33 ` Jason Merrill
@ 2015-10-05 16:50   ` Paolo Carlini
  2015-10-05 17:10     ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Paolo Carlini @ 2015-10-05 16:50 UTC (permalink / raw)
  To: Jason Merrill, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1774 bytes --]

Hi,

On 09/24/2015 03:24 PM, Jason Merrill wrote:
> 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?
First, sorry for late replying (a few days of vacations)...

In general, the rationale behind changing that earlier conditional was 
restricting it to the specific case at issue and avoid affecting other 
default-related diagnostic. That said, the patch was subtly wrong 
anyway, because relied on msg remaining zero for the second call of 
check_default_tmpl_args for defarg20.C, thus the testcase was correctly 
accepted but with a zeroed default.

Today, it occurred to me that maybe we can even more directly avoid 
emitting a meaningless "default argument for template parameter for 
class enclosing" for an enclosing class which isn't a template. Thus the 
below, which definitely passes the testsuite and also complexified 
variants (deeper nestings) of the new testcases. Does it make sense to you?

Thanks,
Paolo.

//////////////////////////////

[-- Attachment #2: patch_53856_2 --]
[-- Type: text/plain, Size: 1909 bytes --]

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 228467)
+++ cp/pt.c	(working copy)
@@ -4940,8 +4940,15 @@ 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))
+    msg = G_("default argument for template parameter for class enclosing %qD");
   else
-    msg = G_("default argument for template parameter for class enclosing %qD");
+    /* 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.  */
+    return true;
 
   if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
     /* If we're inside a class definition, there's no need to
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 = { };

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [C++ Patch] PR 53856
  2015-10-05 16:50   ` Paolo Carlini
@ 2015-10-05 17:10     ` Jason Merrill
  2015-10-05 17:45       ` Paolo Carlini
  0 siblings, 1 reply; 6+ messages in thread
From: Jason Merrill @ 2015-10-05 17:10 UTC (permalink / raw)
  To: Paolo Carlini, gcc-patches

On 10/05/2015 12:50 PM, Paolo Carlini wrote:
> +  else if (!current_class_type || CLASSTYPE_IS_TEMPLATE (current_class_type))
> +    msg = G_("default argument for template parameter for class enclosing %qD");

Why would this be right when !current_class_type?

Jason

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [C++ Patch] PR 53856
  2015-10-05 17:10     ` Jason Merrill
@ 2015-10-05 17:45       ` Paolo Carlini
  2015-10-05 17:46         ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Paolo Carlini @ 2015-10-05 17:45 UTC (permalink / raw)
  To: Jason Merrill, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 524 bytes --]

Hi,

On 10/05/2015 07:10 PM, Jason Merrill wrote:
> On 10/05/2015 12:50 PM, Paolo Carlini wrote:
>> +  else if (!current_class_type || CLASSTYPE_IS_TEMPLATE 
>> (current_class_type))
>> +    msg = G_("default argument for template parameter for class 
>> enclosing %qD");
>
> Why would this be right when !current_class_type?
Yes, it doesn't make much sense, but at least it's conservatively 
correct ;) I'm finishing regtesting the below, everything seems fine so 
far. Ok if it passes?

Thanks,
Paolo.

//////////////////

[-- Attachment #2: patch_53856_2b --]
[-- Type: text/plain, Size: 1908 bytes --]

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 228467)
+++ cp/pt.c	(working copy)
@@ -4940,8 +4940,15 @@ 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))
+    msg = G_("default argument for template parameter for class enclosing %qD");
   else
-    msg = G_("default argument for template parameter for class enclosing %qD");
+    /* 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.  */
+    return true;
 
   if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
     /* If we're inside a class definition, there's no need to
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 = { };

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [C++ Patch] PR 53856
  2015-10-05 17:45       ` Paolo Carlini
@ 2015-10-05 17:46         ` Jason Merrill
  0 siblings, 0 replies; 6+ messages in thread
From: Jason Merrill @ 2015-10-05 17:46 UTC (permalink / raw)
  To: Paolo Carlini, gcc-patches

OK.

Jason

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-10-05 17:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-22 19:41 [C++ Patch] PR 53856 Paolo Carlini
2015-09-24 13:33 ` Jason Merrill
2015-10-05 16:50   ` Paolo Carlini
2015-10-05 17:10     ` Jason Merrill
2015-10-05 17:45       ` Paolo Carlini
2015-10-05 17:46         ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).