This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug inline-asm/11807] GCC should error out when clobbering the stack or frame pointer
- From: "bmills at andrew dot cmu dot edu" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 21 Nov 2003 09:56:03 -0000
- Subject: [Bug inline-asm/11807] GCC should error out when clobbering the stack or frame pointer
- References: <20030805124527.11807.aw11@os.inf.tu-dresden.de>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From bmills at andrew dot cmu dot edu 2003-11-21 09:55 -------
(In reply to comment #12)
> > Presumably if the programmer is intentionally, explicitly clobbering
> > the frame pointer, the base pointer, or both using inline assembly,
> > they are doing so knowing full well what they are doing
>....
> If they knew what they were doing, they would realize
> that clobbering the frame pointer will throw the compiler into a
> tizzy and WILL NEVER WORK.
Just because you know not to trust the compiler, that doesn't mean that trusting
the compiler to generate correct code is unreasonable. There are two
assumptions that a programmer could make regarding the compiler: that the
compiler writer knows how their code works and has it behave in reasonable ways;
or that the compiler writer has forgotton or ignored some cases, which are
broken. If the latter is the better assumption, no one should ever compile code
with GCC because they *may* be using broken features -- there's no way to
reliably tell which ones are and which ones aren't. This is clearly not an
assumption that you want users to be making if you want your compiler to be
taken seriously.
Anything that can be fed successfully to the compiler should produce correct
output; it should never be possible to "throw the compiler into a tizzy",
because the compiler should have some well-defined behaviour for every allowable
piece of code that it processes. It *does* have control over every line of code
it generates.
Your point here (and one that seems to be repeated far too often) seems to be
that no one should use a language in a subtle, unusual way -- which has clearly
not been the case, and probably never will be. Programmers will always push the
system as far as it can go, and the system should (and historically has, for the
most part) be able to handle it.
In a compiler with a robust register allocator, it *is* possible for the
compiler to deal with these very sorts of edge cases in a well-defined and
intuitive manner, and whether they "work" in the sense that the programmer
intended or not, they should at the bare minimum "work" in the sense that they
do something anticipatable and rational (see comment #9 for suggestions of what
that well-defined, rational behaviour could be). Some possibilities for dealing
with the frame pointer include saving before the clobber and restoring after,
and using a safer (and probably slower) stack discipline in the presence of
volatile stack frames.
If the code "WILL NEVER WORK" in the compiler, that's because the compiler
contains errors -- and errors should be corrected, not avoided.
> The nature of GCC's inline assembly is unfortunate. It's extremely
> powerful, but it exposes so much of compiler internals that you have
> to know how the compiler works so as to avoid invalid corner cases.
Saying "it's ok for the compiler to generate invalid code because it's a corner
case" is equivalent to saying "Apache may immediately crash upon receiving a
malformed HTTP request" or "bash can accept strings into a buffer without
performing any buffer length checks", which are clearly false -- corner cases,
which have been thoroughly considered and handled in a robust manner (or at
least that's what we expect). When it comes to programming, corner cases are a
fact of life -- and they have to be dealt with responsibly rather than swept
under the rug. It is the compiler-writer's duty to resolve corner cases in the
compiler, not the programmer's -- they have their own set to worry about.
> > The assertion that there is no useful application for such clobbering
> > is false, as careful adjusting of the frame and base pointers in
> > assembly interleaved with struct/array accesses in C can produce ...
>
> ... a mess. Use out-of-line assembly if you're going to be playing
> with such stack frame fundamentals.
Once again, if the language accepted by the compiler contains unusual
constructs, they *must* be compiled correctly or else the compiler is *broken*.
I have successfully written a context switch even in the presence of the
current stack frame bugs -- by doing so in a function with no local variables.
If I were to re-write the code in pure assembly, I would either have to
completely commit myself to a particular, unrefinable data structure for storing
process information, or check all of my assembly offsets every time I made a
change. If I didn't want to use the features of GCC to my advantage, I would
have written it in assembly to begin with -- but higher-level languages are much
more elegant, especially when large, complex data structures are concerned.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11807