Hi, based on the discussion here, I have updated my patch again...
This is the rest of the patch, which removes outdated function names, and creates built-in definitions for vfork, getcontext, savectx. These built-ins have the return_twice attribute but not the leaf attribute, because we do not really know, what these functions do. The reason for ceating the builtin functions is, that I would like to get a warning about conflicting builtin definition if someone accidentally picks the name of one of these less well known special functions, which are _not_ reserved names in most environments. I do not define builtins (without __builtin_ prefix) for setjmp and sigsetjmp because these are like wildcards, and they fall in the well-known category anyways. I still retain the handling of these functions in special_function_p because even in a free standing environment, returning ECF_RETURNS_TWICE is on the safe side. Is it OK for trunk after boot-strap and regression-testing? Thanks Bernd.
2016-07-21 Bernd Edlinger <bernd.edlin...@hotmail.de> PR middle-end/71876 * builtin-attrs.def (ATTR_RT_NOTHROW_LIST): New return twice no leaf attribute. * builtins.def (BUILT_IN_GETCONTEXT, BUILT_IN_SAVECTX, BUILT_IN_VFORK): New builtins using ATTR_RT_NOTHROW_LIST. * calls.c (special_function_p): Remove special handling of "setjmp_syscall", "qsetjmp", "longjmp", "siglongjmp" and the prefix "__x". Recognize "savectx", "vfork" and "getcontext" only without prefix. Remove potentially unsafe ECF_LEAF and ECF_NORETURN.
Index: gcc/builtin-attrs.def =================================================================== --- gcc/builtin-attrs.def (revision 238611) +++ gcc/builtin-attrs.def (working copy) @@ -131,6 +131,8 @@ DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, AT ATTR_NULL, ATTR_NOTHROW_LIST) DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LEAF_LIST, ATTR_NORETURN,\ ATTR_NULL, ATTR_NOTHROW_LEAF_LIST) +DEF_ATTR_TREE_LIST (ATTR_RT_NOTHROW_LIST, ATTR_RETURNS_TWICE,\ + ATTR_NULL, ATTR_NOTHROW_LIST) DEF_ATTR_TREE_LIST (ATTR_RT_NOTHROW_LEAF_LIST, ATTR_RETURNS_TWICE,\ ATTR_NULL, ATTR_NOTHROW_LEAF_LIST) DEF_ATTR_TREE_LIST (ATTR_COLD_NOTHROW_LEAF_LIST, ATTR_COLD,\ Index: gcc/builtins.def =================================================================== --- gcc/builtins.def (revision 238611) +++ gcc/builtins.def (working copy) @@ -796,6 +796,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finit DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_FPCLASSIFY, "fpclassify", BT_FN_INT_INT_INT_INT_INT_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_GETCONTEXT, "getcontext", BT_FN_INT_PTR, ATTR_RT_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_ISFINITE, "isfinite", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) DEF_GCC_BUILTIN (BUILT_IN_ISINF_SIGN, "isinf_sign", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) @@ -836,6 +837,7 @@ DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefet DEF_LIB_BUILTIN (BUILT_IN_REALLOC, "realloc", BT_FN_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SAVECTX, "savectx", BT_FN_VOID_PTR, ATTR_RT_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_RT_NOTHROW_LEAF_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4) @@ -849,6 +851,7 @@ DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK_LEN, "va_arg_pack_len", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_VFORK, "vfork", BT_FN_PID, ATTR_RT_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST) Index: gcc/calls.c =================================================================== --- gcc/calls.c (revision 238611) +++ gcc/calls.c (working copy) @@ -474,8 +474,6 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNU For example, if the function might return more than one time (setjmp), then set RETURNS_TWICE to a nonzero value. - Similarly set NORETURN if the function is in the longjmp family. - Set MAY_BE_ALLOCA for any memory allocation function that might allocate space from the stack such as alloca. */ @@ -491,7 +489,7 @@ special_function_p (const_tree fndecl, int flags) name_decl = DECL_NAME (cgraph_node::get (fndecl)->orig_decl); if (fndecl && name_decl - && IDENTIFIER_LENGTH (name_decl) <= 17 + && IDENTIFIER_LENGTH (name_decl) <= 11 /* Exclude functions not at the file scope, or not `extern', since they are not the magic functions we would otherwise think they are. @@ -514,43 +512,22 @@ special_function_p (const_tree fndecl, int flags) && ! strcmp (name, "alloca")) flags |= ECF_MAY_BE_ALLOCA; - /* Disregard prefix _, __ or __x. */ + /* Disregard prefix _ or __. */ if (name[0] == '_') { - if (name[1] == '_' && name[2] == 'x') - tname += 3; - else if (name[1] == '_') + if (name[1] == '_') tname += 2; else tname += 1; } - if (tname[0] == 's') - { - if ((tname[1] == 'e' - && (! strcmp (tname, "setjmp") - || ! strcmp (tname, "setjmp_syscall"))) - || (tname[1] == 'i' - && ! strcmp (tname, "sigsetjmp")) - || (tname[1] == 'a' - && ! strcmp (tname, "savectx"))) - flags |= ECF_RETURNS_TWICE | ECF_LEAF; - - if (tname[1] == 'i' - && ! strcmp (tname, "siglongjmp")) - flags |= ECF_NORETURN; - } - else if ((tname[0] == 'q' && tname[1] == 's' - && ! strcmp (tname, "qsetjmp")) - || (tname[0] == 'v' && tname[1] == 'f' - && ! strcmp (tname, "vfork")) - || (tname[0] == 'g' && tname[1] == 'e' - && !strcmp (tname, "getcontext"))) - flags |= ECF_RETURNS_TWICE | ECF_LEAF; - - else if (tname[0] == 'l' && tname[1] == 'o' - && ! strcmp (tname, "longjmp")) - flags |= ECF_NORETURN; + /* ECF_RETURNS_TWICE is safe even for -ffreestanding. */ + if (! strcmp (tname, "setjmp") + || ! strcmp (tname, "sigsetjmp") + || ! strcmp (name, "savectx") + || ! strcmp (name, "vfork") + || ! strcmp (name, "getcontext")) + flags |= ECF_RETURNS_TWICE; } if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)