fetchurl can't be used on generated patches this way. The hash doesn't match anymore. fetchpatch would be an alternative.
93 lines
2.9 KiB
Diff
93 lines
2.9 KiB
Diff
From de31f5445b12fd9ab9969dc536d821fe6f0edad0 Mon Sep 17 00:00:00 2001
|
|
From: Patrick Palka <ppalka@redhat.com>
|
|
Date: Mon, 21 Jun 2021 07:54:26 -0400
|
|
Subject: [PATCH] c++: conversion to base of vbase in NSDMI [PR80431]
|
|
|
|
The delayed processing of conversions to a virtual base in an NSDMI
|
|
assumes the target base type is a (possibly indirect) virtual base of
|
|
the current class, but the target base type could also be a base of a
|
|
virtual base, as in the testcase below. Since such a base isn't a part
|
|
of CLASSTYPE_VBASECLASSES, we end up miscompiling the testcase due to
|
|
the call to build_base_path (with binfo=NULL_TREE) silently returning
|
|
error_mark_node. Fix this by using convert_to_base to build the
|
|
conversion instead.
|
|
|
|
PR c++/80431
|
|
|
|
gcc/cp/ChangeLog:
|
|
|
|
* tree.c (bot_replace): Use convert_to_base to build the
|
|
conversion to the (morally) virtual base.
|
|
|
|
gcc/testsuite/ChangeLog:
|
|
|
|
* g++.dg/cpp0x/nsdmi-virtual1a.C: New test.
|
|
---
|
|
gcc/cp/tree.c | 14 ++++------
|
|
gcc/testsuite/g++.dg/cpp0x/nsdmi-virtual1a.C | 28 ++++++++++++++++++++
|
|
2 files changed, 33 insertions(+), 9 deletions(-)
|
|
create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-virtual1a.C
|
|
|
|
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
|
|
index fec5afaa2be..297da2b1550 100644
|
|
--- a/gcc/cp/tree.c
|
|
+++ b/gcc/cp/tree.c
|
|
@@ -3242,15 +3242,11 @@ bot_replace (tree* t, int* /*walk_subtrees*/, void* data_)
|
|
else if (TREE_CODE (*t) == CONVERT_EXPR
|
|
&& CONVERT_EXPR_VBASE_PATH (*t))
|
|
{
|
|
- /* In an NSDMI build_base_path defers building conversions to virtual
|
|
- bases, and we handle it here. */
|
|
- tree basetype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (*t)));
|
|
- vec<tree, va_gc> *vbases = CLASSTYPE_VBASECLASSES (current_class_type);
|
|
- int i; tree binfo;
|
|
- FOR_EACH_VEC_SAFE_ELT (vbases, i, binfo)
|
|
- if (BINFO_TYPE (binfo) == basetype)
|
|
- break;
|
|
- *t = build_base_path (PLUS_EXPR, TREE_OPERAND (*t, 0), binfo, true,
|
|
+ /* In an NSDMI build_base_path defers building conversions to morally
|
|
+ virtual bases, and we handle it here. */
|
|
+ tree basetype = TREE_TYPE (*t);
|
|
+ *t = convert_to_base (TREE_OPERAND (*t, 0), basetype,
|
|
+ /*check_access=*/false, /*nonnull=*/true,
|
|
tf_warning_or_error);
|
|
}
|
|
|
|
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-virtual1a.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-virtual1a.C
|
|
new file mode 100644
|
|
index 00000000000..dc847cc16e5
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-virtual1a.C
|
|
@@ -0,0 +1,28 @@
|
|
+// PR c++/80431
|
|
+// { dg-do run { target c++11 } }
|
|
+
|
|
+// A variant of nsdmi-virtual1.C where A is only a morally virtual base of B.
|
|
+
|
|
+struct A
|
|
+{
|
|
+ A(): i(42) { }
|
|
+ int i;
|
|
+ int f() { return i; }
|
|
+};
|
|
+
|
|
+struct D : A { int pad; };
|
|
+
|
|
+struct B : virtual D
|
|
+{
|
|
+ int j = i + f();
|
|
+ int k = A::i + A::f();
|
|
+};
|
|
+
|
|
+struct C: B { int pad; };
|
|
+
|
|
+int main()
|
|
+{
|
|
+ C c;
|
|
+ if (c.j != 84 || c.k != 84)
|
|
+ __builtin_abort();
|
|
+}
|
|
--
|
|
2.31.1
|
|
|