* help with g++ and strict aliasing on x86-64
@ 2010-11-22 17:48 Alberto Griggio
2010-11-22 17:53 ` Alberto Griggio
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Alberto Griggio @ 2010-11-22 17:48 UTC (permalink / raw)
To: gcc-help
Hello,
I'm having trouble understanding what I'm doing wrong in the following piece
of code.
My OS is Debian GNU/Linux 5.0, compiler is
g++-4.1 (GCC) 4.1.3 20080704 (prerelease) (Debian 4.1.2-25)
platform x86-64
The following code results in abort() being called (sorry if it's a bit
long, but this is the smallest example I could come up with):
#include <new>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
struct Link { Link *next_; }; // __attribute__((__may_alias__));
struct Foo { void *value; };
struct Alloc {
Alloc() { head_ = NULL; }
~Alloc() {}
void *allocate()
{
static int cnt = 0;
if (head_ == NULL) {
if (cnt++) { abort(); }
Link *mem = static_cast<Link *>(malloc(sizeof(Link) * 3));
head_ = new (mem) Link;
Link *last = head_ + 2;
for (Link *p = head_; p < last; ++p) {
Link *next = new (p+1) Link;
p->next_ = next;
}
last->next_ = NULL;
}
Link *p = head_;
head_ = p->next_;
p->~Link();
return static_cast<void *>(p);
}
Link *head_;
};
struct FooAlloc {
Foo *alloc() { return new (p_.allocate()) Foo(); }
Alloc p_;
};
int main()
{
if (sizeof(Foo) != sizeof(Link)) { abort(); }
printf("here\n"); fflush(stdout);
FooAlloc pool;
Foo *e = pool.alloc();
if (e) {
printf("e\n"); fflush(stdout);
}
e = pool.alloc();
return 0;
}
If I uncomment the "may_alias" attribute, everything works. But I don't
quite understand why "may_alias" is needed here. Could somebody help please?
My understanding is that, since in Alloc::allocate() I'm calling the
destructor of p before returning a pointer to the memory in which it is
allocated, and in FooAllo::alloc() I'm constructing a new object in that
memory area, aliasing should not be an issue. I'm pretty sure I'm missing
something, but I can't see it... If somebody could help me, that would be
very much appreciated. FWIW, If I use gcc 4.3 on the same machine
(to be precise: gcc-4.3 (Debian 4.3.2-1.1) 4.3.2) abort() is not called.
Thanks in advance,
Alberto
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: help with g++ and strict aliasing on x86-64
2010-11-22 17:48 help with g++ and strict aliasing on x86-64 Alberto Griggio
@ 2010-11-22 17:53 ` Alberto Griggio
2010-11-22 18:12 ` Andrew Haley
2010-11-22 18:37 ` Ian Lance Taylor
2 siblings, 0 replies; 6+ messages in thread
From: Alberto Griggio @ 2010-11-22 17:53 UTC (permalink / raw)
To: gcc-help
> Hello,
> I'm having trouble understanding what I'm doing wrong in the following
> piece of code.
>
> My OS is Debian GNU/Linux 5.0, compiler is
> g++-4.1 (GCC) 4.1.3 20080704 (prerelease) (Debian 4.1.2-25)
> platform x86-64
Sorry, I realized I forgot to include the compilation flags required for
reproducing the problem:
g++-4.1 -O1 -fdelete-null-pointer-checks -fschedule-insns -fstrict-
aliasing -ftree-vrp
Alberto
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: help with g++ and strict aliasing on x86-64
2010-11-22 17:48 help with g++ and strict aliasing on x86-64 Alberto Griggio
2010-11-22 17:53 ` Alberto Griggio
@ 2010-11-22 18:12 ` Andrew Haley
2010-11-22 18:37 ` Ian Lance Taylor
2 siblings, 0 replies; 6+ messages in thread
From: Andrew Haley @ 2010-11-22 18:12 UTC (permalink / raw)
To: gcc-help
On 11/22/2010 04:41 PM, Alberto Griggio wrote:
> Hello,
> I'm having trouble understanding what I'm doing wrong in the following piece
> of code.
>
> My OS is Debian GNU/Linux 5.0, compiler is
> g++-4.1 (GCC) 4.1.3 20080704 (prerelease) (Debian 4.1.2-25)
> platform x86-64
>
> The following code results in abort() being called (sorry if it's a bit
> long, but this is the smallest example I could come up with):
>
> #include <new>
> #include <stdlib.h>
> #include <assert.h>
> #include <stdio.h>
>
> struct Link { Link *next_; }; // __attribute__((__may_alias__));
> struct Foo { void *value; };
>
> struct Alloc {
> Alloc() { head_ = NULL; }
> ~Alloc() {}
>
> void *allocate()
> {
> static int cnt = 0;
> if (head_ == NULL) {
> if (cnt++) { abort(); }
>
> Link *mem = static_cast<Link *>(malloc(sizeof(Link) * 3));
> head_ = new (mem) Link;
> Link *last = head_ + 2;
> for (Link *p = head_; p < last; ++p) {
> Link *next = new (p+1) Link;
> p->next_ = next;
> }
> last->next_ = NULL;
> }
> Link *p = head_;
> head_ = p->next_;
> p->~Link();
> return static_cast<void *>(p);
> }
>
> Link *head_;
> };
>
> struct FooAlloc {
> Foo *alloc() { return new (p_.allocate()) Foo(); }
> Alloc p_;
> };
>
> int main()
> {
> if (sizeof(Foo) != sizeof(Link)) { abort(); }
> printf("here\n"); fflush(stdout);
>
> FooAlloc pool;
> Foo *e = pool.alloc();
> if (e) {
> printf("e\n"); fflush(stdout);
> }
> e = pool.alloc();
> return 0;
> }
>
>
> If I uncomment the "may_alias" attribute, everything works. But I don't
> quite understand why "may_alias" is needed here. Could somebody help please?
> My understanding is that, since in Alloc::allocate() I'm calling the
> destructor of p before returning a pointer to the memory in which it is
> allocated, and in FooAllo::alloc() I'm constructing a new object in that
> memory area, aliasing should not be an issue.
It's much simpler than that.
Here you have a Link* :
Link *p = head_;
head_ = p->next_;
p->~Link();
return static_cast<void *>(p);
and you cast it to a Foo* :
Foo *e = pool.alloc();
Foo and Link are not compatible types. You cannnot take a pointer to
a Link and alias it to a pointer to a Foo.
Your problem is these two casts. gcc doesn't spot the problem because
you're going via void*.
Andrew.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: help with g++ and strict aliasing on x86-64
2010-11-22 17:48 help with g++ and strict aliasing on x86-64 Alberto Griggio
2010-11-22 17:53 ` Alberto Griggio
2010-11-22 18:12 ` Andrew Haley
@ 2010-11-22 18:37 ` Ian Lance Taylor
2010-11-22 18:53 ` Andrew Haley
2010-11-23 8:40 ` Alberto Griggio
2 siblings, 2 replies; 6+ messages in thread
From: Ian Lance Taylor @ 2010-11-22 18:37 UTC (permalink / raw)
To: Alberto Griggio; +Cc: gcc-help
Alberto Griggio <alberto.griggio@gmail.com> writes:
> My OS is Debian GNU/Linux 5.0, compiler is
> g++-4.1 (GCC) 4.1.3 20080704 (prerelease) (Debian 4.1.2-25)
> platform x86-64
> head_ = new (mem) Link;
> If I uncomment the "may_alias" attribute, everything works.
There have been a few bugs in the handling of placement new with regard
to aliasing. See in particular http://gcc.gnu.org/PR29286 . As far as
I know these bugs are fixed in current releases but they are apparently
not fixed in the older release you are using.
Ian
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: help with g++ and strict aliasing on x86-64
2010-11-22 18:37 ` Ian Lance Taylor
@ 2010-11-22 18:53 ` Andrew Haley
2010-11-23 8:40 ` Alberto Griggio
1 sibling, 0 replies; 6+ messages in thread
From: Andrew Haley @ 2010-11-22 18:53 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: Alberto Griggio, gcc-help
On 11/22/2010 06:14 PM, Ian Lance Taylor wrote:
> Alberto Griggio <alberto.griggio@gmail.com> writes:
>
>> My OS is Debian GNU/Linux 5.0, compiler is
>> g++-4.1 (GCC) 4.1.3 20080704 (prerelease) (Debian 4.1.2-25)
>> platform x86-64
>
>> head_ = new (mem) Link;
>
>> If I uncomment the "may_alias" attribute, everything works.
>
> There have been a few bugs in the handling of placement new with regard
> to aliasing. See in particular http://gcc.gnu.org/PR29286 . As far as
> I know these bugs are fixed in current releases but they are apparently
> not fixed in the older release you are using.
Ah. Albert, please ignore my posting.
It looked like astraightforward aliasing violation.
Andrew.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: help with g++ and strict aliasing on x86-64
2010-11-22 18:37 ` Ian Lance Taylor
2010-11-22 18:53 ` Andrew Haley
@ 2010-11-23 8:40 ` Alberto Griggio
1 sibling, 0 replies; 6+ messages in thread
From: Alberto Griggio @ 2010-11-23 8:40 UTC (permalink / raw)
To: gcc-help
Ian,
> Alberto Griggio <alberto.griggio@gmail.com> writes:
>
>> My OS is Debian GNU/Linux 5.0, compiler is
>> g++-4.1 (GCC) 4.1.3 20080704 (prerelease) (Debian 4.1.2-25)
>> platform x86-64
>
>> head_ = new (mem) Link;
>
>> If I uncomment the "may_alias" attribute, everything works.
>
> There have been a few bugs in the handling of placement new with regard
> to aliasing. See in particular http://gcc.gnu.org/PR29286 . As far as
> I know these bugs are fixed in current releases but they are apparently
> not fixed in the older release you are using.
Thanks a lot! This was driving me crazy... :-)
Best,
Alberto
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-11-23 7:52 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-22 17:48 help with g++ and strict aliasing on x86-64 Alberto Griggio
2010-11-22 17:53 ` Alberto Griggio
2010-11-22 18:12 ` Andrew Haley
2010-11-22 18:37 ` Ian Lance Taylor
2010-11-22 18:53 ` Andrew Haley
2010-11-23 8:40 ` Alberto Griggio
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).