diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-01-07 15:34:43 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-01-07 15:34:43 +0000 |
commit | 789a8d72f35c340e98859cb1ecdf72d70573bdbf (patch) | |
tree | 4175c00ea44d892ce1035c8ff1cbaf29665e98fe /gcc/gimple.c | |
parent | 71e72cc261bbd16dad0ec1ca9731fa4fe3eb9f74 (diff) | |
download | gcc-789a8d72f35c340e98859cb1ecdf72d70573bdbf.tar.gz |
2013-01-07 Richard Biener <rguenther@suse.de>
PR middle-end/55890
* gimple.h (gimple_call_builtin_p): New overload.
* gimple.c (validate_call): New function.
(gimple_call_builtin_p): Likewise.
* tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
Use gimple_call_builtin_p.
(find_func_clobbers): Likewise.
* tree-ssa-strlen.c (adjust_last_stmt): Likewise.
(strlen_optimize_stmt): Likewise.
* gcc.dg/torture/pr55890-1.c: New testcase.
* gcc.dg/torture/pr55890-2.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194975 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimple.c')
-rw-r--r-- | gcc/gimple.c | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/gcc/gimple.c b/gcc/gimple.c index 5a53e0082c0..4f4bac860c4 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -4137,16 +4137,60 @@ is_gimple_builtin_call (gimple stmt) return false; } -/* Return true when STMT is builtins call to CODE. */ +/* Return true when STMTs arguments match those of FNDECL. */ + +static bool +validate_call (gimple stmt, tree fndecl) +{ + tree targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); + unsigned nargs = gimple_call_num_args (stmt); + for (unsigned i = 0; i < nargs; ++i) + { + /* Variadic args follow. */ + if (!targs) + return true; + tree arg = gimple_call_arg (stmt, i); + if (INTEGRAL_TYPE_P (TREE_TYPE (arg)) + && INTEGRAL_TYPE_P (TREE_VALUE (targs))) + ; + else if (POINTER_TYPE_P (TREE_TYPE (arg)) + && POINTER_TYPE_P (TREE_VALUE (targs))) + ; + else if (TREE_CODE (TREE_TYPE (arg)) + != TREE_CODE (TREE_VALUE (targs))) + return false; + targs = TREE_CHAIN (targs); + } + if (targs && !VOID_TYPE_P (TREE_VALUE (targs))) + return false; + return true; +} + +/* Return true when STMT is builtins call to CLASS. */ + +bool +gimple_call_builtin_p (gimple stmt, enum built_in_class klass) +{ + tree fndecl; + if (is_gimple_call (stmt) + && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE + && DECL_BUILT_IN_CLASS (fndecl) == klass) + return validate_call (stmt, fndecl); + return false; +} + +/* Return true when STMT is builtins call to CODE of CLASS. */ 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); + if (is_gimple_call (stmt) + && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (fndecl) == code) + return validate_call (stmt, fndecl); + return false; } /* Return true if STMT clobbers memory. STMT is required to be a |