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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189860
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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);
#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
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;
+}
+
\f
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts.
&& !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
#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
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);
\f
#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;
\f
/* Adjust the stack and return the number of bytes taken to do it. */
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
/* 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;
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);
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,
&& ! 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 */
#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"
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[])
{
#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
+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
&& !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");
@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.
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
@hook TARGET_SET_UP_BY_PROLOGUE
+@hook TARGET_WARN_FUNC_RETURN
+
@node Stack Smashing Protection
@subsection Stack smashing protection
@cindex stack smashing protection
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");
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,
+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.
--- /dev/null
+/* { 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__ ("");
+}
}]
}
+# 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.
#
#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. */
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)