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,
DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
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);
}
for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
......
......@@ -348,8 +348,7 @@ inline_transform (struct cgraph_node *node)
{
unsigned int todo = 0;
struct cgraph_edge *e;
bool inline_p = false;
/* FIXME: Currently the pass manager is adding inline transform more than
once to some clones. This needs revisiting after WPA cleanups. */
if (cfun->after_inlining)
......@@ -361,20 +360,17 @@ inline_transform (struct cgraph_node *node)
save_inline_function_body (node);
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. */
todo |= TODO_update_ssa_only_virtuals;
}
if (inline_p)
{
timevar_push (TV_INTEGRATION);
todo = optimize_inline_calls (current_function_decl);
timevar_pop (TV_INTEGRATION);
}
timevar_pop (TV_INTEGRATION);
cfun->always_inline_functions_inlined = true;
cfun->after_inlining = true;
return todo | execute_fixup_cfg ();
......
......@@ -56,7 +56,7 @@ int __attribute__ ((noinline,noclone)) get_input(void)
return 1;
}
int __attribute__ ((always_inline))
int inline __attribute__ ((always_inline))
A::middleman_1 (int i)
{
return this->foo (i);
......
......@@ -2,7 +2,7 @@
tree_flow_call_edges_add. */
/* { dg-do compile } */
/* { dg-options "-O1 -fprofile-generate" } */
/* { dg-options "-O1 -fprofile-generate -Wno-attributes" } */
static __attribute__ ((always_inline)) void
baz ()
......
/* { dg-do compile } */
/* { dg-options "-Winline -O2" } */
/* { dg-options "-O2" } */
#include <stdarg.h>
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_start (q, t);
......
/* { dg-do compile } */
/* { dg-options "-Winline -O2" } */
inline __attribute__ ((always_inline)) void t(void); /* { dg-message "sorry\[^\n\]*body not available" "" } */
/* { dg-options "-O2" } */
inline __attribute__ ((always_inline)) void t(void); /* { dg-error "body not available" } */
void
q(void)
{
t(); /* { dg-message "sorry\[^\n\]*called from here" "" } */
t(); /* { dg-error "called from here" } */
}
/* { dg-do compile } */
/* { dg-options "-Winline -O2" } */
/* { dg-options "-O2" } */
int do_something_evil (void);
inline __attribute__ ((always_inline)) void
q2(void) /* { dg-message "sorry\[^\n\]*recursive" "" } */
q2(void) /* { dg-error "recursive inlining" } */
{
if (do_something_evil ())
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. */
}
/* { dg-do compile } */
/* { dg-options "-Wno-attributes" } */
#if (__SIZEOF_INT__ <= 2)
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-options "-funit-at-a-time" } */
/* { dg-options "-funit-at-a-time -Wno-attributes" } */
/* Verify we can inline without a complete prototype and with promoted
arguments. See also PR32492. */
__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 () {
set_mem_alias_set ();
}
......@@ -4,6 +4,6 @@ int main(void)
}
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 ();
}
/* { dg-do run } */
/* { dg-options "-fdump-tree-ealias" } */
/* { dg-options "-fdump-tree-ealias -Wno-attributes" } */
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
struct X
......
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
/* { dg-options "-Wuninitialized -Wno-attributes -O2" } */
int g;
int bar();
......
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
/* { dg-options "-Wuninitialized -Wno-attributes -O2" } */
int g;
int bar();
......
......@@ -3192,7 +3192,7 @@ tree_inlinable_function_p (tree fn)
As a bonus we can now give more details about the reason why a
function is not inlinable. */
if (always_inline)
sorry (inline_forbidden_reason, fn);
error (inline_forbidden_reason, fn);
else if (do_warning)
warning (OPT_Winline, inline_forbidden_reason, fn);
......@@ -3742,11 +3742,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
/* 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,
_(cgraph_inline_failed_string (reason)));
sorry ("called from here");
error ("inlining failed in call to always_inline %q+F: %s", fn,
cgraph_inline_failed_string (reason));
error ("called from here");
}
else if (warn_inline
&& 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