aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@gcc.gnu.org>2010-05-31 16:25:35 +0000
committerJan Hubicka <hubicka@gcc.gnu.org>2010-05-31 16:25:35 +0000
commitc54c785d41ae9a2c59288939a08f0051f05b7a6f (patch)
tree7abd6b17d74d7f3258b196f10f26ef8e74c4a1bc
parent4892422a064e6f5d633123afecf6e95e4fca0f48 (diff)
downloadgcc-c54c785d41ae9a2c59288939a08f0051f05b7a6f.zip
gcc-c54c785d41ae9a2c59288939a08f0051f05b7a6f.tar.gz
gcc-c54c785d41ae9a2c59288939a08f0051f05b7a6f.tar.bz2
gimple.c (gimple_call_builtin_p): New function.
* 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
-rw-r--r--gcc/gimple.c12
-rw-r--r--gcc/gimple.h1
-rw-r--r--gcc/ipa-pure-const.c3
-rw-r--r--gcc/tree-cfg.c21
4 files changed, 34 insertions, 3 deletions
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 759caf2..f4c57b2 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -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"
diff --git a/gcc/gimple.h b/gcc/gimple.h
index baa839f..1a4dacd 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -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 *);
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 864e49d..5423885 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -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))
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 18754c4..5d094b5 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -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;
}