aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-12-13 12:40:45 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-12-13 12:40:45 +0000
commit2b031ef48e365e256495a3e6d226a59f2290444f (patch)
tree0c16bd0aea4e78482c77d43b41b8af8cf638f023
parent0c8af82a15cedbc181df3f0ec09622adffb9ef53 (diff)
downloadgcc-2b031ef48e365e256495a3e6d226a59f2290444f.zip
gcc-2b031ef48e365e256495a3e6d226a59f2290444f.tar.gz
gcc-2b031ef48e365e256495a3e6d226a59f2290444f.tar.bz2
[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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c62
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/pr71826.C13
4 files changed, 58 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 23dcc3f..d298315 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+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>
* decl.c (value_dependent_init_p): Check the type of a CONSTRUCTOR.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b5be980..282dd14 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
- expression on the left-hand side of the "." or "->" operator. A
- baselink indicates a function from a base class. Both the
- BASELINK_ACCESS_BINFO and the base class referenced may indicate
- 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. */
+ expression on the left-hand side of the "." or "->" operator. We
+ only do the lookup if we had a dependent BASELINK. Otherwise we
+ adjust it onto the instantiated heirarchy. */
static tree
tsubst_baselink (tree baselink, tree object_type,
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));
qualifying_scope = tsubst (qualifying_scope, args, complain, in_decl);
@@ -14443,24 +14439,43 @@ tsubst_baselink (tree baselink, tree object_type,
complain, in_decl);
}
- tree name = OVL_NAME (fns);
- if (IDENTIFIER_CONV_OP_P (name))
- name = make_conv_op_name (optype);
+ 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));
- baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
- if (!baselink)
+ if (dependent_p)
{
- if ((complain & tf_error) && constructor_name_p (name, qualifying_scope))
- error ("cannot call constructor %<%T::%D%> directly",
- qualifying_scope, name);
- return error_mark_node;
+ tree name = OVL_NAME (fns);
+ if (IDENTIFIER_CONV_OP_P (name))
+ 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);
+ 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 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.) */
- if (BASELINK_P (baselink))
- fns = BASELINK_FUNCTIONS (baselink);
if (!template_id_p && !really_overloaded_fn (fns)
&& !mark_used (OVL_FIRST (fns), complain) && !(complain & tf_error))
return error_mark_node;
@@ -14470,8 +14485,7 @@ tsubst_baselink (tree baselink, tree object_type,
/* Add back the template arguments, if present. */
if (template_id_p)
BASELINK_FUNCTIONS (baselink)
- = build2 (TEMPLATE_ID_EXPR, unknown_type_node,
- BASELINK_FUNCTIONS (baselink), template_args);
+ = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fns, template_args);
/* Update the conversion operator type. */
BASELINK_OPTYPE (baselink) = optype;
@@ -14480,12 +14494,12 @@ tsubst_baselink (tree baselink, tree object_type,
if (!object_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,
qualifying_scope,
object_type);
- if (!qualified)
+ if (!qualified_p)
/* We need to call adjust_result_of_qualified_name_lookup in case the
destructor names a base class, but we unset BASELINK_QUALIFIED_P
so that we still get virtual function binding. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2a863db..7159ab9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
PR tree-optimization/83298
diff --git a/gcc/testsuite/g++.dg/template/pr71826.C b/gcc/testsuite/g++.dg/template/pr71826.C
index 753fd7e..45d6443 100644
--- a/gcc/testsuite/g++.dg/template/pr71826.C
+++ b/gcc/testsuite/g++.dg/template/pr71826.C
@@ -1,11 +1,16 @@
-// PR c++/71826
+// PR c++/71826 ICE
+// PR c++/15272 Invalid ambiguous
// { dg-do compile }
-template <class> struct A { int i; }; // { dg-message "note" }
-struct B { void i () {} }; // { dg-message "note" }
+// 15272, we don't search the dependent base
+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
{
- void f () { i (); } // { dg-error "is ambiguous" }
+ void f () { i (); } // here
};
int