From: hubicka Date: Mon, 31 May 2010 16:25:35 +0000 (+0000) Subject: * gimple.c (gimple_call_builtin_p): New function. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3ea38c1f35c70c83ce74f3dcd0d20ef54e078dd4;p=thirdparty%2Fgcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160079 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/gimple.c b/gcc/gimple.c index 759caf2e0c32..f4c57b2861c5 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 baa839fab6f6..1a4dacd23319 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 864e49dc8a9e..54238856e908 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 18754c48f98e..5d094b5bbaef 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; }