diff options
author | Martin Sebor <msebor@redhat.com> | 2015-08-02 23:14:18 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2015-08-02 17:14:18 -0600 |
commit | 8423e57caae976cddbc1f9f68ebf6fef595cae83 (patch) | |
tree | 97746f9a2a68398bc9ae1064c1bc4e81ce8b48ef /gcc/builtins.c | |
parent | 8ebca419e837774146ef77574580456107d7315b (diff) | |
download | gcc-8423e57caae976cddbc1f9f68ebf6fef595cae83.zip gcc-8423e57caae976cddbc1f9f68ebf6fef595cae83.tar.gz gcc-8423e57caae976cddbc1f9f68ebf6fef595cae83.tar.bz2 |
c.opt (-Wframe-address): New warning option.
gcc/ChangeLog
2015-07-28 Martin Sebor <msebor@redhat.com>
* c-family/c.opt (-Wframe-address): New warning option.
* doc/invoke.texi (Wframe-address): Document it.
* doc/extend.texi (__builtin_frame_address, __builtin_return_address):
Clarify possible effects of calling the functions with non-zero
arguments and mention -Wframe-address.
* builtins.c (expand_builtin_frame_address): Handle -Wframe-address.
gcc/testsuite/ChangeLog
2015-07-28 Martin Sebor <msebor@redhat.com>
* g++.dg/Wframe-address-in-Wall.C: New test.
* g++.dg/Wframe-address.C: New test.
* g++.dg/Wno-frame-address.C: New test.
* gcc.dg/Wframe-address-in-Wall.c: New test.
* gcc.dg/Wframe-address.c: New test.
* gcc.dg/Wno-frame-address.c: New test.
From-SVN: r226480
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index d7eb65f..eb7b7b2 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4551,34 +4551,38 @@ expand_builtin_frame_address (tree fndecl, tree exp) { /* The argument must be a nonnegative integer constant. It counts the number of frames to scan up the stack. - The value is the return address saved in that frame. */ + The value is either the frame pointer value or the return + address saved in that frame. */ if (call_expr_nargs (exp) == 0) /* Warning about missing arg was already issued. */ return const0_rtx; else if (! tree_fits_uhwi_p (CALL_EXPR_ARG (exp, 0))) { - if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) - error ("invalid argument to %<__builtin_frame_address%>"); - else - error ("invalid argument to %<__builtin_return_address%>"); + error ("invalid argument to %qD", fndecl); return const0_rtx; } else { - rtx tem - = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl), - tree_to_uhwi (CALL_EXPR_ARG (exp, 0))); + /* Number of frames to scan up the stack. */ + unsigned HOST_WIDE_INT count = tree_to_uhwi (CALL_EXPR_ARG (exp, 0)); + + rtx tem = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl), count); /* Some ports cannot access arbitrary stack frames. */ if (tem == NULL) { - if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) - warning (0, "unsupported argument to %<__builtin_frame_address%>"); - else - warning (0, "unsupported argument to %<__builtin_return_address%>"); + warning (0, "unsupported argument to %qD", fndecl); return const0_rtx; } + if (count) + { + /* Warn since no effort is made to ensure that any frame + beyond the current one exists or can be safely reached. */ + warning (OPT_Wframe_address, "calling %qD with " + "a nonzero argument is unsafe", fndecl); + } + /* For __builtin_frame_address, return what we've got. */ if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) return tem; |