While chasing two testsuite fails for -Os this wrong-code bug surfaced.
Fix tested on x86_64-linux/darwin.  OK for trunk / backports?
thanks
Iain

--- 8< ---

For Darwin, at least, when -Os is selected we attempt to declone cdtors
since the platform does not support strong symbol aliases the clones
are emitted verbatim, leading to larger binaries.

The unified cdtor is a private implementational detail local to a TU
and so we should not emit a thunk if that will not be emitted.

Likewise, a  thunk and the unified body must be selected together at
link time; for a vague-linkage cdtor COMDAT groups support this but,
without COMDAT, there is no guarantee and so we have to decline the
declone and emit ordinary clones instead.

gcc/cp/ChangeLog:

        * optimize.cc (maybe_thunk_body): Decline declone for targets
        without COMDAT when the item is vague-linkage.

gcc/testsuite/ChangeLog:

        * g++.dg/opt/declone4.C: New test.
        * g++.dg/opt/declone5.C: New test.

Signed-off-by: Iain Sandoe <[email protected]>
---
 gcc/cp/optimize.cc                  |  8 +++++++
 gcc/testsuite/g++.dg/opt/declone4.C | 37 +++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/opt/declone5.C | 33 +++++++++++++++++++++++++
 3 files changed, 78 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/opt/declone4.C
 create mode 100644 gcc/testsuite/g++.dg/opt/declone5.C

diff --git a/gcc/cp/optimize.cc b/gcc/cp/optimize.cc
index 0afeefd5704..d81e8e4ba15 100644
--- a/gcc/cp/optimize.cc
+++ b/gcc/cp/optimize.cc
@@ -287,6 +287,14 @@ maybe_thunk_body (tree fn, bool force)
   if (ctor_omit_inherited_parms (fns[0]))
     return 0;
 
+  /* A thunk and the unified body must be selected together at link time;
+     for a vague-linkage cdtor COMDAT groups support this.  Without COMDAT
+     there is no guarantee and so we have to decline and emit ordinary clones
+     instead.  FORCE means the body must not be copied at all, so it is still
+     honoured.  */
+  if (!force && DECL_WEAK (fn) && !HAVE_COMDAT_GROUP)
+    return 0;
+
   /* Don't diagnose deprecated or unavailable cdtors just because they
      have thunks emitted for them.  */
   auto du = make_temp_override (deprecated_state,
diff --git a/gcc/testsuite/g++.dg/opt/declone4.C 
b/gcc/testsuite/g++.dg/opt/declone4.C
new file mode 100644
index 00000000000..1d3f87d3126
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/declone4.C
@@ -0,0 +1,37 @@
+// { dg-do run }
+// { dg-options "-fdeclone-ctor-dtor -save-temps" }
+
+// A cdtor whose unified body this translation unit does emit should be
+// decloned.  The C1/C2 clones become thunks and the unified C4 body is
+// emitted either private to the translation unit here, or to the COMDAT
+// group on targets that support them.
+
+struct V { int v; V (); };
+V::V () : v (1) {}
+
+struct B : virtual V
+{
+  int n;
+  B (int);
+};
+
+B::B (int x) : n (x * 3 + 1) {}
+
+struct D : B                           // uses B::C2
+{
+  D (int x) : B (x) {}
+};
+
+B *p;
+D *q;
+
+int
+main ()
+{
+  p = new B (2);                       // uses B::C1
+  q = new D (5);
+  return !(p->n == 7 && q->n == 16 && p->v == 1 && q->v == 1);
+}
+
+// { dg-final { scan-assembler "_ZN1BC4Ei" } }
+// { dg-final { scan-assembler-not "globl\[^\n\]*_ZN1BC4Ei" } }
diff --git a/gcc/testsuite/g++.dg/opt/declone5.C 
b/gcc/testsuite/g++.dg/opt/declone5.C
new file mode 100644
index 00000000000..d714f99de40
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/declone5.C
@@ -0,0 +1,33 @@
+// { dg-do run }
+// { dg-options "-fdeclone-ctor-dtor -save-temps" }
+
+// We cannot emit a thunk to a unified cdtor on targets without comdat
+// support, since the thunk and the target must be selected together for
+// vague linkage.
+
+struct V { int v; V () : v (1) {} };
+
+template <typename T>
+struct B : virtual V
+{
+  T n;
+  B (T x) : n (x * 3 + 1) {}
+};
+
+struct D : B<int>                      // uses B<int>::C2
+{
+  D (int x) : B<int> (x) {}
+};
+
+B<int> *p;
+D *q;
+
+int
+main ()
+{
+  p = new B<int> (2);                  // uses B<int>::C1
+  q = new D (5);
+  return !(p->n == 7 && q->n == 16 && p->v == 1 && q->v == 1);
+}
+
+// { dg-final { scan-assembler-not "_ZN1BIiEC4Ei" { target { ! comdat_group } 
} } }
-- 
2.50.1 (Apple Git-155)

Reply via email to