C++ delete operator undefined behavior

Ioi Lam ioi.lam at oracle.com
Sat Feb 9 14:24:37 UTC 2019


On 2/9/19 4:36 AM, David Holmes wrote:
> Hi Ioi,
>
> On 9/02/2019 6:42 pm, Ioi Lam wrote:
>> I am getting a "ud2" instruction on the Mac for a 'delete' 
>> expression. According to this page, it's clang flagging an undefined 
>> behavior:
>>
>> https://stackoverflow.com/questions/21529308/why-does-clang-generate-ud2-opcode-on-osx 
>>
>>
>> My code looks like this:
>>
>> class MetaspaceClosure {
>>    class Ref : public ResourceObj {
>>    ...
>>    };
>>
>>
>>    void push_impl(Ref* ref) {
>>      if (_nest_level < MAX_NEST_LEVEL) {
>>        do_push(ref);
>>        delete ref;
>>      } else {
>>        ref->set_next(_pending_refs);
>>        _pending_refs = ref;
>>      }
>>    }
>> };
>>
>> and clang generates this code
>>
>> libjvm.dylib`MetaspaceClosure::push_impl:
>>      0x10316db9c <+0>:  pushq  %rbp
>>      0x10316db9d <+1>:  movq   %rsp, %rbp
>>      0x10316dba0 <+4>:  pushq  %rbx
>>      0x10316dba1 <+5>:  pushq  %rax
>>      0x10316dba2 <+6>:  movq   %rsi, %rbx
>>      0x10316dba5 <+9>:  cmpl   $0x4, 0x10(%rdi)
>>      0x10316dba9 <+13>: jg     0x10316dbba
>>      0x10316dbab <+15>: movq   %rbx, %rsi
>>      0x10316dbae <+18>: callq  0x10316dbce  ; do_push()
>>      0x10316dbb3 <+23>: testq  %rbx, %rbx
>>      0x10316dbb6 <+26>: je     0x10316dbc6
>> ->  0x10316dbb8 <+28>: ud2 <<<<<<<<<<<<<<<<<<<<<<< HERE
>>      0x10316dbba <+30>: movq   0x8(%rdi), %rax
>>      0x10316dbbe <+34>: movq   %rax, 0x20(%rbx)
>>      0x10316dbc2 <+38>: movq   %rbx, 0x8(%rdi)
>>      0x10316dbc6 <+42>: addq   $0x8, %rsp
>>      0x10316dbca <+46>: popq   %rbx
>>      0x10316dbcb <+47>: popq   %rbp
>>      0x10316dbcc <+48>: retq
>>      0x10316dbcd <+49>: nop
>>
>> Shouldn't the 'delete' expression be translated to 
>> ResourceObj::operator delete()?
>
> Are Ref's allocated on the C_heap? That's the only kind of resourceObj 
> you can delete:
>
> void ResourceObj::operator delete(void* p) {
>   assert(((ResourceObj *)p)->allocated_on_C_heap(),
>          "delete only allowed for C_HEAP objects");
>   DEBUG_ONLY(((ResourceObj *)p)->_allocation_t[0] = 
> (uintptr_t)badHeapOopVal;)
>   FreeHeap(p);
> }
>

I allocate them using

Ref *r = new (C_HEAP, mtInternal)Ref(....);

However, whether I do that or not isn't something that clang can deduce 
statically to mark my 'delete' as having undefined behavior.

Thanks

- Ioi



> David
> -----
>
>> And I couldn't find any warning messages given by clang ....
>>
>> I rewrote the Ref class to inherit from CHeapObj<mtInternal> instead, 
>> and it magically worked.
>>
>> However, but there's other use of 'delete' on ResourceObj (such as 
>> ResourceHashtable) that seems to work just fine. Am I missing something?
>>
>> Thanks
>>
>> - Ioi
>>
>>
>>


More information about the hotspot-dev mailing list