re PR target/53633 (__attribute__((naked)) should disable -Wreturn-type)

2012-07-25  Sandra Loosemore  <sandra@codesourcery.com>
	    Paul Brook  <paul@codesourcery.com>

	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.

Co-Authored-By: Paul Brook <paul@codesourcery.com>

From-SVN: r189860
This commit is contained in:
Sandra Loosemore 2012-07-25 14:08:06 -04:00 committed by Sandra Loosemore
parent 62732c3044
commit d45eae79db
17 changed files with 153 additions and 39 deletions

View File

@ -1,3 +1,29 @@
2012-07-25 Sandra Loosemore <sandra@codesourcery.com>
Paul Brook <paul@codesourcery.com>
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 <siddhesh@redhat.com>
* final.c [ASSEMBLER_DIALECT](do_assembler_dialects): New

View File

@ -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.

View File

@ -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

View File

@ -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,

View File

@ -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"

View File

@ -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

View File

@ -1,3 +1,10 @@
2012-07-25 Sandra Loosemore <sandra@codesourcery.com>
Paul Brook <paul@codesourcery.com>
PR target/53633
* decl.c (finish_function): Check targetm.warn_func_return.
2012-07-25 Jason Merrill <jason@redhat.com>
PR c++/54086

View File

@ -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");

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -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,

View File

@ -1,3 +1,12 @@
2012-07-25 Sandra Loosemore <sandra@codesourcery.com>
Paul Brook <paul@codesourcery.com>
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 <siddhesh@redhat.com>
* gcc.target/i386/asm-dialect-1.c: New test case.

View File

@ -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__ ("");
}

View File

@ -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.
#

View File

@ -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)