Now that pranges can have invariants in it, we need to make sure the
return value range does not record non-ipa invariants; otherwise we
might prop the address of a local variable from one function to
another.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/125857

gcc/ChangeLog:

        * ipa-prop.cc (ipa_record_return_value_range_1): Don't record
        pranges which have non ipa-invariants in it.

gcc/testsuite/ChangeLog:

        * gcc.dg/pr125857-1.c: New test.

Signed-off-by: Andrew Pinski <[email protected]>
---
 gcc/ipa-prop.cc                   | 17 +++++++++++++++++
 gcc/testsuite/gcc.dg/pr125857-1.c | 16 ++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr125857-1.c

diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 79b59a6a76f..3e05f659f30 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -5986,6 +5986,23 @@ ipa_prop_write_jump_functions (void)
 static void
 ipa_record_return_value_range_1 (cgraph_node *n, value_range val)
 {
+  // Remove local invariant from return values.
+  if (is_a<prange> (val))
+    {
+      const prange &pr = as_a <prange> (val);
+      tree t = pr.pt_invariant ();
+      if (t && !is_gimple_ip_invariant (t))
+        {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "Could not record return range of %s:", 
n->dump_name ());
+             val.dump (dump_file);
+             fprintf (dump_file, "\n");
+             fprintf (dump_file, "Because uses non ipa invariant\n");
+           }
+         return;
+        }
+    }
   if (!ipa_return_value_sum)
     {
       if (!ipa_vr_hash_table)
diff --git a/gcc/testsuite/gcc.dg/pr125857-1.c 
b/gcc/testsuite/gcc.dg/pr125857-1.c
new file mode 100644
index 00000000000..1904db7e319
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr125857-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* PR tree-optimization/125857 */
+
+/* Make sure we don't ICE when returning the address to a local variable
+   and using it in the other function.  */
+int *a, **b = &a, c;
+int *d() {
+  int e, *f = &e;
+  for (; c; c++)
+    __builtin_abort();
+  if (!b)
+    __builtin_abort();
+  return f; /* { dg-warning "function may return address of local variable" } 
*/
+}
+int main() { *b = d(); }
-- 
2.43.0

Reply via email to