diff options
author | Richard Biener <rguenther@suse.de> | 2013-01-07 15:34:43 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-01-07 15:34:43 +0000 |
commit | 3626621a07bd682cb31ea832d2034776dde4e780 (patch) | |
tree | 4175c00ea44d892ce1035c8ff1cbaf29665e98fe /gcc | |
parent | 8b2ea410c7d5ccc14b94447d449abdc0b4d547ac (diff) | |
download | gcc-3626621a07bd682cb31ea832d2034776dde4e780.zip gcc-3626621a07bd682cb31ea832d2034776dde4e780.tar.gz gcc-3626621a07bd682cb31ea832d2034776dde4e780.tar.bz2 |
re PR tree-optimization/55890 (calling a builtin func through a cast triggers an ICE)
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.
From-SVN: r194975
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/gimple.c | 54 | ||||
-rw-r--r-- | gcc/gimple.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr55890-1.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr55890-2.c | 4 | ||||
-rw-r--r-- | gcc/tree-ssa-strlen.c | 8 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 6 |
8 files changed, 83 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6b7ef3e..7fb1b33 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +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. + 2013-01-07 James Greenhalgh <james.greenhalgh@arm.com> * config/aarch64/arm_neon.h (vld1_dup_*): Make argument const. diff --git a/gcc/gimple.c b/gcc/gimple.c index 5a53e00..4f4bac8 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 diff --git a/gcc/gimple.h b/gcc/gimple.h index 5fcaac6..a5be00a 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -893,6 +893,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_class); extern bool gimple_call_builtin_p (gimple, enum built_in_function); extern bool gimple_asm_clobbers_memory_p (const_gimple); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 178459e..80f18ba 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-01-07 Richard Biener <rguenther@suse.de> + + PR middle-end/55890 + * gcc.dg/torture/pr55890-1.c: New testcase. + * gcc.dg/torture/pr55890-2.c: Likewise. + 2013-01-07 James Greenhalgh <james.greenhalgh@arm.com> * gcc.target/aarch64/fmovd.c: New. diff --git a/gcc/testsuite/gcc.dg/torture/pr55890-1.c b/gcc/testsuite/gcc.dg/torture/pr55890-1.c new file mode 100644 index 0000000..9fd558e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr55890-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ + +extern void *memmove(void *, void *, __SIZE_TYPE__); +typedef int (*_TEST_fun_) (); +static _TEST_fun_ i = (_TEST_fun_) memmove; +main() { i(); } diff --git a/gcc/testsuite/gcc.dg/torture/pr55890-2.c b/gcc/testsuite/gcc.dg/torture/pr55890-2.c new file mode 100644 index 0000000..a753e57 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr55890-2.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */
+
+extern void *memcpy();
+main() { memcpy(); }
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index aa8b3d6..a574a83 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -807,12 +807,10 @@ adjust_last_stmt (strinfo si, gimple stmt, bool is_strcat) return; } - if (!is_gimple_call (last.stmt)) - return; - callee = gimple_call_fndecl (last.stmt); - if (callee == NULL_TREE || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL) + if (!gimple_call_builtin_p (last.stmt, BUILT_IN_NORMAL)) return; + callee = gimple_call_fndecl (last.stmt); switch (DECL_FUNCTION_CODE (callee)) { case BUILT_IN_MEMCPY: @@ -1750,7 +1748,7 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi) if (is_gimple_call (stmt)) { tree callee = gimple_call_fndecl (stmt); - if (callee && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL) + if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) switch (DECL_FUNCTION_CODE (callee)) { case BUILT_IN_STRLEN: diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 4c3cb32..8eb8544 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4014,8 +4014,7 @@ find_func_aliases_for_builtin_call (gimple t) vec<ce_s> rhsc = vNULL; varinfo_t fi; - if (fndecl != NULL_TREE - && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + if (gimple_call_builtin_p (t, BUILT_IN_NORMAL)) /* ??? All builtins that are handled here need to be handled in the alias-oracle query functions explicitly! */ switch (DECL_FUNCTION_CODE (fndecl)) @@ -4768,8 +4767,7 @@ find_func_clobbers (gimple origt) /* For builtins we do not have separate function info. For those we do not generate escapes for we have to generate clobbers/uses. */ - if (decl - && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) + if (gimple_call_builtin_p (t, BUILT_IN_NORMAL)) switch (DECL_FUNCTION_CODE (decl)) { /* The following functions use and clobber memory pointed to |