Commit fde6f97e by Paolo Carlini

PR c++/21682, implement DR 565

/cp
2013-09-02  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/21682, implement DR 565
	* name-lookup.c (compparms_for_decl_and_using_decl): New.
	(push_overloaded_decl_1, do_nonmember_using_decl): Use it.

/testsuite
2013-09-02  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/21682, implement DR 565
	* g++.dg/template/using24.C: New.
	* g++.dg/template/using25.C: Likewise.
	* g++.dg/template/using26.C: Likewise.

From-SVN: r202163
parent 576016fe
2013-09-02 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/21682, implement DR 565
* name-lookup.c (compparms_for_decl_and_using_decl): New.
(push_overloaded_decl_1, do_nonmember_using_decl): Use it.
2013-08-30 Marek Polacek <polacek@redhat.com>
* typeck.c (cp_build_binary_op): Add division by zero and shift
......
......@@ -2267,6 +2267,27 @@ pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
return ret;
}
/* Helper function for push_overloaded_decl_1 and do_nonmember_using_decl.
Compares the parameter-type-lists of DECL1 and DECL2 and returns false
if they are different. If the DECLs are template functions, the return
types and the template parameter lists are compared too (DR 565). */
static bool
compparms_for_decl_and_using_decl (tree decl1, tree decl2)
{
if (!compparms (TYPE_ARG_TYPES (TREE_TYPE (decl1)),
TYPE_ARG_TYPES (TREE_TYPE (decl2))))
return false;
if (! DECL_FUNCTION_TEMPLATE_P (decl1)
|| ! DECL_FUNCTION_TEMPLATE_P (decl2))
return true;
return (comp_template_parms (DECL_TEMPLATE_PARMS (decl1),
DECL_TEMPLATE_PARMS (decl2))
&& same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
TREE_TYPE (TREE_TYPE (decl2))));
}
/* DECL is a FUNCTION_DECL for a non-member function, which may have
other definitions already in place. We get around this by making
......@@ -2324,8 +2345,7 @@ push_overloaded_decl_1 (tree decl, int flags, bool is_friend)
if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
&& !(flags & PUSH_USING)
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
TYPE_ARG_TYPES (TREE_TYPE (decl)))
&& compparms_for_decl_and_using_decl (fn, decl)
&& ! decls_match (fn, decl))
diagnose_name_conflict (decl, fn);
......@@ -2561,8 +2581,7 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
break;
else if (TREE_CODE (tmp1) == OVERLOAD && OVL_USED (tmp1))
continue; /* this is a using decl */
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
else if (compparms_for_decl_and_using_decl (new_fn, old_fn))
{
gcc_assert (!DECL_ANTICIPATED (old_fn)
|| DECL_HIDDEN_FRIEND_P (old_fn));
......
2013-09-01 Jan Hubicka <jh@suse.cz>
2013-09-02 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/21682, implement DR 565
* g++.dg/template/using24.C: New.
* g++.dg/template/using25.C: Likewise.
* g++.dg/template/using26.C: Likewise.
2013-09-01 Jan Hubicka <jh@suse.cz>
* g++.dg/ipa/devirt-15.C: New testcase.
......
// PR c++/21682
template <class T>
struct t
{
typedef typename T::type type;
};
template<> class t<int>{};
template <class T> struct t1{ };
template<> struct t1<int>
{
typedef int type;
};
namespace name1
{
template <class S> typename t<S>::type begin(S const& s);
namespace name2
{
template <class S> typename t1<S>::type begin(S const& s);
}
using name2::begin;
}
/* Test calling the function. */
int f(int a) { return name1::begin(a); }
struct aa { typedef double type; };
double g(aa t) { return name1::begin(t); }
// PR c++/21682
namespace one {
template<typename T> void fun(T);
}
using one::fun;
template<typename T> void fun(T); // { dg-error "conflicts" }
template<typename T> void funr(T);
namespace oner {
template<typename T> void funr(T);
}
using oner::funr; // { dg-error "conflicts" }
// PR c++/21682
namespace one {
template<typename T> int bar1(T);
}
using one::bar1;
template<typename T> void bar1(T);
template<typename T> void bar1r(T);
namespace oner {
template<typename T> int bar1r(T);
}
using oner::bar1r;
namespace two {
template<typename T, typename U> void bar2(T);
}
using two::bar2;
template<typename T> void bar2(T);
template<typename T> void bar2r(T);
namespace twor {
template<typename T, typename U> void bar2r(T);
}
using twor::bar2r;
namespace three {
template<int i> void bar3();
}
using three::bar3;
template<typename T> void bar3();
template<typename T> void bar3r();
namespace threer {
template<int i> void bar3r();
}
using threer::bar3r;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment