Unwinding ObjC code involves calls to intrinsics like llvm.obj.retain and llvm.objc.destroyWeak. Exception handling on Windows is based on funclets and WinEHPrepare only allows calls to nounwind intrinsics. This works just fine, except for ObjC nounwind intrinsics, because these are lowered into regular function calls in an earlier stage already (i.e. PreISelIntrinsicLoweringPass). Thus, WinEHPrepare accidentally drops them as implausible instructions and silently truncates certain funclets. Eventually, this causes crashes during unwinding on Windows with the GNUstep ObjC runtime [1].
This patch is a first attempt to fix the issue: PreISelIntrinsicLoweringPass passes on nounwind attributes to lowered call sites and WinEHPrepare gets a little less conservative by allowing any nounwind calls. It fixes the issue in GNUstep libobjc2 [1] and related projects. I will work on a test case during the next weeks and I understand if this is not immediately ready to land upstream. For the moment, I am looking for feedback to avoid unintended side effects.
Thanks for all input!
Are all these functions actually nounwind? Destroying objects can call into user code.