mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-09 16:01:12 +08:00
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:
parent
62732c3044
commit
d45eae79db
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
16
gcc/testsuite/c-c++-common/pr53633.c
Normal file
16
gcc/testsuite/c-c++-common/pr53633.c
Normal 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__ ("");
|
||||
}
|
@ -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.
|
||||
#
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user