On 01/03/2018 02:40 PM, Jan Hubicka wrote:
>>>> + if (!original->in_same_comdat_group_p (alias))
>>>> + {
>>>> + if (dump_file)
>>>> + fprintf (dump_file, "Not unifying; alias cannot be created; "
>>>> + "across comdat group boundary\n\n");
>>>> +
>>>> + return false;
>>>> + }
>>>
>>> Wasn't we supposed to do the wrapper in this case?
>>>
>>> Honza
>>>
>>
>> We attempt to do a wrapper, but even with wrapper we cannot introduce such
>> call
>> crossing the boundary. Proper message should be probably:
>>
>> "Not unifying; alias nor wrapper cannot be created; across comdat group
>> boundary"
>
> If the symbol we are calling is one exported from comdat, it shoud work fine
> as long as we produce gimple thunk and it the symbol comdat exports.
> Of course producing call from one comdat to another may close comdat loop
> (which we handle elsewhere, so i assume original is comdat and alias is not)
>
> I see in the PR is the split part of comdat which is comdat local, so perhaps
> we want to check that original is not comdat local in addition to your current
> check?
Ok, you understand problematic of comdats more than me. I will test and install
patch with the check added.
Thanks,
Martin
>
> Honza
>>
>> Martin
>From 707e88333778b306f66c1bf683838b1a7bb4f737 Mon Sep 17 00:00:00 2001
From: marxin <[email protected]>
Date: Wed, 3 Jan 2018 11:10:18 +0100
Subject: [PATCH] Be careful about comdat boundary in ICF (PR ipa/82352).
gcc/ChangeLog:
2018-01-03 Martin Liska <[email protected]>
PR ipa/82352
* ipa-icf.c (sem_function::merge): Do not cross comdat boundary.
gcc/testsuite/ChangeLog:
2018-01-03 Martin Liska <[email protected]>
PR ipa/82352
* g++.dg/ipa/pr82352.C: New test.
---
gcc/ipa-icf.c | 11 +++++
gcc/testsuite/g++.dg/ipa/pr82352.C | 93 ++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/ipa/pr82352.C
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index a8d3b800318..e17c4292392 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -1113,6 +1113,17 @@ sem_function::merge (sem_item *alias_item)
return false;
}
+ if (!original->in_same_comdat_group_p (alias)
+ || original->comdat_local_p ())
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Not unifying; alias nor wrapper cannot be created; "
+ "across comdat group boundary\n\n");
+
+ return false;
+ }
+
/* See if original is in a section that can be discarded if the main
symbol is not used. */
diff --git a/gcc/testsuite/g++.dg/ipa/pr82352.C b/gcc/testsuite/g++.dg/ipa/pr82352.C
new file mode 100644
index 00000000000..c044345a486
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr82352.C
@@ -0,0 +1,93 @@
+// PR ipa/82352
+// { dg-do compile }
+// { dg-options "-O2" }
+
+typedef long unsigned int size_t;
+
+class A
+{
+public :
+ typedef enum { Zero = 0, One = 1 } tA;
+ A(tA a) { m_a = a; }
+
+private :
+ tA m_a;
+};
+
+class B
+{
+public :
+ void *operator new(size_t t) { return (void*)(42); };
+};
+
+class C
+{
+public:
+ virtual void ffff () = 0;
+};
+
+class D
+{
+ public :
+ virtual void g() = 0;
+ virtual void h() = 0;
+};
+
+template<class T> class IIII: public T, public D
+{
+public:
+ void ffff()
+ {
+ if (!m_i2) throw A(A::One);
+ };
+
+ void h()
+ {
+ if (m_i2) throw A(A::Zero);
+ }
+
+protected:
+ virtual void g()
+ {
+ if (m_i1 !=0) throw A(A::Zero);
+ };
+
+private :
+ int m_i1;
+ void *m_i2;
+};
+
+class E
+{
+private:
+ size_t m_e;
+ static const size_t Max;
+
+public:
+ E& i(size_t a, size_t b, size_t c)
+ {
+ if ((a > Max) || (c > Max)) throw A(A::Zero );
+ if (a + b > m_e) throw A(A::One );
+ return (*this);
+ }
+
+ inline E& j(const E &s)
+ {
+ return i(0,0,s.m_e);
+ }
+};
+
+class F : public C { };
+class G : public C { };
+class HHHH : public B, public F, public G { };
+
+void k()
+{
+ new IIII<HHHH>();
+}
+
+void l()
+{
+ E e1, e2;
+ e1.j(e2);
+}
--
2.14.3