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
` (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 -------
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
` (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 -------
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).