From 08c6cbd2f55bbb046e5ec82a8933fbd662b4009d Mon Sep 17 00:00:00 2001 From: sandra Date: Wed, 25 Jul 2012 18:08:06 +0000 Subject: [PATCH] 2012-07-25 Sandra Loosemore Paul Brook PR target/53633 gcc/ * target.def (warn_func_return): New hook. * doc/tm.texi.in (TARGET_WARN_FUNC_RETURN): New hook. * doc/tm.texi: Regenerate. * doc/sourcebuild.texi (Effective-Target Keywords): Document naked_functions. * ipa-pure-const.c (warn_function_noreturn): Check targetm.warn_func_return. * tree-cfg.c (execute_warn_function_return): Likewise. * config/spu/spu.c (spu_warn_func_return): New. (TARGET_WARN_FUNC_RETURN): Define. * config/rx/rx.c (rx_warn_func_return): New. (TARGET_WARN_FUNC_RETURN): Define. * config/avr/avr.c (avr_warn_func_return): New. (TARGET_WARN_FUNC_RETURN): Define. * config/arm/arm.c (arm_warn_func_return): New. (TARGET_WARN_FUNC_RETURN): Define. * config/mcore/mcore.c (mcore_warn_func_return): New. (TARGET_WARN_FUNC_RETURN): Define. (saved_warn_return_type, saved_warn_return_type_count): Remove. (mcore_reorg, mcore_handle_naked_attribute): Remove warn_return hack. gcc/cp/ * decl.c (finish_function): Check targetm.warn_func_return. gcc/testsuite/ * lib/target-suports.exp (check_effective_target_naked_functions): New. * c-c++-common/pr53633.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189860 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 26 ++++++++++++++++++ gcc/config/arm/arm.c | 12 +++++++++ gcc/config/avr/avr.c | 14 ++++++++++ gcc/config/mcore/mcore.c | 50 +++++++++-------------------------- gcc/config/rx/rx.c | 11 ++++++++ gcc/config/spu/spu.c | 11 ++++++++ gcc/cp/ChangeLog | 7 +++++ gcc/cp/decl.c | 3 ++- gcc/doc/sourcebuild.texi | 3 +++ gcc/doc/tm.texi | 4 +++ gcc/doc/tm.texi.in | 2 ++ gcc/ipa-pure-const.c | 3 ++- gcc/target.def | 9 +++++++ gcc/testsuite/ChangeLog | 9 +++++++ gcc/testsuite/c-c++-common/pr53633.c | 16 +++++++++++ gcc/testsuite/lib/target-supports.exp | 8 ++++++ gcc/tree-cfg.c | 4 +++ 17 files changed, 153 insertions(+), 39 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr53633.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a63568..a61a37c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2012-07-25 Sandra Loosemore + Paul Brook + + PR target/53633 + + * target.def (warn_func_return): New hook. + * doc/tm.texi.in (TARGET_WARN_FUNC_RETURN): New hook. + * doc/tm.texi: Regenerate. + * doc/sourcebuild.texi (Effective-Target Keywords): Document + naked_functions. + * ipa-pure-const.c (warn_function_noreturn): Check + targetm.warn_func_return. + * tree-cfg.c (execute_warn_function_return): Likewise. + * config/spu/spu.c (spu_warn_func_return): New. + (TARGET_WARN_FUNC_RETURN): Define. + * config/rx/rx.c (rx_warn_func_return): New. + (TARGET_WARN_FUNC_RETURN): Define. + * config/avr/avr.c (avr_warn_func_return): New. + (TARGET_WARN_FUNC_RETURN): Define. + * config/arm/arm.c (arm_warn_func_return): New. + (TARGET_WARN_FUNC_RETURN): Define. + * config/mcore/mcore.c (mcore_warn_func_return): New. + (TARGET_WARN_FUNC_RETURN): Define. + (saved_warn_return_type, saved_warn_return_type_count): Remove. + (mcore_reorg, mcore_handle_naked_attribute): Remove warn_return hack. + 2012-07-25 Siddhesh Poyarekar * final.c [ASSEMBLER_DIALECT](do_assembler_dialects): New diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 267868b..1f3f9b3 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -236,6 +236,7 @@ static int arm_issue_rate (void); static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; static bool arm_output_addr_const_extra (FILE *, rtx); static bool arm_allocate_stack_slots_for_args (void); +static bool arm_warn_func_return (tree); static const char *arm_invalid_parameter_type (const_tree t); static const char *arm_invalid_return_type (const_tree t); static tree arm_promoted_type (const_tree t); @@ -458,6 +459,9 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_TRAMPOLINE_ADJUST_ADDRESS #define TARGET_TRAMPOLINE_ADJUST_ADDRESS arm_trampoline_adjust_address +#undef TARGET_WARN_FUNC_RETURN +#define TARGET_WARN_FUNC_RETURN arm_warn_func_return + #undef TARGET_DEFAULT_SHORT_ENUMS #define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums @@ -2168,6 +2172,14 @@ arm_allocate_stack_slots_for_args (void) return !IS_NAKED (arm_current_func_type ()); } +static bool +arm_warn_func_return (tree decl) +{ + /* Naked functions are implemented entirely in assembly, including the + return sequence, so suppress warnings about this. */ + return lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) == NULL_TREE; +} + /* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 68048b6..e0d2e82 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -686,6 +686,17 @@ avr_can_eliminate (const int from, const int to) && !frame_pointer_needed)); } + +/* Implement TARGET_WARN_FUNC_RETURN. */ + +static bool +avr_warn_func_return (tree decl) +{ + /* Naked functions are implemented entirely in assembly, including the + return sequence, so suppress warnings about this. */ + return !avr_naked_function_p (decl); +} + /* Compute offset between arg_pointer and frame_pointer. */ int @@ -10790,6 +10801,9 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg, #undef TARGET_CAN_ELIMINATE #define TARGET_CAN_ELIMINATE avr_can_eliminate +#undef TARGET_WARN_FUNC_RETURN +#define TARGET_WARN_FUNC_RETURN avr_warn_func_return + #undef TARGET_CLASS_LIKELY_SPILLED_P #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 9b8cf02..c592964 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -138,6 +138,7 @@ static unsigned int mcore_function_arg_boundary (enum machine_mode, const_tree); static void mcore_asm_trampoline_template (FILE *); static void mcore_trampoline_init (rtx, tree, rtx); +static bool mcore_warn_func_return (tree); static void mcore_option_override (void); static bool mcore_legitimate_constant_p (enum machine_mode, rtx); @@ -228,6 +229,9 @@ static const struct attribute_spec mcore_attribute_table[] = #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P mcore_legitimate_constant_p +#undef TARGET_WARN_FUNC_RETURN +#define TARGET_WARN_FUNC_RETURN mcore_warn_func_return + struct gcc_target targetm = TARGET_INITIALIZER; /* Adjust the stack and return the number of bytes taken to do it. */ @@ -2580,9 +2584,6 @@ conditionalize_optimization (void) continue; } -static int saved_warn_return_type = -1; -static int saved_warn_return_type_count = 0; - /* This is to handle loads from the constant pool. */ static void @@ -2591,21 +2592,6 @@ mcore_reorg (void) /* Reset this variable. */ current_function_anonymous_args = 0; - /* Restore the warn_return_type if it has been altered. */ - if (saved_warn_return_type != -1) - { - /* Only restore the value if we have reached another function. - The test of warn_return_type occurs in final_function () in - c-decl.c a long time after the code for the function is generated, - so we need a counter to tell us when we have finished parsing that - function and can restore the flag. */ - if (--saved_warn_return_type_count == 0) - { - warn_return_type = saved_warn_return_type; - saved_warn_return_type = -1; - } - } - if (optimize == 0) return; @@ -3056,25 +3042,7 @@ static tree mcore_handle_naked_attribute (tree * node, tree name, tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, bool * no_add_attrs) { - if (TREE_CODE (*node) == FUNCTION_DECL) - { - /* PR14310 - don't complain about lack of return statement - in naked functions. The solution here is a gross hack - but this is the only way to solve the problem without - adding a new feature to GCC. I did try submitting a patch - that would add such a new feature, but it was (rightfully) - rejected on the grounds that it was creeping featurism, - so hence this code. */ - if (warn_return_type) - { - saved_warn_return_type = warn_return_type; - warn_return_type = 0; - saved_warn_return_type_count = 2; - } - else if (saved_warn_return_type_count) - saved_warn_return_type_count = 2; - } - else + if (TREE_CODE (*node) != FUNCTION_DECL) { warning (OPT_Wattributes, "%qE attribute only applies to functions", name); @@ -3126,6 +3094,14 @@ mcore_naked_function_p (void) return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE; } +static bool +mcore_warn_func_return (tree decl) +{ + /* Naked functions are implemented entirely in assembly, including the + return sequence, so suppress warnings about this. */ + return lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) == NULL_TREE; +} + #ifdef OBJECT_FORMAT_ELF static void mcore_asm_named_section (const char *name, diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index 058f54f..e2e61b2 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -2629,6 +2629,14 @@ rx_func_attr_inlinable (const_tree decl) && ! is_naked_func (decl); } +static bool +rx_warn_func_return (tree decl) +{ + /* Naked functions are implemented entirely in assembly, including the + return sequence, so suppress warnings about this. */ + return !is_naked_func (decl); +} + /* Return nonzero if it is ok to make a tail-call to DECL, a function_decl or NULL if this is an indirect call, using EXP */ @@ -3282,6 +3290,9 @@ rx_adjust_insn_length (rtx insn, int current_length) #undef TARGET_LEGITIMIZE_ADDRESS #define TARGET_LEGITIMIZE_ADDRESS rx_legitimize_address +#undef TARGET_WARN_FUNC_RETURN +#define TARGET_WARN_FUNC_RETURN rx_warn_func_return + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-rx.h" diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index cdae4d8..2d5405d 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -5881,6 +5881,14 @@ spu_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) emit_insn (gen_sync ()); } +static bool +spu_warn_func_return (tree decl) +{ + /* Naked functions are implemented entirely in assembly, including the + return sequence, so suppress warnings about this. */ + return !spu_naked_function_p (decl); +} + void spu_expand_sign_extend (rtx ops[]) { @@ -7272,6 +7280,9 @@ static const struct attribute_spec spu_attribute_table[] = #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT spu_trampoline_init +#undef TARGET_WARN_FUNC_RETURN +#define TARGET_WARN_FUNC_RETURN spu_warn_func_return + #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE spu_option_override diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 409e64d..2d87bdc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-07-25 Sandra Loosemore + Paul Brook + + PR target/53633 + + * decl.c (finish_function): Check targetm.warn_func_return. + 2012-07-25 Jason Merrill PR c++/54086 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 047b2fe..8e95a06 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13575,7 +13575,8 @@ finish_function (int flags) && !TREE_NO_WARNING (fndecl) /* Structor return values (if any) are set by the compiler. */ && !DECL_CONSTRUCTOR_P (fndecl) - && !DECL_DESTRUCTOR_P (fndecl)) + && !DECL_DESTRUCTOR_P (fndecl) + && targetm.warn_func_return (fndecl)) { warning (OPT_Wreturn_type, "no return statement in function returning non-void"); diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 44c2842..43afa00 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -1787,6 +1787,9 @@ Target keeps null pointer checks, either due to the use of @item lto Compiler has been configured to support link-time optimization (LTO). +@item naked_functions +Target supports the @code{naked} function attribute. + @item named_sections Target supports named sections. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index d1a27f8..b419a71 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4977,6 +4977,10 @@ FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM. This hook should add additional registers that are computed by the prologue to the hard regset for shrink-wrapping optimization purposes. @end deftypefn +@deftypefn {Target Hook} bool TARGET_WARN_FUNC_RETURN (tree) +True if a function's return statements should be checked for matching the function's return type. This includes checking for falling off the end of a non-void function. Return false if no such check should be made. +@end deftypefn + @node Stack Smashing Protection @subsection Stack smashing protection @cindex stack smashing protection diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 85d9d1d..3f2ef1e 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4918,6 +4918,8 @@ FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, and the PIC_OFFSET_TABLE_REGNUM. @hook TARGET_SET_UP_BY_PROLOGUE +@hook TARGET_WARN_FUNC_RETURN + @node Stack Smashing Protection @subsection Stack smashing protection @cindex stack smashing protection diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index a5933f3..980e428 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -186,7 +186,8 @@ void warn_function_noreturn (tree decl) { static struct pointer_set_t *warned_about; - if (!lang_hooks.missing_noreturn_ok_p (decl)) + if (!lang_hooks.missing_noreturn_ok_p (decl) + && targetm.warn_func_return (decl)) warned_about = suggest_attribute (OPT_Wsuggest_attribute_noreturn, decl, true, warned_about, "noreturn"); diff --git a/gcc/target.def b/gcc/target.def index c172673..bdbf68e 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2715,6 +2715,15 @@ DEFHOOK void, (struct hard_reg_set_container *), NULL) +/* For targets that have attributes that can affect whether a + function's return statements need checking. For instance a 'naked' + function attribute. */ +DEFHOOK +(warn_func_return, + "True if a function's return statements should be checked for matching the function's return type. This includes checking for falling off the end of a non-void function. Return false if no such check should be made.", + bool, (tree), + hook_bool_tree_true) + /* Determine the type of unwind info to emit for debugging. */ DEFHOOK (debug_unwind_info, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c57bc3..c749654 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2012-07-25 Sandra Loosemore + Paul Brook + + PR target/53633 + + * lib/target-suports.exp (check_effective_target_naked_functions): + New. + * c-c++-common/pr53633.c: New test. + 2012-07-25 Siddhesh Poyarekar * gcc.target/i386/asm-dialect-1.c: New test case. diff --git a/gcc/testsuite/c-c++-common/pr53633.c b/gcc/testsuite/c-c++-common/pr53633.c new file mode 100644 index 0000000..db7e1ce --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr53633.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target naked_functions } */ +/* { dg-options "-O2 -Wall" } */ +/* Check that we do not get warnings about missing return statements + or bogus looking noreturn functions. */ +int __attribute__((naked)) +foo(void) +{ + __asm__ (""); +} + +int __attribute__((naked,noreturn)) +bar(void) +{ + __asm__ (""); +} diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index dbe4086..6640ef2 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -984,6 +984,14 @@ proc check_named_sections_available { } { }] } +# Return true if the "naked" function attribute is supported on this target. + +proc check_effective_target_naked_functions { } { + return [check_no_compiler_messages naked_functions assembly { + void f() __attribute__((naked)); + }] +} + # Return 1 if the target supports Fortran real kinds larger than real(8), # 0 otherwise. # diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 88efc78..2615de3 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "value-prof.h" #include "pointer-set.h" #include "tree-inline.h" +#include "target.h" /* This file contains functions for building the Control Flow Graph (CFG) for a function tree. */ @@ -7614,6 +7615,9 @@ execute_warn_function_return (void) edge e; edge_iterator ei; + if (!targetm.warn_func_return (cfun->decl)) + return 0; + /* If we have a path to EXIT, then we do return. */ if (TREE_THIS_VOLATILE (cfun->decl) && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0) -- 2.7.4