From: Christian Bruel Date: Tue, 21 Jun 2011 06:42:05 +0000 (+0200) Subject: PR middle-end/49139 fix always_inline diagnostics X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c9fc06dcdd6568fa4a54d10408098ec51d07234f;p=gcc.git PR middle-end/49139 fix always_inline diagnostics From-SVN: r175239 --- diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 6683d2a5df3..de9bbe3edeb 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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) diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index 2e1375437d5..39c0138956e 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -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 (); diff --git a/gcc/testsuite/g++.dg/ipa/devirt-7.C b/gcc/testsuite/g++.dg/ipa/devirt-7.C index ac147b57599..1c59122303d 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-7.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-7.C @@ -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); diff --git a/gcc/testsuite/gcc.dg/20051201-1.c b/gcc/testsuite/gcc.dg/20051201-1.c index 8e77986296e..bc8e7926be0 100644 --- a/gcc/testsuite/gcc.dg/20051201-1.c +++ b/gcc/testsuite/gcc.dg/20051201-1.c @@ -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 () diff --git a/gcc/testsuite/gcc.dg/always_inline.c b/gcc/testsuite/gcc.dg/always_inline.c index 08119f1a254..482a0a2b46c 100644 --- a/gcc/testsuite/gcc.dg/always_inline.c +++ b/gcc/testsuite/gcc.dg/always_inline.c @@ -1,8 +1,8 @@ /* { dg-do compile } */ -/* { dg-options "-Winline -O2" } */ +/* { dg-options "-O2" } */ #include 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); diff --git a/gcc/testsuite/gcc.dg/always_inline2.c b/gcc/testsuite/gcc.dg/always_inline2.c index c65df24ea60..4f1634e1348 100644 --- a/gcc/testsuite/gcc.dg/always_inline2.c +++ b/gcc/testsuite/gcc.dg/always_inline2.c @@ -1,8 +1,8 @@ /* { 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" } */ } diff --git a/gcc/testsuite/gcc.dg/always_inline3.c b/gcc/testsuite/gcc.dg/always_inline3.c index 97c80aa5217..80ea314741b 100644 --- a/gcc/testsuite/gcc.dg/always_inline3.c +++ b/gcc/testsuite/gcc.dg/always_inline3.c @@ -1,11 +1,11 @@ /* { 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. */ } diff --git a/gcc/testsuite/gcc.dg/debug/pr41264-1.c b/gcc/testsuite/gcc.dg/debug/pr41264-1.c index 34bdcfe2047..7d03e51ae37 100644 --- a/gcc/testsuite/gcc.dg/debug/pr41264-1.c +++ b/gcc/testsuite/gcc.dg/debug/pr41264-1.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-options "-Wno-attributes" } */ #if (__SIZEOF_INT__ <= 2) typedef unsigned long hashval_t; diff --git a/gcc/testsuite/gcc.dg/fail_always_inline.c b/gcc/testsuite/gcc.dg/fail_always_inline.c new file mode 100644 index 00000000000..4b196acb07f --- /dev/null +++ b/gcc/testsuite/gcc.dg/fail_always_inline.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ + +extern __attribute__ ((always_inline)) void + bar() { } /* { dg-warning "function might not be inlinable" } */ + +void +f() +{ + bar(); +} + diff --git a/gcc/testsuite/gcc.dg/inline-22.c b/gcc/testsuite/gcc.dg/inline-22.c index 6d790f97402..1785e1ce6d5 100644 --- a/gcc/testsuite/gcc.dg/inline-22.c +++ b/gcc/testsuite/gcc.dg/inline-22.c @@ -1,5 +1,5 @@ /* { 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() {} diff --git a/gcc/testsuite/gcc.dg/lto/20090218-1_0.c b/gcc/testsuite/gcc.dg/lto/20090218-1_0.c index 1dc9ee08540..750c2027510 100644 --- a/gcc/testsuite/gcc.dg/lto/20090218-1_0.c +++ b/gcc/testsuite/gcc.dg/lto/20090218-1_0.c @@ -1,4 +1,4 @@ -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 (); } diff --git a/gcc/testsuite/gcc.dg/lto/20090218-1_1.c b/gcc/testsuite/gcc.dg/lto/20090218-1_1.c index 33d4fb000f3..7db2c85e4ce 100644 --- a/gcc/testsuite/gcc.dg/lto/20090218-1_1.c +++ b/gcc/testsuite/gcc.dg/lto/20090218-1_1.c @@ -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 (); } diff --git a/gcc/testsuite/gcc.dg/torture/pta-structcopy-1.c b/gcc/testsuite/gcc.dg/torture/pta-structcopy-1.c index 5dc041b0edd..97e8946da54 100644 --- a/gcc/testsuite/gcc.dg/torture/pta-structcopy-1.c +++ b/gcc/testsuite/gcc.dg/torture/pta-structcopy-1.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-fdump-tree-ealias" } */ +/* { dg-options "-fdump-tree-ealias -Wno-attributes" } */ /* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ struct X diff --git a/gcc/testsuite/gcc.dg/uninit-pred-5_a.c b/gcc/testsuite/gcc.dg/uninit-pred-5_a.c index 845f3c46124..7fa0b253fb1 100644 --- a/gcc/testsuite/gcc.dg/uninit-pred-5_a.c +++ b/gcc/testsuite/gcc.dg/uninit-pred-5_a.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-Wuninitialized -O2" } */ +/* { dg-options "-Wuninitialized -Wno-attributes -O2" } */ int g; int bar(); diff --git a/gcc/testsuite/gcc.dg/uninit-pred-5_b.c b/gcc/testsuite/gcc.dg/uninit-pred-5_b.c index 13f1e31f805..9760fa8a5c8 100644 --- a/gcc/testsuite/gcc.dg/uninit-pred-5_b.c +++ b/gcc/testsuite/gcc.dg/uninit-pred-5_b.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-Wuninitialized -O2" } */ +/* { dg-options "-Wuninitialized -Wno-attributes -O2" } */ int g; int bar(); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index dc3288b5b37..c8b9f4c19da 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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)