For their virtual definition of malloc used by the optimizer, it's allowed to be treated as if it may always succeed and is also treated as having no external side effects outside the program. Neither of those is really true, but that's the C virtual machine they implement.
Conversation
How so? The memory model and address space aren't something defined. Pointers aren't inherently limited to addressing only the space reflected by their size. In practice, that call cannot succeed, but those semantics aren't what is standardized or implemented by compilers at all.
2
By deciding they can remove malloc(4), they've decided that the side effects or potential for failure don't need to be treated as observable. It's not that much further for them to then decide to use a virtual definition of it where it can be treated as potentially succeeding.
1
There are a lot of things that are explicitly undefined in the standard specifically to permit odd implementations of C with (mostly) precise garbage collection, etc. Pointers aren't really defined as addresses either and int conversions / arithmetic are very constrained by that.
1
Convert a pointer to an integer. Write the integer to a pipe, read it from the other end of the pipe and convert it back to a pointer. Dereferencing that pointer or even just doing any arithmetic on it is undefined and will even be broken by Clang / GCC optimization in practice.
3
I see your sentiments, but the above is incorrect or glossing over something important. Pointer escaping via write() is no different from escaping via any other function. Note how this is different from e.g. obtaining a not-escaping pointer value with a debugger.
1
1
You're trying to reason about it as a logical system providing native semantics which it isn't. The compilers have knowledge about standard library functions and they don't simply act the way they're defined in the library. My example is just something they consider undefined.
1
A very easy example to demonstrate is strdup. It's considered to have __attribute__((malloc)) (whether or not the libc marks it as such like glibc does) which includes guaranteeing:
> no pointers to valid objects occur in any storage addressed by P.
which can clearly happen.
2
Clearly __attribute__((__malloc__)) is wrong for strdup - the pointed-to memory is initialized with something other than all 0 bytes, controlled by the caller, and thus could contain valid pointers to objects (in practice, only possible on 32-bit archs).
1
It's logically wrong, but it's not wrong based on how they define pointers as working in their model. It's not allowed to convert a pointer to some other representation and then back to a pointer in a way that doesn't fit some vague rules about provenance.
There's also cl.cam.ac.uk/~pes20/cerberu about this along with rules in the C++14 standard aimed at making a more formal and official definition of what compilers are doing based on their aggressive interpretation: timepp.github.io/doc/cpp14/basi. You can consider it wrong, but they do it.
Sure it is. You're completely misreading the provenance rules, likely largely because DR260 is a steaming 💩.
1
The language explicitly supports conversions to/from string/file format (%p) and to/from integer values and these have to work regardless of what intermediate steps the value went through. What doesn't have to work is one derived from a different happens-to-be-numerically-eq ptr.


