aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2015-08-02 23:14:18 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2015-08-02 17:14:18 -0600
commit8423e57caae976cddbc1f9f68ebf6fef595cae83 (patch)
tree97746f9a2a68398bc9ae1064c1bc4e81ce8b48ef /gcc/builtins.c
parent8ebca419e837774146ef77574580456107d7315b (diff)
downloadgcc-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.c28
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;