diff mbox

Fix PR ipa/65908.

Message ID 5555B0A1.1060702@suse.cz
State New
Headers show

Commit Message

Martin Liška May 15, 2015, 8:38 a.m. UTC
Hello.

Following patch is fix for GCC-5 branch for PR ipa/65908, was tested on x86_64-linux-pc, as well as bootstrapped.
As soon as the patch is applied, I'm going to send the similar patch for trunk.

Ready for 5 branch?
Thanks,
Martin


gcc/testsuite/ChangeLog:

2015-05-12  Martin Liska  <mliska@suse.cz>

	* g++.dg/ipa/pr65908.C: New test.

gcc/ChangeLog:

2015-05-12  Martin Liska  <mliska@suse.cz>

	PR ipa/65908
	* ipa-icf.c (sem_function::equals_private): Always compare argument
	type got from TYPE_ARG_TYPES.
	(sem_function::compatible_parm_types_p): New function.
	(sem_function::equals_wpa): Use the function.
	(sem_function::equals_private): Likewise.
	(sem_function::parse_tree_args): Handle case where we have a different
	number of arguments.
	* ipa-icf.h (sem_function::compatible_parm_types_p): Declare new
	function.
---
  gcc/ipa-icf.c                      | 63 +++++++++++++++++++++++---------------
  gcc/ipa-icf.h                      |  3 ++
  gcc/testsuite/g++.dg/ipa/pr65908.C | 26 ++++++++++++++++
  3 files changed, 68 insertions(+), 24 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/ipa/pr65908.C

Comments

Jakub Jelinek May 15, 2015, 10:38 a.m. UTC | #1
On Fri, May 15, 2015 at 10:38:57AM +0200, Martin Liška wrote:
> Following patch is fix for GCC-5 branch for PR ipa/65908, was tested on x86_64-linux-pc, as well as bootstrapped.
> As soon as the patch is applied, I'm going to send the similar patch for trunk.

I'll leave the review to Honza or Richi, just a few nits:
1) it should go to the trunk first, then to GCC-5 branch

> --- a/gcc/ipa-icf.c
> +++ b/gcc/ipa-icf.c
> @@ -417,6 +417,33 @@ bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
>    return true;
>  }
> +/* Return true if DECL_ARGUMENT types are valid to be merged.  */

Please add another newline between } and the comment.
> --- a/gcc/ipa-icf.h
> +++ b/gcc/ipa-icf.h
> @@ -364,6 +364,9 @@ private:
>    bool equals_private (sem_item *item,
>  		       hash_map <symtab_node *, sem_item *> &ignored_nodes);
> +  /* Return true if DECL_ARGUMENT types are valid to be merged.  */
> +  bool compatible_parm_types_p ();
> +
>    /* Returns true if tree T can be compared as a handled component.  */
>    static bool icf_handled_component_p (tree t);

And here should be an empty line above the Return true if ... comment
too.  Though, I wonder how this can apply cleanly to the current 5 branch,
because there is an empty newline in between equals_private and the comment
above icf_handled_component_p.

> diff --git a/gcc/testsuite/g++.dg/ipa/pr65908.C b/gcc/testsuite/g++.dg/ipa/pr65908.C
> new file mode 100644
> index 0000000..c1884ab
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ipa/pr65908.C
> @@ -0,0 +1,26 @@
> +// PR ipa/65908
> +// { dg-options "-O2 -fPIC" }
> +// { dg-do compile { target { { fpic } } } }

Perhaps
// PR ipa/65908
// { dg-do compile }
// { dg-options "-O2" }
// { dg-additional-options "-fPIC" { target fpic } }
instead?

	Jakub
diff mbox

Patch

diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index b902373..e2da19e 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -417,6 +417,33 @@  bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
    return true;
  }
  
