if (gimple_call_fn (use_stmt) == name)
lattice[index].merge (~EAF_NOCLOBBER);
- /* Return slot optimization would require bit of propagation;
- give up for now. */
- if (gimple_call_return_slot_opt_p (call)
- && gimple_call_lhs (call) != NULL_TREE
- && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call))))
- {
- if (dump_file)
- fprintf (dump_file, "%*s Unhandled return slot opt\n",
- depth * 4, "");
- lattice[index].merge (0);
- }
/* Recursion would require bit of propagation; give up for now. */
- else if (callee && !ipa && recursive_call_p (current_function_decl,
+ if (callee && !ipa && recursive_call_p (current_function_decl,
callee))
lattice[index].merge (0);
else
/* Handle *name = func (...). */
if (gimple_call_lhs (call)
&& memory_access_to (gimple_call_lhs (call), name))
- lattice[index].merge_direct_store ();
+ {
+ lattice[index].merge_direct_store ();
+ /* Return slot optimization passes address of
+ LHS to callee via hidden parameter and this
+ may make LHS to escape. See PR 98499. */
+ if (gimple_call_return_slot_opt_p (call)
+ && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call))))
+ lattice[index].merge (EAF_NOREAD | EAF_DIRECT);
+ }
/* We do not track accesses to the static chain (we could)
so give up. */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+struct S { int a; char b[20]; S(); S(S const&); };
+volatile int global;
+
+__attribute__ ((noinline,noclone))
+struct S noescape (int *b)
+{
+ struct S a;
+ a.a = b!=0;
+ global = 1;
+ return a;
+}
+
+void escape (struct S *p);
+
+__attribute__ ((noinline,noclone))
+int
+test(int *b)
+{
+ struct S s = noescape (b);
+ escape (&s);
+ return *b;
+}
+int test2()
+{
+ int b=1234;
+ test (&b);
+ return b;
+}
+// ipa-modref should analyze parameter B of test as noescape.
+// { dg-final { scan-tree-dump "return 1234" } }