[Bug other/56955] New: documentation for attribute malloc contradicts itself

2013-04-14 Thread sunfish at google dot com


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

2013-04-14 Thread sunfish at google dot com


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

2013-04-14 Thread sunfish at google dot com


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

2013-04-14 Thread sunfish at google dot com


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

2013-04-14 Thread sunfish at google dot com


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

2013-04-14 Thread sunfish at google dot com

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

2013-04-14 Thread sunfish at google dot com


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

2013-04-15 Thread sunfish at google dot com


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.