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