+/* Return true if DECL_ARGUMENT types are valid to be merged.  */
+
+bool
+sem_function::compatible_parm_types_p ()
+{
+  tree parm1, parm2;
+
+  for (parm1 = DECL_ARGUMENTS (decl),
+       parm2 = DECL_ARGUMENTS (m_compared_func->decl);
+       parm1 && parm2; parm1 = DECL_CHAIN (parm1), parm2 = DECL_CHAIN (parm2))
+  {
+    if (POINTER_TYPE_P (parm1)
+	&& (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2)))
+      return return_false_with_msg ("argument restrict flag mismatch");
+    /* nonnull_arg_p implies non-zero range to REFERENCE types.  */
+    if (POINTER_TYPE_P (parm1)
+	&& TREE_CODE (parm1) != TREE_CODE (parm2)
+	&& opt_for_fn (decl, flag_delete_null_pointer_checks))
+      return return_false_with_msg ("pointer wrt reference mismatch");
+  }
+
+  if (parm1 || parm2)
+    return return_false ();
+
+  return true;
+}
+
  /* Fast equality function based on knowledge known in WPA.  */
  
  bool
@@ -520,12 +547,12 @@  sem_function::equals_wpa (sem_item *item,
        if (!func_checker::compatible_types_p (arg_types[i],
  					     m_compared_func->arg_types[i]))
  	return return_false_with_msg ("argument type is different");
-      if (POINTER_TYPE_P (arg_types[i])
-	  && (TYPE_RESTRICT (arg_types[i])
-	      != TYPE_RESTRICT (m_compared_func->arg_types[i])))
-	return return_false_with_msg ("argument restrict flag mismatch");
      }
  
+  /* For functions with !prototype_p, we have to compare DECL_ARGUMENTS.  */
+  if (!compatible_parm_types_p ())
+    return return_false ();
+
    if (node->num_references () != item->node->num_references ())
      return return_false_with_msg ("different number of references");
  
@@ -743,9 +770,12 @@  sem_function::equals_private (sem_item *item,
    for (arg1 = DECL_ARGUMENTS (decl),
         arg2 = DECL_ARGUMENTS (m_compared_func->decl);
         arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
-    if (!m_checker->compare_decl (arg1, arg2))
+    if (!arg2 || !m_checker->compare_decl (arg1, arg2))
        return return_false ();
  
+  if (!compatible_parm_types_p ())
+    return return_false ();
+
    /* Fill-up label dictionary.  */
    for (unsigned i = 0; i < bb_sorted.length (); ++i)
      {
@@ -1481,30 +1511,15 @@  sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
  void
  sem_function::parse_tree_args (void)
  {
-  tree result;
-
    if (arg_types.exists ())
      arg_types.release ();
  
    arg_types.create (4);
-  tree fnargs = DECL_ARGUMENTS (decl);
+  tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
+  for (tree parm = type; parm; parm = TREE_CHAIN (parm))
+    arg_types.safe_push (TREE_VALUE (parm));
  
-  for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
-    arg_types.safe_push (DECL_ARG_TYPE (parm));
-
-  /* Function result type.  */
-  result = DECL_RESULT (decl);
-  result_type = result ? TREE_TYPE (result) : NULL;
-
-  /* During WPA, we can get arguments by following method.  */
-  if (!fnargs)
-    {
-      tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
-      for (tree parm = type; parm; parm = TREE_CHAIN (parm))
-	arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
-
-      result_type = TREE_TYPE (TREE_TYPE (decl));
-    }
+  result_type = TREE_TYPE (TREE_TYPE (decl));
  }
  
  /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h
index 7eb9f27..d6dabfe 100644
--- a/gcc/ipa-icf.h
+++ b/gcc/ipa-icf.h
@@ -364,6 +364,9 @@  private:
    bool equals_private (sem_item *item,
  		       hash_map <symtab_node *, sem_item *> &ignored_nodes);
  
+  /* Return true if DECL_ARGUMENT types are valid to be merged.  */
+  bool compatible_parm_types_p ();
+
    /* Returns true if tree T can be compared as a handled component.  */
    static bool icf_handled_component_p (tree t);
  
diff --git a/gcc/testsuite/g++.dg/ipa/pr65908.C b/gcc/testsuite/g++.dg/ipa/pr65908.C
new file mode 100644
index 0000000..c1884ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr65908.C
@@ -0,0 +1,26 @@ 
+// PR ipa/65908
+// { dg-options "-O2 -fPIC" }
+// { dg-do compile { target { { fpic } } } }
+
+class A
+{
+  A (A &);
+};
+class B
+{
+  const A &m_fn1 () const;
+};
+class C
+{
+  A m_fn2 () const;
+};
+A
+C::m_fn2 () const
+{
+  throw 0;
+}
+const A &
+B::m_fn1 () const
+{
+  throw 0;
+}