aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c24
-rw-r--r--gcc/cp/method.c3
-rw-r--r--gcc/testsuite/g++.dg/overload/using5.C28
4 files changed, 53 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f98726e..b99a774 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2017-03-03 Jason Merrill <jason@redhat.com>
+
+ Core issues 2273 and 2277
+ * call.c (joust): Adjust using-declaration tiebreaker to handle
+ the intermediate base case.
+ * method.c (strip_inheriting_ctors): Just return the argument if
+ !flag_new_inheriting_ctors.
+
2017-03-03 Richard Biener <rguenther@suse.de>
PR c++/79825
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index dc629b9..5afec4f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -9735,20 +9735,26 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
}
}
- /* or, if not that, F2 is from a using-declaration, F1 is not, and the
- conversion sequences are equivalent.
- (proposed in http://lists.isocpp.org/core/2016/10/1142.php) */
+ /* F1 is a member of a class D, F2 is a member of a base class B of D, and
+ for all arguments the corresponding parameters of F1 and F2 have the same
+ type (CWG 2273/2277). */
if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
&& !DECL_CONV_FN_P (cand1->fn)
&& DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
&& !DECL_CONV_FN_P (cand2->fn))
{
- bool used1 = (DECL_INHERITED_CTOR (cand1->fn)
- || (BINFO_TYPE (cand1->access_path)
- != DECL_CONTEXT (cand1->fn)));
- bool used2 = (DECL_INHERITED_CTOR (cand2->fn)
- || (BINFO_TYPE (cand2->access_path)
- != DECL_CONTEXT (cand2->fn)));
+ tree base1 = DECL_CONTEXT (strip_inheriting_ctors (cand1->fn));
+ tree base2 = DECL_CONTEXT (strip_inheriting_ctors (cand2->fn));
+
+ bool used1 = false;
+ bool used2 = false;
+ if (base1 == base2)
+ /* No difference. */;
+ else if (DERIVED_FROM_P (base1, base2))
+ used1 = true;
+ else if (DERIVED_FROM_P (base2, base1))
+ used2 = true;
+
if (int diff = used2 - used1)
{
for (i = 0; i < len; ++i)
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index beb0a24..f6024cd 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -498,7 +498,8 @@ forward_parm (tree parm)
tree
strip_inheriting_ctors (tree dfn)
{
- gcc_assert (flag_new_inheriting_ctors);
+ if (!flag_new_inheriting_ctors)
+ return dfn;
tree fn = dfn;
while (tree inh = DECL_INHERITED_CTOR (fn))
{
diff --git a/gcc/testsuite/g++.dg/overload/using5.C b/gcc/testsuite/g++.dg/overload/using5.C
new file mode 100644
index 0000000..ad17c78
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/using5.C
@@ -0,0 +1,28 @@
+// Core issues 2273, 2277
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ A(int, int = 0);
+ static void f(int = 0);
+};
+
+struct B: A
+{
+ using A::A;
+ B(int);
+
+ using A::f;
+ static void f();
+};
+
+struct C: B {
+ using B::B;
+ using B::f;
+};
+
+int main()
+{
+ C c (42);
+ c.f();
+}