[llvm-bugs] [Bug 29136] New: [windows/arm] extraneous C++ object destructor call added when objects are passed by value

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Aug 25 05:46:11 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=29136

            Bug ID: 29136
           Summary: [windows/arm] extraneous C++ object destructor call
                    added when objects are passed by value
           Product: clang
           Version: 3.8
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Keywords: miscompilation
          Severity: normal
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: adrien at guinet.me
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org,
                    szkudl.k at gmail.com
    Classification: Unclassified

This is only happening when using Clang under Windows to generate Thumb code.

When a C++ object is passed by value to a function, the temporary object
created by copy is destructed twice, once in the callee function (which is
okay) and once more in the caller function (which should not happen). This
leads to a double free of a C++ object.

Attached is a minimal test case that reproduces the problem (double_free.cpp,
reduced by Kevin Szkudlapski in CC).

Here is the assembler output without any optimisation:

> clang.exe double_free.cpp -c -o double_free.o --target=armv7-pc-windows-msvc -fmsc-version=1900 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1

(using IDA)
 ; int __cdecl main(int argc, const char **argv, const char **envp)
                 EXPORT main
 main

 var_28          = -0x28
 tmpObject       = -0x24
 var_20          = -0x20
 var_1C          = -0x1C
 var_18          = -0x18
 var_14          = -0x14
 var_10          = -0x10
 var_C           = -0xC

  PUSH.W          {R11,LR}       
  MOV             R11, SP        
  SUB             SP, SP, #0x20  
  MOVS            R0, #0         
  STR             R0, [SP,#0x28+var_C]
  ADD             R1, SP, #0x28+var_10
  STR             R0, [SP,#0x28+var_18]
  MOV             R0, R1         
  STR             R1, [SP,#0x28+var_1C]
  BL              c::c(void)     
  MOV             R0, #`string' ; "f start"
  BL              puts           
  ADD             R1, SP, #0x28+var_14
  STR             R0, [SP,#0x28+var_20]
  MOV             R0, R1         
  LDR.W           LR, [SP,#0x28+var_1C]
  STR             R1, [SP,#0x28+tmpObject]
  MOV             R1, LR         
  BL              c::c(c const &)
  BL              f(c)           
  LDR             R0, [SP,#0x28+tmpObject]
  BL              c::~c(void) ; double free happens here!
  MOV             R0, #`string' ; "f end"
  BL              puts           
  LDR             R1, [SP,#0x28+var_18]
  STR             R1, [SP,#0x28+var_C]
  LDR.W           LR, [SP,#0x28+var_1C]
  STR             R0, [SP,#0x28+var_28]
  MOV             R0, LR         
  BL              c::~c(void)    
  LDR             R0, [SP,#0x28+var_C]
  ADD             SP, SP, #0x20  
  POP.W           {R11,PC} 

And the "f::f" function:
void __cdecl f(class c)                 

var_10          = -0x10        
var_C           = -0xC         

  PUSH.W          {R11,LR}      
  MOV             R11, SP       
  SUB             SP, SP, #8    
  MOV             R0, #`string' ; "f inside"
  BL              puts          
  ADD.W           LR, SP, #0x10+var_C
  STR             R0, [SP,#0x10+var_10]
  MOV             R0, LR        
  BL              c::~c(void) ; this one is okay and destruct the temporary
object
  ADD             SP, SP, #8    
  POP.W           {R11,PC}

The LLVM IR also reflects this issue. The optimized code (-O2) shows three
printf calls with "dtor: %p" as argument (where only two should be present, one
for the original copy and one for the temporary object).

This has been tested using the official clang 3.8.1 release (not the 3.9RC or
trunk).

Let us know if more information are needed!

Thanks!

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160825/3177a484/attachment.html>


More information about the llvm-bugs mailing list