Commit c9fc06dc by Christian Bruel

PR middle-end/49139 fix always_inline diagnostics

From-SVN: r175239
parent f1ee724c
...@@ -986,6 +986,14 @@ process_function_and_variable_attributes (struct cgraph_node *first, ...@@ -986,6 +986,14 @@ process_function_and_variable_attributes (struct cgraph_node *first,
DECL_ATTRIBUTES (decl) = remove_attribute ("weakref", DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
DECL_ATTRIBUTES (decl)); DECL_ATTRIBUTES (decl));
} }
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl))
&& !DECL_DECLARED_INLINE_P (decl)
/* redefining extern inline function makes it DECL_UNINLINABLE. */
&& !DECL_UNINLINABLE (decl))
warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
"always_inline function might not be inlinable");
process_common_attributes (decl); process_common_attributes (decl);
} }
for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next) for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
......
...@@ -348,8 +348,7 @@ inline_transform (struct cgraph_node *node) ...@@ -348,8 +348,7 @@ inline_transform (struct cgraph_node *node)
{ {
unsigned int todo = 0; unsigned int todo = 0;
struct cgraph_edge *e; struct cgraph_edge *e;
bool inline_p = false;
/* FIXME: Currently the pass manager is adding inline transform more than /* FIXME: Currently the pass manager is adding inline transform more than
once to some clones. This needs revisiting after WPA cleanups. */ once to some clones. This needs revisiting after WPA cleanups. */
if (cfun->after_inlining) if (cfun->after_inlining)
...@@ -361,20 +360,17 @@ inline_transform (struct cgraph_node *node) ...@@ -361,20 +360,17 @@ inline_transform (struct cgraph_node *node)
save_inline_function_body (node); save_inline_function_body (node);
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = e->next_callee)
cgraph_redirect_edge_call_stmt_to_callee (e);
timevar_push (TV_INTEGRATION);
if (node->callees)
{ {
cgraph_redirect_edge_call_stmt_to_callee (e);
if (!e->inline_failed || warn_inline)
inline_p = true;
/* Redirecting edges might lead to a need for vops to be recomputed. */ /* Redirecting edges might lead to a need for vops to be recomputed. */
todo |= TODO_update_ssa_only_virtuals; todo |= TODO_update_ssa_only_virtuals;
}
if (inline_p)
{
timevar_push (TV_INTEGRATION);
todo = optimize_inline_calls (current_function_decl); todo = optimize_inline_calls (current_function_decl);
timevar_pop (TV_INTEGRATION);
} }
timevar_pop (TV_INTEGRATION);
cfun->always_inline_functions_inlined = true; cfun->always_inline_functions_inlined = true;
cfun->after_inlining = true; cfun->after_inlining = true;
return todo | execute_fixup_cfg (); return todo | execute_fixup_cfg ();
......
...@@ -56,7 +56,7 @@ int __attribute__ ((noinline,noclone)) get_input(void) ...@@ -56,7 +56,7 @@ int __attribute__ ((noinline,noclone)) get_input(void)
return 1; return 1;
} }
int __attribute__ ((always_inline)) int inline __attribute__ ((always_inline))
A::middleman_1 (int i) A::middleman_1 (int i)
{ {
return this->foo (i); return this->foo (i);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
tree_flow_call_edges_add. */ tree_flow_call_edges_add. */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O1 -fprofile-generate" } */ /* { dg-options "-O1 -fprofile-generate -Wno-attributes" } */
static __attribute__ ((always_inline)) void static __attribute__ ((always_inline)) void
baz () baz ()
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-Winline -O2" } */ /* { dg-options "-O2" } */
#include <stdarg.h> #include <stdarg.h>
inline __attribute__ ((always_inline)) void inline __attribute__ ((always_inline)) void
e(int t, ...) /* { dg-message "sorry\[^\n\]*variable argument" "" } */ e(int t, ...) /* { dg-error "variable argument lists" } */
{ {
va_list q; va_list q;
va_start (q, t); va_start (q, t);
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-Winline -O2" } */ /* { dg-options "-O2" } */
inline __attribute__ ((always_inline)) void t(void); /* { dg-message "sorry\[^\n\]*body not available" "" } */ inline __attribute__ ((always_inline)) void t(void); /* { dg-error "body not available" } */
void void
q(void) q(void)
{ {
t(); /* { dg-message "sorry\[^\n\]*called from here" "" } */ t(); /* { dg-error "called from here" } */
} }
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-Winline -O2" } */ /* { dg-options "-O2" } */
int do_something_evil (void); int do_something_evil (void);
inline __attribute__ ((always_inline)) void inline __attribute__ ((always_inline)) void
q2(void) /* { dg-message "sorry\[^\n\]*recursive" "" } */ q2(void) /* { dg-error "recursive inlining" } */
{ {
if (do_something_evil ()) if (do_something_evil ())
return; return;
q2(); /* { dg-message "sorry\[^\n\]*called from here" "" } */ q2(); /* { dg-error "called from here" } */
q2(); /* With -O2 we don't warn here, it is eliminated by tail recursion. */ q2(); /* With -O2 we don't warn here, it is eliminated by tail recursion. */
} }
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-Wno-attributes" } */
#if (__SIZEOF_INT__ <= 2) #if (__SIZEOF_INT__ <= 2)
typedef unsigned long hashval_t; typedef unsigned long hashval_t;
......
/* { dg-do compile } */
extern __attribute__ ((always_inline)) void
bar() { } /* { dg-warning "function might not be inlinable" } */
void
f()
{
bar();
}
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-funit-at-a-time" } */ /* { dg-options "-funit-at-a-time -Wno-attributes" } */
/* Verify we can inline without a complete prototype and with promoted /* Verify we can inline without a complete prototype and with promoted
arguments. See also PR32492. */ arguments. See also PR32492. */
__attribute__((always_inline)) void f1() {} __attribute__((always_inline)) void f1() {}
......
void set_mem_alias_set () __attribute__ ((always_inline)); void inline set_mem_alias_set () __attribute__ ((always_inline));
void emit_push_insn () { void emit_push_insn () {
set_mem_alias_set (); set_mem_alias_set ();
} }
...@@ -4,6 +4,6 @@ int main(void) ...@@ -4,6 +4,6 @@ int main(void)
} }
static void __attribute__ ((noinline)) get_mem_attrs () { static void __attribute__ ((noinline)) get_mem_attrs () {
} }
void __attribute__ ((always_inline)) set_mem_alias_set () { void inline __attribute__ ((always_inline)) set_mem_alias_set () {
get_mem_attrs (); get_mem_attrs ();
} }
/* { dg-do run } */ /* { dg-do run } */
/* { dg-options "-fdump-tree-ealias" } */ /* { dg-options "-fdump-tree-ealias -Wno-attributes" } */
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ /* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
struct X struct X
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */ /* { dg-options "-Wuninitialized -Wno-attributes -O2" } */
int g; int g;
int bar(); int bar();
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */ /* { dg-options "-Wuninitialized -Wno-attributes -O2" } */
int g; int g;
int bar(); int bar();
......
...@@ -3192,7 +3192,7 @@ tree_inlinable_function_p (tree fn) ...@@ -3192,7 +3192,7 @@ tree_inlinable_function_p (tree fn)
As a bonus we can now give more details about the reason why a As a bonus we can now give more details about the reason why a
function is not inlinable. */ function is not inlinable. */
if (always_inline) if (always_inline)
sorry (inline_forbidden_reason, fn); error (inline_forbidden_reason, fn);
else if (do_warning) else if (do_warning)
warning (OPT_Winline, inline_forbidden_reason, fn); warning (OPT_Winline, inline_forbidden_reason, fn);
...@@ -3742,11 +3742,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) ...@@ -3742,11 +3742,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
/* Avoid warnings during early inline pass. */ /* Avoid warnings during early inline pass. */
&& cgraph_global_info_ready) && cgraph_global_info_ready
/* PR 20090218-1_0.c. Body can be provided by another module. */
&& (reason != CIF_BODY_NOT_AVAILABLE || !flag_generate_lto))
{ {
sorry ("inlining failed in call to %q+F: %s", fn, error ("inlining failed in call to always_inline %q+F: %s", fn,
_(cgraph_inline_failed_string (reason))); cgraph_inline_failed_string (reason));
sorry ("called from here"); error ("called from here");
} }
else if (warn_inline else if (warn_inline
&& DECL_DECLARED_INLINE_P (fn) && DECL_DECLARED_INLINE_P (fn)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment