[Bug other/56955] New: documentation for attribute malloc contradicts itself
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56955 Bug #: 56955 Summary: documentation for attribute malloc contradicts itself Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: other AssignedTo: unassig...@gcc.gnu.org ReportedBy: sunf...@google.com The GCC manual's definition of the malloc function attribute is: "The malloc attribute is used to tell the compiler that a function may be treated as if any non-NULL pointer it returns cannot alias any other pointer valid when the function returns and that the memory has undefined content. This often improves optimization. Standard functions with this property include malloc and calloc. realloc-like functions do not have this property as the memory pointed to does not have undefined content." It says that the attribute implies that allocated memory has undefined content, but then it says that calloc has this property, despite the fact that memory allocated by calloc has well-defined content. Since calloc is already marked with this attribute in lots of places (including GLIBC), and since the undefined-content part of this attribute seems less important than the aliasing part for optimizers anyway, I suggest just removing the undefined-content language from the description of the attribute. Also, the last sentence says that realloc-like functions don't qualify since their memory does not have undefined content. The comment on GLIBC's declaration of realloc says that realloc doesn't qualify since the returned pointer may alias the argument pointer (for some definition of alias). GLIBC's comment seems more likely to be the real reason, and it doesn't rely on the undefined-content language.
[Bug c/56956] New: ftrapv traps on valid abs-like code
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56956 Bug #: 56956 Summary: ftrapv traps on valid abs-like code Classification: Unclassified Product: gcc Version: 4.7.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: sunf...@google.com This program aborts when compiled with -ftrapv, despite not having any overflow: #include #include #include __attribute__((noinline)) uint64_t foo(uint64_t x) { return x <= INT64_MAX ? x : -x; } int main() { uint64_t n = foo((uint64_t)INT64_MIN); printf("%" PRIx64 "\n", n); return 0; } It appears that the code in foo is being folded into an absolute-value expression which does not work properly on INT64_MIN. However, the code as written does handle INT64_MIN without any signed overflow.
[Bug other/56955] documentation for attribute malloc contradicts itself
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56955 --- Comment #2 from Dan Gohman 2013-04-14 19:47:42 UTC --- (In reply to comment #1) > I think it is talking about the memory returned by malloc/calloc will not > point > to another memory location while realloc can. I agree that's essentially what it ought to talk about, and the bug is that it's talking about something else -- the contents of the pointed-to memory.
[Bug c/56956] ftrapv traps on valid abs-like code
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56956 --- Comment #2 from Dan Gohman 2013-04-15 03:53:10 UTC --- (In reply to comment #1) > I think 'x' can not present negative value. The unary minus operator is defined for unsigned types. It doesn't produce signed overflow.
[Bug c/56956] ftrapv traps on valid abs-like code
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56956 --- Comment #3 from Dan Gohman 2013-04-15 03:54:32 UTC --- Pulling the unary minus out into a separate statement, like this: uint64_t y = -x; return x <= INT64_MAX ? x : -y; causes the program to execute correctly.
[Bug c/56956] ftrapv traps on valid abs-like code
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56956 --- Comment #5 from Dan Gohman 2013-04-15 05:12:30 UTC --- (In reply to comment #4) > (In reply to comment #2) > > (In reply to comment #1) > > > I think 'x' can not present negative value. > > > > The unary minus operator is defined for unsigned types. It doesn't produce > > signed overflow. > > According to C99 6.5.3.3 Point 3 and C99 6.5 Point 5: > > "The result of the unary '-' operator is the negative of its operand." > > "... if the result is ... not in the range of representable > values for its type... the behavior is undefined." > > So my understanding is that the evaluation expression '-x' is not > a representable value of 'uint64_t', which is undefined behavior, > resulting abort if -ftrav is issued. > > Perhaps my understanding is incorrect? :( Yes; unsigned types are an exception to the rule: C99 6.2.5p9 says "A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type." The wording is a little vague, but it means that negative results are converted to unsigned values by conceptually adding the maximum unsigned value plus one until the value is in range.
[Bug c/56956] ftrapv traps on valid abs-like code
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56956 --- Comment #6 from Dan Gohman 2013-04-15 05:14:27 UTC --- (In reply to comment #3) > Pulling the unary minus out into a separate statement, like this: > > uint64_t y = -x; > return x <= INT64_MAX ? x : -y; > > causes the program to execute correctly. Actually, I meant to write this: uint64_t y = -x; return x <= INT64_MAX ? x : y; and it still executes correctly, with no trap.
[Bug other/56955] documentation for attribute malloc contradicts itself
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56955 --- Comment #4 from Dan Gohman 2013-04-15 14:53:06 UTC --- (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. 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? > 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.