public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/17665] New:
@ 2004-09-24 23:13 gcc-bugzilla at gcc dot gnu dot org
  2004-09-24 23:39 ` [Bug c/17665] wrong code with -O2 pinskia at gcc dot gnu dot org
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: gcc-bugzilla at gcc dot gnu dot org @ 2004-09-24 23:13 UTC (permalink / raw)
  To: gcc-bugs



The wrong code is generated for -O2 on a dereference of a pointer to a 'void
*'.

Environment:
System: Linux youknow.youwant.to 2.4.20-28.7smp #1 SMP Thu Dec 18 11:18:31 EST 2003 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../configure --enable-languages=c++,java --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --program-suffix=342

How-To-Repeat:

#include <stdio.h>
#include <stdlib.h>

// Optimization issue with g++ 2.96 and 3.4.2 and probably others.
// With -O2, I get "3 1 0" and "3 1 2"
// With -O1, I get "3 1 2" and "3 1 2"

void *GetBlocks(void)
{
 void *block1=malloc(64);
 void *block2=malloc(64);
 void *block3=malloc(64);
 *(void **) block1=block2;
 *(void **) block2=block3;
 *(void **) block3=NULL;
 return block1;
}

int CountList(void *a)
{
 int ret=0;
 while(a!=NULL)
 {
  ret++;
  a=*(void **) a;
 }
 return ret;
}


void RemoveOneA(void *head)
{
 int l1, l2, l3;
 void *newhead;
 l1=CountList(head);
 newhead=*(void **) head;
 *(char **) head=NULL;
 l2=CountList(head);
 l3=CountList(newhead);
 printf("%d %d %d\n", l1, l2, l3);
}

void RemoveOneB(void *head)
{
 int l1, l2, l3;
 void *newhead;
 l1=CountList(head);
 newhead=*(char **) head;
 *(char **) head=0;
 l2=CountList(head);
 l3=CountList(newhead);
 printf("%d %d %d\n", l1, l2, l3);
}

int main(void)
{
 RemoveOneA(GetBlocks());
 RemoveOneB(GetBlocks());
}
------- Additional Comments From davids at webmaster dot com  2004-09-24 23:13 -------
Fix:

The same code should be generated. Or see the other 'RemoveOne'
implementation.

David Schwartz
<davids@webmaster.com>

-- 
           Product: gcc
           Version: 3.4.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P1
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: davids at webmaster dot com
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
@ 2004-09-24 23:39 ` pinskia at gcc dot gnu dot org
  2004-09-25  5:41 ` davids at webmaster dot com
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-09-24 23:39 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-09-24 23:39 -------
 newhead=*(void **) head;
 *(char **) head=NULL;

You are violating aliasing rules here. Either fix your code or use -fno-strict-aliasing.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID
            Summary|                            |wrong code with -O2


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
  2004-09-24 23:39 ` [Bug c/17665] wrong code with -O2 pinskia at gcc dot gnu dot org
@ 2004-09-25  5:41 ` davids at webmaster dot com
  2004-09-25  8:48 ` jsm at polyomino dot org dot uk
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: davids at webmaster dot com @ 2004-09-25  5:41 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From davids at webmaster dot com  2004-09-25 05:41 -------
I am perfectly willing to entertain the possibility that I am being dense or 
misguided, but we're talking about 'void *' here. You can't get a 'void *' by 
taking the address of a 'void' and you can't dereference a 'void *' to get 
a 'void'. The only use of 'void *' is for type aliasing.

If you cannot alias at all without '-fno-strict-aliasing', that would imply 
that you can do *nothing* with a 'void *' without defining it. That, obviously, 
can't be right.

The documentation for '-fstrict-aliasing' talks about an object of one type 
being at the same address as an object of another type. But 'void' is not a 
type of object, so I don't see that I'm violating aliasing rules.

DS


-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |UNCONFIRMED
         Resolution|INVALID                     |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
  2004-09-24 23:39 ` [Bug c/17665] wrong code with -O2 pinskia at gcc dot gnu dot org
  2004-09-25  5:41 ` davids at webmaster dot com
@ 2004-09-25  8:48 ` jsm at polyomino dot org dot uk
  2004-09-25 10:55 ` giovannibajo at libero dot it
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: jsm at polyomino dot org dot uk @ 2004-09-25  8:48 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From jsm at polyomino dot org dot uk  2004-09-25 08:48 -------
Subject: Re:  wrong code with -O2

On Sat, 25 Sep 2004, davids at webmaster dot com wrote:

