Commit 2b031ef4 by Nathan Sidwell Committed by Nathan Sidwell

[PR C++/15272] lookups with ambiguating dependent base

https://gcc.gnu.org/ml/gcc-patches/2017-12/msg00766.html
	PR c++/15272
	* pt.c (tsubst_baselink): Don't repeat the lookup for
	non-dependent baselinks.

	PR c++/15272
	* g++.dg/template/pr71826.C: Adjust for 15272 fix.

From-SVN: r255605
parent 0c8af82a
2017-12-13 Nathan Sidwell <nathan@acm.org>
PR c++/15272
* pt.c (tsubst_baselink): Don't repeat the lookup for
non-dependent baselinks.
2017-12-12 Jason Merrill <jason@redhat.com> 2017-12-12 Jason Merrill <jason@redhat.com>
* decl.c (value_dependent_init_p): Check the type of a CONSTRUCTOR. * decl.c (value_dependent_init_p): Check the type of a CONSTRUCTOR.
......
...@@ -14411,19 +14411,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -14411,19 +14411,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
} }
/* tsubst a BASELINK. OBJECT_TYPE, if non-NULL, is the type of the /* tsubst a BASELINK. OBJECT_TYPE, if non-NULL, is the type of the
expression on the left-hand side of the "." or "->" operator. A expression on the left-hand side of the "." or "->" operator. We
baselink indicates a function from a base class. Both the only do the lookup if we had a dependent BASELINK. Otherwise we
BASELINK_ACCESS_BINFO and the base class referenced may indicate adjust it onto the instantiated heirarchy. */
bases of the template class, rather than the instantiated class.
In addition, lookups that were not ambiguous before may be
ambiguous now. Therefore, we perform the lookup again. */
static tree static tree
tsubst_baselink (tree baselink, tree object_type, tsubst_baselink (tree baselink, tree object_type,
tree args, tsubst_flags_t complain, tree in_decl) tree args, tsubst_flags_t complain, tree in_decl)
{ {
bool qualified = BASELINK_QUALIFIED_P (baselink); bool qualified_p = BASELINK_QUALIFIED_P (baselink);
tree qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink)); tree qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink));
qualifying_scope = tsubst (qualifying_scope, args, complain, in_decl); qualifying_scope = tsubst (qualifying_scope, args, complain, in_decl);
...@@ -14443,24 +14439,43 @@ tsubst_baselink (tree baselink, tree object_type, ...@@ -14443,24 +14439,43 @@ tsubst_baselink (tree baselink, tree object_type,
complain, in_decl); complain, in_decl);
} }
tree binfo_type = BINFO_TYPE (BASELINK_BINFO (baselink));
binfo_type = tsubst (binfo_type, args, complain, in_decl);
bool dependent_p = binfo_type != BINFO_TYPE (BASELINK_BINFO (baselink));
if (dependent_p)
{
tree name = OVL_NAME (fns); tree name = OVL_NAME (fns);
if (IDENTIFIER_CONV_OP_P (name)) if (IDENTIFIER_CONV_OP_P (name))
name = make_conv_op_name (optype); name = make_conv_op_name (optype);
if (name == complete_dtor_identifier)
/* Treat as-if non-dependent below. */
dependent_p = false;
baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
if (!baselink) if (!baselink)
{ {
if ((complain & tf_error) && constructor_name_p (name, qualifying_scope)) if ((complain & tf_error)
&& constructor_name_p (name, qualifying_scope))
error ("cannot call constructor %<%T::%D%> directly", error ("cannot call constructor %<%T::%D%> directly",
qualifying_scope, name); qualifying_scope, name);
return error_mark_node; return error_mark_node;
} }
/* If lookup found a single function, mark it as used at this point.
(If it lookup found multiple functions the one selected later by
overload resolution will be marked as used at that point.) */
if (BASELINK_P (baselink)) if (BASELINK_P (baselink))
fns = BASELINK_FUNCTIONS (baselink); fns = BASELINK_FUNCTIONS (baselink);
}
else
{
gcc_assert (optype == BASELINK_OPTYPE (baselink));
/* We're going to overwrite pieces below, make a duplicate. */
baselink = copy_node (baselink);
}
/* If lookup found a single function, mark it as used at this point.
(If lookup found multiple functions the one selected later by
overload resolution will be marked as used at that point.) */
if (!template_id_p && !really_overloaded_fn (fns) if (!template_id_p && !really_overloaded_fn (fns)
&& !mark_used (OVL_FIRST (fns), complain) && !(complain & tf_error)) && !mark_used (OVL_FIRST (fns), complain) && !(complain & tf_error))
return error_mark_node; return error_mark_node;
...@@ -14470,8 +14485,7 @@ tsubst_baselink (tree baselink, tree object_type, ...@@ -14470,8 +14485,7 @@ tsubst_baselink (tree baselink, tree object_type,
/* Add back the template arguments, if present. */ /* Add back the template arguments, if present. */
if (template_id_p) if (template_id_p)
BASELINK_FUNCTIONS (baselink) BASELINK_FUNCTIONS (baselink)
= build2 (TEMPLATE_ID_EXPR, unknown_type_node, = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fns, template_args);
BASELINK_FUNCTIONS (baselink), template_args);
/* Update the conversion operator type. */ /* Update the conversion operator type. */
BASELINK_OPTYPE (baselink) = optype; BASELINK_OPTYPE (baselink) = optype;
...@@ -14480,12 +14494,12 @@ tsubst_baselink (tree baselink, tree object_type, ...@@ -14480,12 +14494,12 @@ tsubst_baselink (tree baselink, tree object_type,
if (!object_type) if (!object_type)
object_type = current_class_type; object_type = current_class_type;
if (qualified || name == complete_dtor_identifier) if (qualified_p || !dependent_p)
{ {
baselink = adjust_result_of_qualified_name_lookup (baselink, baselink = adjust_result_of_qualified_name_lookup (baselink,
qualifying_scope, qualifying_scope,
object_type); object_type);
if (!qualified) if (!qualified_p)
/* We need to call adjust_result_of_qualified_name_lookup in case the /* We need to call adjust_result_of_qualified_name_lookup in case the
destructor names a base class, but we unset BASELINK_QUALIFIED_P destructor names a base class, but we unset BASELINK_QUALIFIED_P
so that we still get virtual function binding. */ so that we still get virtual function binding. */
......
2017-12-13 Nathan Sidwell <nathan@acm.org>
PR c++/15272
* g++.dg/template/pr71826.C: Adjust for 15272 fix.
2017-12-12 Jeff Law <law@redhat.com> 2017-12-12 Jeff Law <law@redhat.com>
PR tree-optimization/83298 PR tree-optimization/83298
......
// PR c++/71826 // PR c++/71826 ICE
// PR c++/15272 Invalid ambiguous
// { dg-do compile } // { dg-do compile }
template <class> struct A { int i; }; // { dg-message "note" } // 15272, we don't search the dependent base
struct B { void i () {} }; // { dg-message "note" } template <class> struct A { int i; };
// We bind to B::i at parse time
struct B { void i () {} };
template <class T> struct C : A <T>, B template <class T> struct C : A <T>, B
{ {
void f () { i (); } // { dg-error "is ambiguous" } void f () { i (); } // here
}; };
int int
......
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