Closed Bug 681694 Opened 13 years ago Closed 12 years ago

Block support code added by Apple's g++/llvm-g++ calls C++ destructor prematurely

Categories

(Core :: Widget: Cocoa, defect)

All
macOS
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: smichaud, Unassigned)

References

Details

(Whiteboard: rdar://10007196)

Attachments

(2 files)

This bug is spun off from bug 678607, to track an Apple bug discovered there (in bug 678607 comment #44). It was reported to Apple as rdar number 10007196 (see bug 678607 comment #68). Apple's "blocks" are described at http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html. In the following I refer to the function in which a block is embedded as its "parent". Blocks require a *lot* of support code under the hood. This is added by Apple's gcc/g++ (and friends). The code inside the block itself is placed in a function named __[parent]_block_invoke_N(), preceded by a fairly lengthy prologue. If the block refers to a variable in its scope within the parent, but not inside the block itself, the block's prologue creates a copy of it on the block's stack (i.e. in a local variable). All references to this variable within the block are translated into references to this "prologue copy". In the case of a C++ structure or class, g++ or llvm-g++ prologue code copies the entire structure onto the stack using a copy constructor. The bug is that, immediately afterwards, the prologue also calls the structure's destructor (instead of calling it at the end of the block, as it should). The memory occupied by the prologue copy of the structure isn't released until the end of the block (when it goes out of scope). But the contents of the structure are, in general, undefined -- who knows what the structure's destructor might have done to it. Clang's block prologue code is quite different, and doesn't have this bug. And Apple seems to be deprecating gcc/g++ and llvm-gcc/llvm-g++ in favor of clang -- so it's unlikely they'll fix this bug. Which (probably) means that the only way *we'll* be able to fix it is to switch to clang on OS X. It'll be a while before we can change to clang on OS X. But [NSEvent trackSwipeEventWithOptions:...] uses blocks, and it seems to be the best way to provide support for two-finger horizontal swipes on OS X Lion, which we need right now (see bug 668953). So we have strong motivation to work around Apple's bug, which it appears we're able to do for now (see particularly bug 678607 comment #70).
Whiteboard: rdar://10007196
I generated this using: lvm-g++ -S -flto -emit-llvm mstange-testcase-orig.mm
As Markus Stange pointed out in bug 678607 comment #40, the following log output shows the bug in action: // CPPStruct(0x7fff5fbfe5b0) copy construction from 0x10040f9b8 // CPPStruct(0x7fff5fbfe5b0) destruction // block called with x = 0, &e: 0x7fff5fbfe5b0, e.mX: 5, [d retainCount]: 1 // CPPStruct(0x7fff5fbfe5b0) copy construction from 0x10040f9b8 // CPPStruct(0x7fff5fbfe5b0) destruction // block called with x = 1, &e: 0x7fff5fbfe5b0, e.mX: 5, [d retainCount]: 1 In the IL from comment #2, look for definition of the function named "__-[TestView mouseDown:]_block_invoke_1". Near the top you'll see the following, where space is allocated on the stack for the local copy of CPPStruct e: // %e = alloca %struct.CPPStruct ; <%struct.CPPStruct*> [#uses=4] Then you'll see the following, where the CPPStruct constructor is called, and immediately afterwards its destructor: // call void @_ZN9CPPStructC1ERKS_(%struct.CPPStruct* %e, %struct.CPPStruct* %1) ssp // call void @_ZN9CPPStructD1Ev(%struct.CPPStruct* %e) ssp But the call to NSLog() (which refers to the local copy of CPPStruct e) only takes place at the bottom of the function, after the CPPStruct destructor was called: // call void (%struct.NSColor*, ...)* // @NSLog( // %struct.NSColor* bitcast // (%struct.__builtin_CFString* @"\01L_unnamed_cfstring_8" to %struct.NSColor*), // i32 %13, // %struct.CPPStruct* %e, // i32 %12, // i64 %10)
Depends on: 682445
See bug 682445 comment 15 for more information on Apple's block support code.
Apple's gcc is dead. We moved to clang.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: