[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:
parent
f1d42e85ad
commit
2139fd74f3
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
63
gcc/testsuite/g++.dg/lookup/pr87531-2.C
Normal file
63
gcc/testsuite/g++.dg/lookup/pr87531-2.C
Normal 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 ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user