Commit 25f0609b by Bernd Edlinger Committed by Bernd Edlinger

re PR middle-end/71876 (longjmp is miscompiled with -ffreestanding)

2016-08-03  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR middle-end/71876
        * 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.

From-SVN: r239092
parent 73c77563
2016-08-03 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR middle-end/71876
* 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.
2016-08-03 Vladimir Makarov <vmakarov@redhat.com> 2016-08-03 Vladimir Makarov <vmakarov@redhat.com>
PR middle-end/72778 PR middle-end/72778
......
...@@ -468,15 +468,13 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU ...@@ -468,15 +468,13 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
anti_adjust_stack (GEN_INT (n_popped)); anti_adjust_stack (GEN_INT (n_popped));
} }
/* Determine if the function identified by NAME and FNDECL is one with /* Determine if the function identified by FNDECL is one with
special properties we wish to know about. special properties we wish to know about. Modify FLAGS accordingly.
For example, if the function might return more than one time (setjmp), then For example, if the function might return more than one time (setjmp), then
set RETURNS_TWICE to a nonzero value. set ECF_RETURNS_TWICE.
Similarly set NORETURN if the function is in the longjmp family. Set ECF_MAY_BE_ALLOCA for any memory allocation function that might allocate
Set MAY_BE_ALLOCA for any memory allocation function that might allocate
space from the stack such as alloca. */ space from the stack such as alloca. */
static int static int
...@@ -491,7 +489,7 @@ special_function_p (const_tree fndecl, int flags) ...@@ -491,7 +489,7 @@ special_function_p (const_tree fndecl, int flags)
name_decl = DECL_NAME (cgraph_node::get (fndecl)->orig_decl); name_decl = DECL_NAME (cgraph_node::get (fndecl)->orig_decl);
if (fndecl && name_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', /* Exclude functions not at the file scope, or not `extern',
since they are not the magic functions we would otherwise since they are not the magic functions we would otherwise
think they are. think they are.
...@@ -514,43 +512,22 @@ special_function_p (const_tree fndecl, int flags) ...@@ -514,43 +512,22 @@ special_function_p (const_tree fndecl, int flags)
&& ! strcmp (name, "alloca")) && ! strcmp (name, "alloca"))
flags |= ECF_MAY_BE_ALLOCA; flags |= ECF_MAY_BE_ALLOCA;
/* Disregard prefix _, __ or __x. */ /* Disregard prefix _ or __. */
if (name[0] == '_') if (name[0] == '_')
{ {
if (name[1] == '_' && name[2] == 'x') if (name[1] == '_')
tname += 3;
else if (name[1] == '_')
tname += 2; tname += 2;
else else
tname += 1; tname += 1;
} }
if (tname[0] == 's') /* ECF_RETURNS_TWICE is safe even for -ffreestanding. */
{ if (! strcmp (tname, "setjmp")
if ((tname[1] == 'e' || ! strcmp (tname, "sigsetjmp")
&& (! strcmp (tname, "setjmp") || ! strcmp (name, "savectx")
|| ! strcmp (tname, "setjmp_syscall"))) || ! strcmp (name, "vfork")
|| (tname[1] == 'i' || ! strcmp (name, "getcontext"))
&& ! strcmp (tname, "sigsetjmp")) flags |= ECF_RETURNS_TWICE;
|| (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;
} }
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment