The following avoids diagnosing failed always-inlining on speculated
calls where the function has cleared DECL_DISREGARD_INLINE_LIMITS
because we earlier detected recursive callgraph edges. Instead
of just checking for the always_inline attribute we should also
check that always-inlining is still active before diagnosing.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
This regresses
FAIL: gcc.dg/always_inline3.c (test for errors, line 5)
FAIL: gcc.dg/always_inline3.c (test for warnings, line 9)
which looks for the diagnostic. It seems to me that disabling
DECL_DISREGARD_INLINE_LIMITS in inline_small_functions is
overly aggressive and also affects not recursive calls as I
see
../../../../ompi/mca/part/persist/part_persist.h:484:1: error: inlining
failed in call to 'always_inline' 'mca_part_persist_start': --param
max-inline-insns-single limit reached
so another fix would be to remove this and instead properly guard
whatever code breaks?
PR ipa/123459
* tree-inline.cc (expand_call_inline): Check
DECL_DISREGARD_INLINE_LIMITS before diagnosting a failed
always-inlining.
* gcc.dg/torture/pr123459.c: New testcase.
---
gcc/testsuite/gcc.dg/torture/pr123459.c | 22 ++++++++++++++++++++++
gcc/tree-inline.cc | 3 +++
2 files changed, 25 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr123459.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr123459.c
b/gcc/testsuite/gcc.dg/torture/pr123459.c
new file mode 100644
index 00000000000..711ec1d3721
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr123459.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+struct handler_chain {
+ struct handler_chain *next;
+ void (*handler)(struct handler_chain *);
+};
+
+__attribute__((always_inline))
+static inline
+void noop_handler(struct handler_chain *h)
+{
+ h = h->next;
+ if (h) {
+ h->handler(h);
+ }
+}
+
+void test(struct handler_chain *h)
+{
+ h->handler = noop_handler;
+ noop_handler(h);
+}
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index df5597ef30d..37b1ff56caa 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -4910,6 +4910,9 @@ expand_call_inline (basic_block bb, gimple *stmt,
copy_body_data *id,
goto egress;
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
+ /* Make sure we didn't disabling always_inline previously
+ when detecting self-recursion. */
+ && DECL_DISREGARD_INLINE_LIMITS (fn)
/* For extern inline functions that get redefined we always
silently ignored always_inline flag. Better behavior would
be to be able to keep both bodies and use extern inline body
--
2.51.0