On 06/11/2015 04:05 PM, Martin Sebor wrote:
Attached is an updated patch for both GCC and the manual.
The patch implements the suggested warning, -Wbuiltin-address,
that issues diagnostics for unsafe calls of the builtin address
functions. Safe calls are those with arguments 0 or 1 anywhere
in a program and argument 2 outside of the main function (since
every function has main as its direct or indirect caller).
Tested on powerpc64le and x86_64 Linux.
Martin
The ChangeLog entries for gcc and testsuite:
2015-06-11 Martin Sebor <mse...@redhat.com>
* c-family/c.opt (-Wbuiltin-address): New warning option.
* doc/invoke.texi (Wbuiltin-address): Document it.
* doc/extend.texi (__builtin_frame_addrress,
__builtin_return_addrress):
Clarify possible effects of calling the functions with
non-zero arguments and mention -Wbuiltin-address.
* builtins.c (expand_builtin_frame_address): Handle
-Wbuiltin-address.
2015-06-11 Martin Sebor <mse...@redhat.com>
* g++.dg/Wbuiltin-address-in-Wall.C: New test.
* g++.dg/Wbuiltin-address.C: New test.
* g++.dg/Wno-builtin-address.C: New test.
* gcc.dg/Wbuiltin-address-in-Wall.c: New test.
* gcc.dg/Wbuiltin-address.c: New test.
* gcc.dg/Wno-builtin-address.c: New test.
PS A few notes about the changes.
There's the following comment in expand_builtin_frame_address:
/* Some ports cannot access arbitrary stack frames. */
just before a block of code where the function can lead to
an "invalid argument" warning which would cause the newly
added tests to fail (since the newly added warning wouldn't
be issued).
I tried to determine what ports these might be so I could add
conditionals to the tests to prevent false positives there but
couldn't find any.
You have to start thinking creatively. For example, consider ports
without dwarf2 unwinders :-) Consider ports where the linker inserts
stubs between caller & callee for various reasons Consider cases where
the next outermost frame is compiled by something other than GCC, or
perhaps was written in pure assembly. Or consider the case when we're
currently in a signal handling frame...
I wanted to also issue a warning for calls at file scope with
arguments greater than 1 (just like in main) but couldn't find
a way to determine that.
I also wanted to make the special treatment of main conditional
on whether or not -ffreestanding is in effect but flag_hosted
is not declared in builtins.c and bringing it into scope seemed
like too much of a change.
I'd be happy to modify the patch and add any of the above if
someone can suggest a way to do it without disrupting too much
code.
I don't think this is really an issue with calling with a non-zero
argument near the top of the stack, but more an issue of the general
difficulty in unwinding beyond the current frame.
It's relatively easy for the compiler to get the return address of the
current frame -- after all, the compiler knows everything about the
current function and can even arrange to avoid things which may make
finding the current frame's address difficult.
However, once you want to go back one frame, you're in an arbitrary hunk
of code and digging the prior frame out can be non-trivial.
You can get a sense of the complexities by looking at the GDB code to
find the saved pc and base of an arbitrary frame. It's insane,
especially in a world without dwarf2 unwind records.
So, my suggestion would be to warn for any call with a nonzero value.
Jeff