2012-07-25 Sandra Loosemore <sandra@codesourcery.com>
authorsandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Jul 2012 18:08:06 +0000 (18:08 +0000)
committersandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Jul 2012 18:08:06 +0000 (18:08 +0000)
    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

17 files changed:
gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/avr/avr.c
gcc/config/mcore/mcore.c
gcc/config/rx/rx.c
gcc/config/spu/spu.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/doc/sourcebuild.texi
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/ipa-pure-const.c
gcc/target.def
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr53633.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp
gcc/tree-cfg.c

index 5a63568..a61a37c 100644 (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
index 267868b..1f3f9b3 100644 (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;
+}
+
 \f
 /* Output assembler code for a block containing the constant parts
    of a trampoline, leaving space for the variable parts.
index 68048b6..e0d2e82 100644 (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
 
index 9b8cf02..c592964 100644 (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);
 \f
@@ -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;
 \f
 /* 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, 
index 058f54f..e2e61b2 100644 (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"
index cdae4d8..2d5405d 100644 (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
 
index 409e64d..2d87bdc 100644 (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
index 047b2fe..8e95a06 100644 (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");
index 44c2842..43afa00 100644 (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.
 
index d1a27f8..b419a71 100644 (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
index 85d9d1d..3f2ef1e 100644 (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
index a5933f3..980e428 100644 (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");
index c172673..bdbf68e 100644 (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,
index 0c57bc3..c749654 100644 (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.
diff --git a/gcc/testsuite/c-c++-common/pr53633.c b/gcc/testsuite/c-c++-common/pr53633.c
new file mode 100644 (file)
index 0000000..db7e1ce
--- /dev/null
@@ -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__ ("");
+}
index dbe4086..6640ef2 100644 (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.
 #
index 88efc78..2615de3 100644 (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)