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 <mli...@suse.cz>
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  <mli...@suse.cz>

	PR ipa/82352
	* ipa-icf.c (sem_function::merge): Do not cross comdat boundary.

gcc/testsuite/ChangeLog:

2018-01-03  Martin Liska  <mli...@suse.cz>

	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

Reply via email to