We ICE when splitting part of a function which has the malloc attribute and that part does not return. While the issue is more general (transfering attributes to a part/clone) we can address this probably common issue with the following simple patch.
Richard. 2012-01-23 Richard Guenther <rguent...@suse.de> PR tree-optimization/51949 * ipa-split.c (execute_split_functions): Do not split malloc functions. * gcc.dg/torture/pr51949.c: New testcase. Index: gcc/ipa-split.c =================================================================== --- gcc/ipa-split.c (revision 183421) +++ gcc/ipa-split.c (working copy) @@ -1395,10 +1395,11 @@ execute_split_functions (void) int todo = 0; struct cgraph_node *node = cgraph_get_node (current_function_decl); - if (flags_from_decl_or_type (current_function_decl) & ECF_NORETURN) + if (flags_from_decl_or_type (current_function_decl) + & (ECF_NORETURN|ECF_MALLOC)) { if (dump_file) - fprintf (dump_file, "Not splitting: noreturn function.\n"); + fprintf (dump_file, "Not splitting: noreturn/malloc function.\n"); return 0; } if (MAIN_NAME_P (DECL_NAME (current_function_decl))) Index: gcc/testsuite/gcc.dg/torture/pr51949.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr51949.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr51949.c (revision 0) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +typedef long unsigned int size_t; +extern __attribute__ ((malloc)) void *mem_alloc(size_t); +void *mem_alloc(size_t amount) +{ + void *q = __builtin_malloc (amount); + if (!q) { + __builtin_printf("malloc"); + __builtin_exit(255); + } +} +void mem_realloc() +{ + mem_alloc(1); +} +void put_env_var() +{ + mem_alloc(1); +}