aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSandra Loosemore <sandra@codesourcery.com>2012-07-25 14:08:06 -0400
committerSandra Loosemore <sandra@gcc.gnu.org>2012-07-25 14:08:06 -0400
commitd45eae79db3e8c41ac1f307b267179498a636e0b (patch)
treef42803034e2d99c0fb7f313962516557837e0a57 /gcc
parent62732c3044c767f4efcff0cd398c9e65ba437bda (diff)
downloadgcc-d45eae79db3e8c41ac1f307b267179498a636e0b.zip
gcc-d45eae79db3e8c41ac1f307b267179498a636e0b.tar.gz
gcc-d45eae79db3e8c41ac1f307b267179498a636e0b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/config/arm/arm.c12
-rw-r--r--gcc/config/avr/avr.c14
-rw-r--r--gcc/config/mcore/mcore.c50
-rw-r--r--gcc/config/rx/rx.c11
-rw-r--r--gcc/config/spu/spu.c11
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c3
-rw-r--r--gcc/doc/sourcebuild.texi3
-rw-r--r--gcc/doc/tm.texi4
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/ipa-pure-const.c3
-rw-r--r--gcc/target.def9
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/c-c++-common/pr53633.c16
-rw-r--r--gcc/testsuite/lib/target-supports.exp8
-rw-r--r--gcc/tree-cfg.c4
17 files changed, 153 insertions, 39 deletions
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 <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
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 <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
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 <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.
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)