re PR c++/15339 ([DR217] Adding default arguments to function templates in redeclarations should be forbidden)

/cp
2014-08-02  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/15339
	* decl.c (check_redeclaration_no_default_args): New.
	(duplicate_decls): Use it, handle default arguments
	in redeclarations of function templates.

/testsuite
2014-08-02  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/15339
	* g++.dg/other/default9.C: New.
	* g++.dg/other/default10.C: Likewise.
	* g++.dg/other/default3.C: Remove xfail.

From-SVN: r213519
This commit is contained in:
Paolo Carlini 2014-08-02 19:41:32 +00:00
parent 91bc34a94d
commit e83a4a2e40
6 changed files with 80 additions and 22 deletions

View file

@ -1,3 +1,10 @@
2014-08-02 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/15339
* decl.c (check_redeclaration_no_default_args): New.
(duplicate_decls): Use it, handle default arguments
in redeclarations of function templates.
2014-08-02 Trevor Saunders <tsaunders@mozilla.com>
* optimize.c, semantics.c: Use hash_map instead of pointer_map.

View file

@ -1236,6 +1236,27 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl)
return true;
}
/* DECL is a redeclaration of a function or function template. If
it does have default arguments issue a diagnostic. Note: this
function is used to enforce the requirements in C++11 8.3.6 about
no default arguments in redeclarations. */
static void
check_redeclaration_no_default_args (tree decl)
{
gcc_assert (DECL_DECLARES_FUNCTION_P (decl));
for (tree t = FUNCTION_FIRST_USER_PARMTYPE (decl);
t && t != void_list_node; t = TREE_CHAIN (t))
if (TREE_PURPOSE (t))
{
permerror (input_location,
"redeclaration of %q#D may not have default "
"arguments", decl);
return;
}
}
#define GNU_INLINE_P(fn) (DECL_DECLARED_INLINE_P (fn) \
&& lookup_attribute ("gnu_inline", \
DECL_ATTRIBUTES (fn)))
@ -1706,28 +1727,23 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
;
else if (TREE_CODE (olddecl) == FUNCTION_DECL)
{
tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl);
tree t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
int i = 1;
if (DECL_FUNCTION_MEMBER_P (newdecl)
&& CLASSTYPE_TEMPLATE_INFO (CP_DECL_CONTEXT (newdecl)))
{
/* C++11 8.3.6/6.
Default arguments for a member function of a class template
shall be specified on the initial declaration of the member
function within the class template. */
for (; t2 && t2 != void_list_node; t2 = TREE_CHAIN (t2))
if (TREE_PURPOSE (t2))
{
permerror (input_location,
"redeclaration of %q#D may not have default "
"arguments", newdecl);
break;
}
}
/* Note: free functions, as TEMPLATE_DECLs, are handled below. */
if (DECL_FUNCTION_MEMBER_P (olddecl)
&& (/* grokfndecl passes member function templates too
as FUNCTION_DECLs. */
DECL_TEMPLATE_INFO (olddecl)
/* C++11 8.3.6/6.
Default arguments for a member function of a class
template shall be specified on the initial declaration
of the member function within the class template. */
|| CLASSTYPE_TEMPLATE_INFO (CP_DECL_CONTEXT (olddecl))))
check_redeclaration_no_default_args (newdecl);
else
{
tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl);
tree t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
int i = 1;
for (; t1 && t1 != void_list_node;
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++)
if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
@ -1864,6 +1880,12 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
if (DECL_FUNCTION_TEMPLATE_P (newdecl))
{
/* Per C++11 8.3.6/4, default arguments cannot be added in later
declarations of a function template. */
check_redeclaration_no_default_args (newdecl);
check_default_args (newdecl);
if (GNU_INLINE_P (old_result) != GNU_INLINE_P (new_result)
&& DECL_INITIAL (new_result))
{

View file

@ -1,4 +1,11 @@
2014-08-01 Jan Hubicka <hubicka@ucw.cz>
2014-08-02 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/15339
* g++.dg/other/default9.C: New.
* g++.dg/other/default10.C: Likewise.
* g++.dg/other/default3.C: Remove xfail.
2014-08-02 Jan Hubicka <hubicka@ucw.cz>
* g++.dg/warn/Wsuggest-final.C: New testcase.
* g++.dg/ipa/devirt-34.C: Fix.

View file

@ -0,0 +1,4 @@
// PR c++/15339
template<typename> void g3(int, int);
template<typename> void g3(int = 0, int) { } // { dg-error "may not have default arguments|default argument missing" }

View file

@ -25,7 +25,7 @@ template<typename> void g3(int, int);
template<typename> void g3(int = 0, int); // { dg-error "default" }
template<typename> void g4(int, int);
template<typename> void g4(int = 0, int) {} // { dg-error "default" "" { xfail *-*-* } }
template<typename> void g4(int = 0, int) {} // { dg-error "default" }
template<typename> void g5();
template<typename> void g5(int = 0, int); // { dg-error "default" }

View file

@ -0,0 +1,18 @@
// PR c++/15339
template<typename> void fun(int);
template<typename> void fun(int = 0); // { dg-error "default arguments" }
class A
{
template<typename> void fun(int);
};
template<typename> void A::fun(int = 0) { } // { dg-error "default arguments" }
class B
{
void fun(int);
};
void B::fun(int = 0) { }