[PR c++/87531] Fix second bug

https://gcc.gnu.org/ml/gcc-patches/2018-12/msg00929.html

	PR c++/87531
	* class.c (finish_struct): Set DECL_CONTEXT of template assign op.
	* name-lookup.c (get_class_binding_direct): Don't strip using-decl
	of overload here.
	* parser.c (cp_parser_postfix_expression): Cope with using decl in
	overload set.
	* semantics.c (finish_id_expr): Likewise.

	* g++.dg/lookup/pr87531-2.C: New.

From-SVN: r267096
This commit is contained in:
Nathan Sidwell 2018-12-13 15:57:24 +00:00 committed by Nathan Sidwell
parent f1d42e85ad
commit 2139fd74f3
7 changed files with 90 additions and 16 deletions

View File

@ -1,3 +1,13 @@
2018-12-13 Nathan Sidwell <nathan@acm.org>
PR c++/87531
* class.c (finish_struct): Set DECL_CONTEXT of template assign op.
* name-lookup.c (get_class_binding_direct): Don't strip using-decl
of overload here.
* parser.c (cp_parser_postfix_expression): Cope with using decl in
overload set.
* semantics.c (finish_id_expr): Likewise.
2018-12-12 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (grokdeclarator): Fix location of error message about

View File

@ -7158,6 +7158,7 @@ finish_struct (tree t, tree attributes)
time. */
tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
NULL_TREE);
DECL_CONTEXT (ass_op) = t;
USING_DECL_SCOPE (ass_op) = t;
DECL_DEPENDENT_P (ass_op) = true;
DECL_ARTIFICIAL (ass_op) = true;

View File

@ -1242,17 +1242,6 @@ get_class_binding_direct (tree klass, tree name, int type_or_fns)
}
else if (STAT_HACK_P (val))
val = STAT_DECL (val);
if (val && TREE_CODE (val) == OVERLOAD
&& TREE_CODE (OVL_FUNCTION (val)) == USING_DECL)
{
/* An overload with a dependent USING_DECL. Does the caller
want the USING_DECL or the functions? */
if (type_or_fns < 0)
val = OVL_CHAIN (val);
else
val = OVL_FUNCTION (val);
}
}
else
{

View File

@ -7240,14 +7240,19 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
else if (!args->is_empty ()
&& is_overloaded_fn (postfix_expression))
{
/* We only need to look at the first function,
because all the fns share the attribute we're
concerned with (all member fns or all local
fns). */
tree fn = get_first_fn (postfix_expression);
fn = STRIP_TEMPLATE (fn);
/* Do not do argument dependent lookup if regular
lookup finds a member function or a block-scope
function declaration. [basic.lookup.argdep]/3 */
if (!DECL_FUNCTION_MEMBER_P (fn)
&& !DECL_LOCAL_FUNCTION_P (fn))
if (!((TREE_CODE (fn) == USING_DECL && DECL_DEPENDENT_P (fn))
|| DECL_FUNCTION_MEMBER_P (fn)
|| DECL_LOCAL_FUNCTION_P (fn)))
{
koenig_p = true;
if (!any_type_dependent_arguments_p (args))

View File

@ -3805,9 +3805,10 @@ finish_id_expression (tree id_expression,
return error_mark_node;
if (!template_arg_p
&& TREE_CODE (first_fn) == FUNCTION_DECL
&& DECL_FUNCTION_MEMBER_P (first_fn)
&& !shared_member_p (decl))
&& (TREE_CODE (first_fn) == USING_DECL
|| (TREE_CODE (first_fn) == FUNCTION_DECL
&& DECL_FUNCTION_MEMBER_P (first_fn)
&& !shared_member_p (decl))))
{
/* A set of member functions. */
decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);

View File

@ -1,3 +1,8 @@
2018-12-13 Nathan Sidwell <nathan@acm.org>
PR c++/87531
* g++.dg/lookup/pr87531-2.C: New.
2018-12-13 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR testsuite/88041

View File

@ -0,0 +1,63 @@
// PR 87531 part 2. dependent using decls + template decls.
template<typename T>
struct One
{
One& operator=(T* p_)
{
return operator=<T>(p_); // Parse failed here
}
template<typename U>
One& operator=(U* p_);
};
template<typename T>
struct Two : T
{
using T::f;
template<typename U> void f ();
using T::operator T*;
operator T * () const;
int frob ()
{
return f<int> (1);
}
T *quux ()
{
return operator T * ();
}
T *quux () const
{
return operator T * ();
}
};
struct Base
{
template <typename T> int f (T i)
{
return i;
}
operator Base *() const;
};
void foo ()
{
One<int> one;
Two<Base> two;
one = One<int> ();
two.frob ();
two.quux ();
const_cast <const Two<Base> &> (two).quux ();
}