This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR59626, _FORTIFY_SOURCE wrappers and LTO
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Richard Biener <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org, Jan Hubicka <hubicka at ucw dot cz>, Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 4 Apr 2014 08:18:26 +0200
- Subject: Re: [PATCH] Fix PR59626, _FORTIFY_SOURCE wrappers and LTO
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LSU dot 2 dot 11 dot 1403241048220 dot 26135 at zhemvz dot fhfr dot qr>
Hi,
here is an updated version of my earlier ipa.c change. It turns out that the
problem was that I did not drop always_inline.
In this version I just drop always_inline attribute on all functions whose body
is removed. The patch will affect non-LTO compilation, too, but IMO only by
making us to not inline&diagnose the cases where indirect call to always inline
is turned direct in between early opts and inline. Does that seem acceptable?
(I personally would preffer this over inventing yet another way to special case
always_inline for LTO only; we never made any strong promises on always_inline
and indirect calls)
Honza
* lto-cgraph.c (input_overwrite_node): Check that partitioning
flags are set only during streaming.
* ipa.c (process_references, walk_polymorphic_call_targets,
symtab_remove_unreachable_nodes): Drop bodies of always inline
after early inlining.
(symtab_remove_unreachable_nodes): Remove always_inline attribute.
* gcc.dg/lto/pr59626_0.c: New testcase.
* gcc.dg/lto/pr59626_1.c: New testcase.
Index: lto-cgraph.c
===================================================================
--- lto-cgraph.c (revision 209062)
+++ lto-cgraph.c (working copy)
@@ -1001,6 +1001,9 @@ input_overwrite_node (struct lto_file_de
node->thunk.thunk_p = bp_unpack_value (bp, 1);
node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN);
+ gcc_assert (flag_ltrans
+ || (!node->in_other_partition
+ && !node->used_from_other_partition));
}
/* Return string alias is alias of. */
@@ -1169,6 +1172,9 @@ input_varpool_node (struct lto_file_decl
node->same_comdat_group = (symtab_node *) (intptr_t) ref;
node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN);
+ gcc_assert (flag_ltrans
+ || (!node->in_other_partition
+ && !node->used_from_other_partition));
return node;
}
Index: ipa.c
===================================================================
--- ipa.c (revision 209062)
+++ ipa.c (working copy)
@@ -139,7 +139,10 @@ process_references (struct ipa_ref_list
if (node->definition && !node->in_other_partition
&& ((!DECL_EXTERNAL (node->decl) || node->alias)
- || (before_inlining_p
+ || (((before_inlining_p
+ && (cgraph_state < CGRAPH_STATE_IPA_SSA
+ || !lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (node->decl)))))
/* We use variable constructors during late complation for
constant folding. Keep references alive so partitioning
knows about potential references. */
@@ -191,7 +194,10 @@ walk_polymorphic_call_targets (pointer_s
/* Prior inlining, keep alive bodies of possible targets for
devirtualization. */
if (n->definition
- && before_inlining_p)
+ && (before_inlining_p
+ && (cgraph_state < CGRAPH_STATE_IPA_SSA
+ || !lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (n->decl)))))
pointer_set_insert (reachable, n);
/* Even after inlining we want to keep the possible targets in the
@@ -491,6 +497,12 @@ symtab_remove_unreachable_nodes (bool be
node->alias = false;
node->thunk.thunk_p = false;
node->weakref = false;
+ /* After early inlining we drop always_inline attributes on
+ bodies of functions that are still referenced (have their
+ address taken). */
+ DECL_ATTRIBUTES (node->decl)
+ = remove_attribute ("always_inline",
+ DECL_ATTRIBUTES (node->decl));
if (!node->in_other_partition)
node->local.local = false;
cgraph_node_remove_callees (node);
Index: testsuite/gcc.dg/lto/pr59626_1.c
===================================================================
--- testsuite/gcc.dg/lto/pr59626_1.c (revision 0)
+++ testsuite/gcc.dg/lto/pr59626_1.c (revision 0)
@@ -0,0 +1,4 @@
+int bar (int (*fn)(const char *))
+{
+ return fn ("0");
+}
Index: testsuite/gcc.dg/lto/pr59626_0.c
===================================================================
--- testsuite/gcc.dg/lto/pr59626_0.c (revision 0)
+++ testsuite/gcc.dg/lto/pr59626_0.c (revision 0)
@@ -0,0 +1,15 @@
+/* { dg-lto-do run } */
+
+int __atoi (const char *) __asm__("atoi");
+extern inline __attribute__((always_inline,gnu_inline))
+int atoi (const char *x)
+{
+ return __atoi (x);
+}
+
+int bar (int (*)(const char *));
+
+int main()
+{
+ return bar (atoi);
+}