public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).