diff options
author | Jan Hubicka <hubicka@gcc.gnu.org> | 2010-05-31 16:25:35 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2010-05-31 16:25:35 +0000 |
commit | c54c785d41ae9a2c59288939a08f0051f05b7a6f (patch) | |
tree | 7abd6b17d74d7f3258b196f10f26ef8e74c4a1bc | |
parent | 4892422a064e6f5d633123afecf6e95e4fca0f48 (diff) | |
download | gcc-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.c | 12 | ||||
-rw-r--r-- | gcc/gimple.h | 1 | ||||
-rw-r--r-- | gcc/ipa-pure-const.c | 3 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 21 |
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; } |