[LLVMdev] optimization assumes malloc return is non-null
Mike Stump
mrs at apple.com
Thu May 1 11:42:56 PDT 2008
On Apr 30, 2008, at 2:20 PM, Jonathan S. Shapiro wrote:
> The standard library specification of malloc() clearly requires that
> it
> allocates storage
No, your interpretation is wrong. When the standard says:
void *malloc(size_t size);
Description
[#2] The malloc function allocates space for an object
they don't mean that the malloc function allocates space for an
object. What they mean is that you cannot write a program that can
notice that it didn't allocate space for an object. The difference is
subtle, but important.
As an example, compare:
#include <stdlib.h>
void *vp;
int main(int argc, char** argv){
if((vp=malloc(sizeof(int))) == NULL){ return 0; }
else{ return 1; }
}
with -fwhole-program the call to malloc goes away. Without it, it
stays.
If we change it to:
#include <stdlib.h>
void * volatile vp;
int foo(int argc, char** argv){
if((vp=malloc(sizeof(int))) == NULL){ return 0; }
else{ return 1; }
}
it stays. If change it to:
#include <stdlib.h>
void * volatile vp;
int main(int argc, char** argv){
if((vp=malloc(sizeof(int))) == NULL){ return 0; }
else{ return 1; }
}
it then stays. This is because you're allowed to observe malloc
through vp as it is volatile. Observing the program with writes and
reads to volatile variables and the I/O behavior of the program are
only ways in which you get to observe the program.
> I do not believe that any such overt statement is required in order
> for it to be clear that malloc() is stateful.
You can observe the behavior with I/O and volatiles, all that you
observe meets the requirements for the semantics according the to
standard. malloc need preserve no state or even change state. The
standard has no mechanism to require that. It only says the program
is required to behave as if describe by the standard.
> The functional description of malloc() and free() clearly cannot be
> satisfied under the C abstract machine without mutation of at least
> one object.
Wrong. In int main() { malloc (4); return 0; } there are 0 writes to
volatile storage. There are 0 input routines called, there are 0
output routines called. The abstract semantics are return 0 to the
environment with no input and no output. Any program that does that,
is a valid compilation of the code.
Another equally valid translation would be:
int d[100];
int foo() { return 100; }
main() {
for (i = 0; i<foo(); ++i)
d[i] = i;
return 0;
}
thats because the abstract semantics of that program are exactly
identical to the required abstract semantics of the first.
> Setting the matter of the standard entirely aside, the currently
> implemented behavior deviates so blatantly from common sense
Most people have no clue just what as if means. People that write
compilers are expected to know what it means. If one doesn't, they
should learn.
> and universal convention that it really must be viewed as a bug.
You can state the required abstract semantics of the program and you
can state the actual semantics of the translation and we can string
compare them, if they are identical, we get to say, that is a valid
compilation of the code.
More information about the llvm-dev
mailing list