> I am perfectly willing to entertain the possibility that I am being dense or 
> misguided, but we're talking about 'void *' here. You can't get a 'void *' by 
> taking the address of a 'void' and you can't dereference a 'void *' to get 
> a 'void'. The only use of 'void *' is for type aliasing.

Look at the code quoted.  You are using the same memory to store an object 
of type "void *" and an object of type "char *".  Although those objects 
have the same representation and alignment requirements, this is not 
permitted aliasing (whereas you could, for example, use the same memory to 
store "int" and "unsigned int").

> The documentation for '-fstrict-aliasing' talks about an object of one type 
> being at the same address as an object of another type. But 'void' is not a 
> type of object, so I don't see that I'm violating aliasing rules.

The problematic object types in your code are "void *" and "char *" 
(accessed by dereferencing "void **" and "char **" pointers), not "void" 
and "char".



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (2 preceding siblings ...)
  2004-09-25  8:48 ` jsm at polyomino dot org dot uk
@ 2004-09-25 10:55 ` giovannibajo at libero dot it
  2004-09-25 17:35 ` davids at webmaster dot com
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: giovannibajo at libero dot it @ 2004-09-25 10:55 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From giovannibajo at libero dot it  2004-09-25 10:55 -------
The solution is dereferencing the void**, and only then casting back to char*. 
Or at least I believe so, I haven't investigated your code that much.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (3 preceding siblings ...)
  2004-09-25 10:55 ` giovannibajo at libero dot it
