Commit 8423e57c by Martin Sebor Committed by Martin Sebor

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
parent 8ebca419
2015-08-02 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.
2015-08-01 Michael Collison <michael.collison@linaro.org 2015-08-01 Michael Collison <michael.collison@linaro.org
Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
......
...@@ -4551,34 +4551,38 @@ expand_builtin_frame_address (tree fndecl, tree exp) ...@@ -4551,34 +4551,38 @@ expand_builtin_frame_address (tree fndecl, tree exp)
{ {
/* The argument must be a nonnegative integer constant. /* The argument must be a nonnegative integer constant.
It counts the number of frames to scan up the stack. 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) if (call_expr_nargs (exp) == 0)
/* Warning about missing arg was already issued. */ /* Warning about missing arg was already issued. */
return const0_rtx; return const0_rtx;
else if (! tree_fits_uhwi_p (CALL_EXPR_ARG (exp, 0))) else if (! tree_fits_uhwi_p (CALL_EXPR_ARG (exp, 0)))
{ {
if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) error ("invalid argument to %qD", fndecl);
error ("invalid argument to %<__builtin_frame_address%>");
else
error ("invalid argument to %<__builtin_return_address%>");
return const0_rtx; return const0_rtx;
} }
else else
{ {
rtx tem /* Number of frames to scan up the stack. */
= expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl), unsigned HOST_WIDE_INT count = tree_to_uhwi (CALL_EXPR_ARG (exp, 0));
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. */ /* Some ports cannot access arbitrary stack frames. */
if (tem == NULL) if (tem == NULL)
{ {
if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) warning (0, "unsupported argument to %qD", fndecl);
warning (0, "unsupported argument to %<__builtin_frame_address%>");
else
warning (0, "unsupported argument to %<__builtin_return_address%>");
return const0_rtx; 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. */ /* For __builtin_frame_address, return what we've got. */
if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS) if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
return tem; return tem;
......
...@@ -295,6 +295,10 @@ Wbool-compare ...@@ -295,6 +295,10 @@ Wbool-compare
C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about boolean expression compared with an integer value different from true/false Warn about boolean expression compared with an integer value different from true/false
Wframe-address
C ObjC C++ ObjC++ Var(warn_frame_address) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn when __builtin_frame_address or __builtin_return_address is used unsafely
Wbuiltin-macro-redefined Wbuiltin-macro-redefined
C ObjC C++ ObjC++ CPP(warn_builtin_macro_redefined) CppReason(CPP_W_BUILTIN_MACRO_REDEFINED) Var(cpp_warn_builtin_macro_redefined) Init(1) Warning C ObjC C++ ObjC++ CPP(warn_builtin_macro_redefined) CppReason(CPP_W_BUILTIN_MACRO_REDEFINED) Var(cpp_warn_builtin_macro_redefined) Init(1) Warning
Warn when a built-in preprocessor macro is undefined or redefined Warn when a built-in preprocessor macro is undefined or redefined
......
...@@ -8652,8 +8652,11 @@ to determine if the top of the stack has been reached. ...@@ -8652,8 +8652,11 @@ to determine if the top of the stack has been reached.
Additional post-processing of the returned value may be needed, see Additional post-processing of the returned value may be needed, see
@code{__builtin_extract_return_addr}. @code{__builtin_extract_return_addr}.
This function should only be used with a nonzero argument for debugging Calling this function with a nonzero argument can have unpredictable
purposes. effects, including crashing the calling program. As a result, calls
that are considered unsafe are diagnosed when the @option{-Wframe-address}
option is in effect. Such calls should only be made in debugging
situations.
@end deftypefn @end deftypefn
@deftypefn {Built-in Function} {void *} __builtin_extract_return_addr (void *@var{addr}) @deftypefn {Built-in Function} {void *} __builtin_extract_return_addr (void *@var{addr})
...@@ -8691,8 +8694,11 @@ any function other than the current one; in such cases, or when the top ...@@ -8691,8 +8694,11 @@ any function other than the current one; in such cases, or when the top
of the stack has been reached, this function returns @code{0} if of the stack has been reached, this function returns @code{0} if
the first frame pointer is properly initialized by the startup code. the first frame pointer is properly initialized by the startup code.
This function should only be used with a nonzero argument for debugging Calling this function with a nonzero argument can have unpredictable
purposes. effects, including crashing the calling program. As a result, calls
that are considered unsafe are diagnosed when the @option{-Wframe-address}
option is in effect. Such calls should only be made in debugging
situations.
@end deftypefn @end deftypefn
@node Vector Extensions @node Vector Extensions
......
...@@ -241,7 +241,7 @@ Objective-C and Objective-C++ Dialects}. ...@@ -241,7 +241,7 @@ Objective-C and Objective-C++ Dialects}.
-pedantic-errors @gol -pedantic-errors @gol
-w -Wextra -Wall -Waddress -Waggregate-return @gol -w -Wextra -Wall -Waddress -Waggregate-return @gol
-Waggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol -Waggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
-Wbool-compare @gol -Wbool-compare -Wframe-address @gol
-Wno-attributes -Wno-builtin-macro-redefined @gol -Wno-attributes -Wno-builtin-macro-redefined @gol
-Wc90-c99-compat -Wc99-c11-compat @gol -Wc90-c99-compat -Wc99-c11-compat @gol
-Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol -Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol
...@@ -4462,6 +4462,13 @@ if ((n > 1) == 2) @{ @dots{} @} ...@@ -4462,6 +4462,13 @@ if ((n > 1) == 2) @{ @dots{} @}
@end smallexample @end smallexample
This warning is enabled by @option{-Wall}. This warning is enabled by @option{-Wall}.
@item -Wframe-address
@opindex Wno-frame-address
@opindex Wframe-address
Warn when the @samp{__builtin_frame_address} or @samp{__builtin_return_address}
is called with an argument greater than 0. Such calls may return indeterminate
values or crash the program. The warning is included in @option{-Wall}.
@item -Wno-discarded-qualifiers @r{(C and Objective-C only)} @item -Wno-discarded-qualifiers @r{(C and Objective-C only)}
@opindex Wno-discarded-qualifiers @opindex Wno-discarded-qualifiers
@opindex Wdiscarded-qualifiers @opindex Wdiscarded-qualifiers
......
2015-08-02 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.
2015-08-02 Patrick Palka <ppalka@gcc.gnu.org> 2015-08-02 Patrick Palka <ppalka@gcc.gnu.org>
* c-c++-common/Wmisleading-indentation.c: Add more tests. * c-c++-common/Wmisleading-indentation.c: Add more tests.
......
// { dg-do compile }
// { dg-options "-Wall" }
// Verify that -Wframe-address is included in -Wall.
void* test_builtin_address (unsigned i)
{
void* const ba[] = {
__builtin_frame_address (4), // { dg-warning "builtin_frame_address" }
__builtin_return_address (4) // { dg-warning "builtin_return_address" }
};
return ba [i];
}
// { dg-do compile }
// { dg-options "-Wframe-address" }
static void* const fa[] = {
__builtin_frame_address (0),
__builtin_frame_address (1), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (2), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (3), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (4) // { dg-warning "builtin_frame_address" }
};
static void* const ra[] = {
__builtin_return_address (0),
__builtin_return_address (1), // { dg-warning "builtin_return_address" }
__builtin_return_address (2), // { dg-warning "builtin_return_address" }
__builtin_return_address (3), // { dg-warning "builtin_return_address" }
__builtin_return_address (4) // { dg-warning "builtin_return_address" }
};
void* __attribute__ ((noclone, noinline))
test_builtin_frame_address (unsigned i)
{
void* const fa[] = {
__builtin_frame_address (0),
__builtin_frame_address (1), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (2), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (3), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (4) // { dg-warning "builtin_frame_address" }
};
return fa [i];
}
void* __attribute__ ((noclone, noinline))
test_builtin_return_address (unsigned i)
{
void* const ra[] = {
__builtin_return_address (0),
__builtin_return_address (1), // { dg-warning "builtin_return_address" }
__builtin_return_address (2), // { dg-warning "builtin_return_address" }
__builtin_return_address (3), // { dg-warning "builtin_return_address" }
__builtin_return_address (4) // { dg-warning "builtin_return_address" }
};
return ra [i];
}
int main ()
{
test_builtin_frame_address (0);
test_builtin_return_address (0);
void* const a[] = {
__builtin_frame_address (0),
__builtin_frame_address (1), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (2), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (3), // { dg-warning "builtin_frame_address" }
__builtin_frame_address (4), // { dg-warning "builtin_frame_address" }
__builtin_return_address (0),
__builtin_return_address (1), // { dg-warning "builtin_return_address" }
__builtin_return_address (2), // { dg-warning "builtin_return_address" }
__builtin_return_address (3), // { dg-warning "builtin_return_address" }
__builtin_return_address (4) // { dg-warning "builtin_return_address" }
};
}
// { dg-do compile }
// { dg-options "-Werror" }
// Verify that -Wframe-address is not enabled by default by enabling
// -Werror and verifying the test still compiles.
#include "Wframe-address.C"
/* { dg-do compile } */
/* { dg-options "-Wall" } */
/* Verify that -Wframe-address is included in -Wall. */
void* test_builtin_address (unsigned i)
{
void* const ba[] = {
__builtin_frame_address (4), /* { dg-warning "builtin_frame_address" } */
__builtin_return_address (4) /* { dg-warning "builtin_return_address" } */
};
return ba [i];
}
/* { dg-do compile } */
/* { dg-options "-Wframe-address" } */
void* __attribute__ ((noclone, noinline))
test_builtin_frame_address (unsigned i)
{
void* const fa[] = {
__builtin_frame_address (0),
__builtin_frame_address (1), /* { dg-warning "builtin_frame_address" } */
__builtin_frame_address (2), /* { dg-warning "builtin_frame_address" } */
__builtin_frame_address (3), /* { dg-warning "builtin_frame_address" } */
__builtin_frame_address (4) /* { dg-warning "builtin_frame_address" } */
};
return fa [i];
}
void* __attribute__ ((noclone, noinline))
test_builtin_return_address (unsigned i)
{
void* const ra[] = {
__builtin_return_address (0),
__builtin_return_address (1), /* { dg-warning "builtin_return_address" } */
__builtin_return_address (2), /* { dg-warning "builtin_return_address" } */
__builtin_return_address (3), /* { dg-warning "builtin_return_address" } */
__builtin_return_address (4) /* { dg-warning "builtin_return_address" } */
};
return ra [i];
}
int main (void)
{
test_builtin_frame_address (0);
test_builtin_return_address (0);
void* const a[] = {
__builtin_frame_address (0),
__builtin_frame_address (1), /* { dg-warning "builtin_frame_address" } */
__builtin_frame_address (2), /* { dg-warning "builtin_frame_address" } */
__builtin_frame_address (3), /* { dg-warning "builtin_frame_address" } */
__builtin_frame_address (4), /* { dg-warning "builtin_frame_address" } */
__builtin_return_address (0),
__builtin_return_address (1), /* { dg-warning "builtin_return_address" } */
__builtin_return_address (2), /* { dg-warning "builtin_return_address" } */
__builtin_return_address (3), /* { dg-warning "builtin_return_address" } */
__builtin_return_address (4) /* { dg-warning "builtin_return_address" } */
};
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Werror" } */
/* Verify that -Wframe-address is not enabled by default by enabling
-Werror and verifying the test still compiles. */
#include "Wframe-address.c"
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