This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug other/56955] documentation for attribute malloc contradicts itself
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 21 May 2014 12:09:08 +0000
- Subject: [Bug other/56955] documentation for attribute malloc contradicts itself
- Auto-submitted: auto-generated
- References: <bug-56955-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56955
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2014-05-21
CC| |rguenth at gcc dot gnu.org
Ever confirmed|0 |1
--- Comment #15 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Dan Gohman from comment #4)
> (In reply to comment #3)
> > Well, it _is_ actually about the content. There must be no way to compute
> > a valid pointer to another object from the contents of the pointed-to
> > memory.
>
> Oh wow. That's a subtlety that completely escaped me.
>
> > So if you initialize the memory to {0, 1, 2, 3, 4 ...} thus
> > every possible byte value is somewhere and then do
> >
> > void *p = (void *)(mem[3] << 24 | mem[58] << 16 | ...);
> >
> > then points-to analysis assumes that from the contents of 'mem' you
> > can only compute pointers to nothing (NULL).
>
> Is that example fundamentally different than something like this:
>
> void *q = (void *)(mem[0] + 0xb1ab1ab1a);
>
> In both cases, the information of the pointer value is in the expression,
> not in the memory.
It's exactly the same.
> Is it the case that the memory must be either actually zeros or
> uninitialized? Or could it contain other data which merely transmits no
> information about pointer values?
There must be no way to "compute" a pointer to an object by _just_
combining bits and bytes of that memory cleverly. So for example
initializing the memory to -1 (all bits set) would not work as you can compute
a zero from 1 ^ 1 and thus any possible pointer value. That's not
possible for zero. Oh wait, you can do ~0. Hmm ... subtle ;)
Ok, we ignore pointer values computed from FP values as well, thus
I guess technically only undefined content is really really valid.
Practically memory with non-pointer values is ok unless you play evil
(or very evil) games outlined above.
> > Technically for targets
> > where NULL is a valid poiner to an object calloc () may not be marked
> > with malloc.
> >
> > That is, read it in the way that the code assumes the memory _may_ be
> > zero-initialized (but only zero-initialized) or uninitialized.
>
> If this is what it means, then I request that the text be updated to say
> this. I'd be willing to propose a wording, once I understand the intent, if
> that'd be helpful.
>
> What should we say about the fact that GLIBC uses the malloc attribute on
> strdup (and similar things)? strdup actually could be used to transmit
> information about pointer values.
True. See above though.
Note that the actual implementation (as opposed to what would be allowed
by the documentation) does:
/* If this is not a real malloc call assume the memory was
initialized and thus may point to global memory. All
builtin functions with the malloc attribute behave in a sane way. */
if (!fndecl
|| DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
make_constraint_from (vi, nonlocal_id);
and thus restricts this to "known" functions (not only malloc, but also
strdup which we just expect you don't use to transfer pointers ...).
As of 'realloc' - yes we can special-case that in the compiler (we don't
do that), but we can't really re-use the existing 'malloc' attribute for that.
The proposed revised documentation looks like a good improvement to me,
Paul, can you post it to gcc-patches@?