===================================================================
@@ -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,\
===================================================================
@@ -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)
===================================================================
@@ -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)