gimple.c (gimple_call_builtin_p): New function.
authorJan Hubicka <hubicka@gcc.gnu.org>
Mon, 31 May 2010 16:25:35 +0000 (16:25 +0000)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 31 May 2010 16:25:35 +0000 (16:25 +0000)
* gimple.c (gimple_call_builtin_p): New function.
* gimple.h (gimple_call_builtin_p): Declare.
* tree-cfg.c (make_edges): Produce edge from BUILT_IN_RETURN
to exit.
(execute_warn_function_return): BUILT_IN_RETURN is return.
(split_critical_edges): Return edges are not critical.
(is_ctrl_altering_stmt): Builtin_in_return is altering.
(gimple_verify_flow_info): Handle built_in_return.
(execute_warn_function_return): Handle built_in_return.
* ipa-pure-const.c (check_call): Ignore builtin_return.

* gcc.dg/builtin-apply4.c: Compile with -Wmissing-return.

From-SVN: r160079

gcc/gimple.c
gcc/gimple.h
gcc/ipa-pure-const.c
gcc/tree-cfg.c

index 759caf2..f4c57b2 100644 (file)
@@ -4732,4 +4732,16 @@ gimple_decl_printable_name (tree decl, int verbosity)
   return IDENTIFIER_POINTER (DECL_NAME (decl));
 }
 
+/* Return true when STMT is builtins call to CODE.  */
+
+bool
+gimple_call_builtin_p (gimple stmt, enum built_in_function code)
+{
+  tree fndecl;
+  return (is_gimple_call (stmt)
+         && (fndecl = gimple_call_fndecl (stmt)) != NULL
+         && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+         && DECL_FUNCTION_CODE (fndecl) == code);
+}
+
 #include "gt-gimple.h"
index baa839f..1a4dacd 100644 (file)
@@ -961,6 +961,7 @@ extern bool walk_stmt_load_store_ops (gimple, void *,
                                      bool (*)(gimple, tree, void *),
                                      bool (*)(gimple, tree, void *));
 extern bool gimple_ior_addresses_taken (bitmap, gimple);
+extern bool gimple_call_builtin_p (gimple, enum built_in_function);
 
 /* In gimplify.c  */
 extern tree create_tmp_var_raw (tree, const char *);
index 864e49d..5423885 100644 (file)
@@ -369,6 +369,9 @@ check_call (funct_state local, gimple call, bool ipa)
      graph.  */
   if (callee_t)
     {
+      /* built_in_return is really just an return statemnt.  */
+      if (gimple_call_builtin_p (call, BUILT_IN_RETURN))
+       return;
       /* When bad things happen to bad functions, they cannot be const
         or pure.  */
       if (setjmp_call_p (callee_t))
index 18754c4..5d094b5 100644 (file)
@@ -568,8 +568,12 @@ make_edges (void)
                 create abnormal edges to them.  */
              make_eh_edges (last);
 
+             /* BUILTIN_RETURN is really a return statement.  */
+             if (gimple_call_builtin_p (last, BUILT_IN_RETURN))
+               make_edge (bb, EXIT_BLOCK_PTR, 0), fallthru = false;
              /* Some calls are known not to return.  */
-             fallthru = !(gimple_call_flags (last) & ECF_NORETURN);
+             else
+               fallthru = !(gimple_call_flags (last) & ECF_NORETURN);
              break;
 
            case GIMPLE_ASSIGN:
@@ -2248,6 +2252,10 @@ is_ctrl_altering_stmt (gimple t)
        /* A call also alters control flow if it does not return.  */
        if (flags & ECF_NORETURN)
          return true;
+
+       /* BUILT_IN_RETURN call is same as return statement.  */
+       if (gimple_call_builtin_p (t, BUILT_IN_RETURN))
+         return true;
       }
       break;
 
@@ -4436,6 +4444,10 @@ gimple_verify_flow_info (void)
            }
          break;
 
+       case GIMPLE_CALL:
+         if (!gimple_call_builtin_p (stmt, BUILT_IN_RETURN))
+           break;
+         /* ... fallthru ... */
        case GIMPLE_RETURN:
          if (!single_succ_p (bb)
              || (single_succ_edge (bb)->flags
@@ -7050,7 +7062,9 @@ split_critical_edges (void)
              gsi = gsi_last_bb (e->src);
              if (!gsi_end_p (gsi)
                  && stmt_ends_bb_p (gsi_stmt (gsi))
-                 && gimple_code (gsi_stmt (gsi)) != GIMPLE_RETURN)
+                 && (gimple_code (gsi_stmt (gsi)) != GIMPLE_RETURN
+                     && !gimple_call_builtin_p (gsi_stmt (gsi),
+                                                BUILT_IN_RETURN)))
                split_edge (e);
            }
        }
@@ -7148,7 +7162,8 @@ execute_warn_function_return (void)
       FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
        {
          last = last_stmt (e->src);
-         if (gimple_code (last) == GIMPLE_RETURN
+         if ((gimple_code (last) == GIMPLE_RETURN
+              || gimple_call_builtin_p (last, BUILT_IN_RETURN))
              && (location = gimple_location (last)) != UNKNOWN_LOCATION)
            break;
        }