This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: IPA: Devirtualization versus placement new
- From: Jonathan Wakely <jwakely dot gcc at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Andrew Haley <aph at redhat dot com>, "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>, Jan Hubicka <hubicka at ucw dot cz>
- Date: Fri, 25 Apr 2014 13:05:07 +0100
- Subject: Re: IPA: Devirtualization versus placement new
- Authentication-results: sourceware.org; auth=none
- References: <535A375E dot 6050301 at redhat dot com> <CAH6eHdTQDqh6WZid5RFc-Cve94xjJB13xGYe7WmypCqp1aubiQ at mail dot gmail dot com> <CAFiYyc1rmYoFjAkqoj1DQxerwGko8h1jz_keknV9kPvT5Fh-HQ at mail dot gmail dot com>
On 25 April 2014 13:01, Richard Biener wrote:
> On Fri, Apr 25, 2014 at 1:18 PM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>> On 25 April 2014 11:22, Andrew Haley wrote:
>>> Summary: Devirtualization uses type information to determine if a
>>> virtual method is reachable from a call site. If type information
>>> indicates that it is not, devirt marks the site as unreachable. I
>>> think this is wrong, and it breaks some programs. At least, it should
>>> not do this if the user specifies -fno-strict-aliasing.
>>>
>>> Consider this class:
>>>
>>> class Container {
>>> void *buffer[5];
>>> public:
>>> EmbeddedObject *obj() { return (EmbeddedObject*)buffer; }
>>> Container() { new (buffer) EmbeddedObject(); }
>>> };
>>>
>>> Placement new is used to embed an object in a buffer inside another
>>> object. Its address can be retrieved. This usage of placement new is
>>> common, and it even appears as the canonical use of placement new in
>>> the in the C++ FAQ at
>>> http://www.parashift.com/c++-faq/placement-new.html. (I am aware that
>>> this is not strictly legal. For one thing, the memory at buffer may
>>> not be suitably aligned. Please bear with me.)
>>
>> I think the program is strictly legal if you define Container like this:
>>
>> class Container {
>> alignas(EmbeddedObject) char buffer[sizeof(EmbeddedObject)];
>> public:
>> EmbeddedObject *obj() { return (EmbeddedObject*)buffer; }
>> Container() { new (buffer) EmbeddedObject(); }
>> };
>>
>> But GCC still does the same transformation and prints nothing, which I
>> agree is wrong (even with -fstrict-aliasing).
>
> I agree, -fstrict-aliasing has nothing to do with this. Sounds simply like
> a genuine bug (please open a bugzilla).
>
> Thanks,
> Richard.
>
>> With ubsan that program gives:
>>
>> sa.cc:9:24: runtime error: load of null pointer of type '<unknown> *'
>> Segmentation fault (core dumped)
I created http://gcc.gnu.org/60963 for the ubsan error. The testcase
there is a single file which crashes with ubsan and returns the wrong
value without. Changing the return statement to
__builtin_printf("%d\n", o.obj()->val()) prints nothing, like Andrew's
original example.
If it's not really a ubsan problem feel free to re-categorise that as
a devirt bug rather than open a new one, whatever's most appropriate.