@ 2004-09-25 17:35 ` davids at webmaster dot com
  2004-09-25 17:56 ` davids at webmaster dot com
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: davids at webmaster dot com @ 2004-09-25 17:35 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From davids at webmaster dot com  2004-09-25 17:35 -------
(In reply to comment #4)

> The problematic object types in your code are "void *" and "char *" 
> (accessed by dereferencing "void **" and "char **" pointers), not "void" 
> and "char".

This is legal C and C++. The *only* use for 'void *' is to alias something. If 
it was 'char *' and 'int *', I'd 100% agree with you. However, you are 
specifically permitted to alias 'void *'.

Other than returning NULL or using it in a union, there is nothing you can do 
with 'void *' other than to use it to hold the same thing as some other type.

A pointer to a void is not actually a pointer to a void, it's a generic pointer 
type. Its typical use, defined by the standard, is to cast other types through 
it.

Unless you can explain how my use of 'void *' differs from the types 
specifically permitted by the standard, calling this bug report invalid is 
equivalent to saying you can't use 'void *' without defining -fno-strict-
aliasing.

Basically, what I'm saying is that because the standard specifically allows 
(and precisely defined the affects of) casting other pointer types to 'void *', 
the compiler should not assume that a 'void *' isn't an alias of another type, 
thought it is entirely justified in doing so for other types.

DS


-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |UNCONFIRMED
         Resolution|INVALID                     |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (4 preceding siblings ...)
  2004-09-25 17:35 ` davids at webmaster dot com
@ 2004-09-25 17:56 ` davids at webmaster dot com
  2004-09-25 18:09 ` pinskia at gcc dot gnu dot org
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: davids at webmaster dot com @ 2004-09-25 17:56 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From davids at webmaster dot com  2004-09-25 17:56 -------
Is this code legal without -fno-strict-aliasing?

void *foo=malloc(sizeof(void *));
*(void **)foo=malloc(16);

DS


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (6 preceding siblings ...)
  2004-09-25 18:09 ` pinskia at gcc dot gnu dot org
@ 2004-09-25 18:09 ` pinskia at gcc dot gnu dot org
  2004-09-25 18:24 ` davids at webmaster dot com
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-09-25 18:09 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-09-25 18:09 -------
No read the standard again
What it says is that only char can aliasing anything and nothing else.
since you access it via both char* and void* that is what violates the aliasing rules.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (5 preceding siblings ...)
  2004-09-25 17:56 ` davids at webmaster dot com
@ 2004-09-25 18:09 ` pinskia at gcc dot gnu dot org
  2004-09-25 18:09 ` pinskia at gcc dot gnu dot org
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-09-25 18:09 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-09-25 18:09 -------
 newhead=*(void **) head;
 *(char **) head=NULL;
is undefined because of what I mentioned, nothing more than that.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (7 preceding siblings ...)
  2004-09-25 18:09 ` pinskia at gcc dot gnu dot org
@ 2004-09-25 18:24 ` davids at webmaster dot com
  2004-09-25 18:30 ` jsm at polyomino dot org dot uk
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: davids at webmaster dot com @ 2004-09-25 18:24 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From davids at webmaster dot com  2004-09-25 18:24 -------
Look in 'alias.c' and search for the string 'a void pointer'. The aliasing code 
is supposed to assume that a 'void *' can alias anything. The variable 'head' 
is a 'void *'.

I'll check the standard again, but my recollection is that it's supposed to be 
safe to cast any pointer to and from a 'void *'. That's why 'malloc' 
returns 'void *'.

DS


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (8 preceding siblings ...)
  2004-09-25 18:24 ` davids at webmaster dot com
@ 2004-09-25 18:30 ` jsm at polyomino dot org dot uk
  2004-09-26  0:28 ` davids at webmaster dot com
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: jsm at polyomino dot org dot uk @ 2004-09-25 18:30 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From jsm at polyomino dot org dot uk  2004-09-25 18:30 -------
Subject: Re:  wrong code with -O2

On Sat, 25 Sep 2004, davids at webmaster dot com wrote:

> I'll check the standard again, but my recollection is that it's supposed to be 
> safe to cast any pointer to and from a 'void *'. That's why 'malloc' 
> returns 'void *'.

The problematic dereference is not of a void * pointer, but of void ** and 
char ** pointers pointing to the same place.  You can use void * and 
double * pointers (for example) pointing to the same place (though 
dereferencing the void * pointer must involve casting it to char * or 
double *).  You can use int * and unsigned int * pointers pointing to the 
same place.  But you cannot use void ** and char ** pointers pointing to 
the same place.

The *value* of a void * pointer can safely be converted to another pointer 
type.  What you are doing is treating the *representation* of that pointer 
as being another type, via void ** and char ** pointers, and this is not 
safe.

Read 6.5#7 again.  Your object has one of void * and char * as effective 
type, but its value is being accessed as the other, which is not 
permitted: it is not within any of the listed cases.  You need to access 
the value as its effective type, then convert, rather than type punning 
the representation.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (9 preceding siblings ...)
  2004-09-25 18:30 ` jsm at polyomino dot org dot uk
@ 2004-09-26  0:28 ` davids at webmaster dot com
  2005-06-05  8:56 ` pinskia at gcc dot gnu dot org
  2005-06-05  8:57 ` pinskia at gcc dot gnu dot org
  12 siblings, 0 replies; 14+ messages in thread
From: davids at webmaster dot com @ 2004-09-26  0:28 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From davids at webmaster dot com  2004-09-26 00:28 -------

Ahh, I think I get it now. If I have:

void *foo;

Then 'foo' follows the aliasing rules for a 'void *'. But if I do:

(void **)foo

The fact that 'foo' is a 'void *' has no affect on aliasing because *I* casted 
it to a 'void **'. So it follows the aliasing rules for 'void **' because 
that's what I specifically asked it to do.

Thanks for your patience.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (10 preceding siblings ...)
  2004-09-26  0:28 ` davids at webmaster dot com
@ 2005-06-05  8:56 ` pinskia at gcc dot gnu dot org
  2005-06-05  8:57 ` pinskia at gcc dot gnu dot org
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-06-05  8:56 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-06-05 08:56 -------
Reopening to ...

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |UNCONFIRMED
         Resolution|INVALID                     |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug c/17665] wrong code with -O2
  2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
                   ` (11 preceding siblings ...)
  2005-06-05  8:56 ` pinskia at gcc dot gnu dot org
@ 2005-06-05  8:57 ` pinskia at gcc dot gnu dot org
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-06-05  8:57 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-06-05 08:57 -------
Mark as a dup of bug 21920.

*** This bug has been marked as a duplicate of 21920 ***

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17665


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2005-06-05  8:57 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-09-24 23:13 [Bug c/17665] New: gcc-bugzilla at gcc dot gnu dot org
2004-09-24 23:39 ` [Bug c/17665] wrong code with -O2 pinskia at gcc dot gnu dot org
2004-09-25  5:41 ` davids at webmaster dot com
2004-09-25  8:48 ` jsm at polyomino dot org dot uk
2004-09-25 10:55 ` giovannibajo at libero dot it
2004-09-25 17:35 ` davids at webmaster dot com
2004-09-25 17:56 ` davids at webmaster dot com
2004-09-25 18:09 ` pinskia at gcc dot gnu dot org
2004-09-25 18:09 ` pinskia at gcc dot gnu dot org
2004-09-25 18:24 ` davids at webmaster dot com
2004-09-25 18:30 ` jsm at polyomino dot org dot uk
2004-09-26  0:28 ` davids at webmaster dot com
2005-06-05  8:56 ` pinskia at gcc dot gnu dot org
2005-06-05  8:57 ` pinskia at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).