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 name = OVL_NAME (fns); tree binfo_type = BINFO_TYPE (BASELINK_BINFO (baselink));
if (IDENTIFIER_CONV_OP_P (name)) binfo_type = tsubst (binfo_type, args, complain, in_decl);
name = make_conv_op_name (optype); bool dependent_p = binfo_type != BINFO_TYPE (BASELINK_BINFO (baselink));
baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); if (dependent_p)
if (!baselink)
{ {
if ((complain & tf_error) && constructor_name_p (name, qualifying_scope)) tree name = OVL_NAME (fns);
error ("cannot call constructor %<%T::%D%> directly", if (IDENTIFIER_CONV_OP_P (name))
qualifying_scope, name); name = make_conv_op_name (optype);
return error_mark_node;
if (name == complete_dtor_identifier)
/* Treat as-if non-dependent below. */
dependent_p = false;
baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
if (!baselink)
{
if ((complain & tf_error)
&& constructor_name_p (name, qualifying_scope))
error ("cannot call constructor %<%T::%D%> directly",
qualifying_scope, name);
return error_mark_node;
}
if (BASELINK_P (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 a single function, mark it as used at this point.
(If it lookup found multiple functions the one selected later by (If lookup found multiple functions the one selected later by
overload resolution will be marked as used at that point.) */ overload resolution will be marked as used at that point.) */
if (BASELINK_P (baselink))
fns = BASELINK_FUNCTIONS (baselink);
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