<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 21, 2017, at 11:01 AM, Alfred Zien via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi! Recently I discovered a way to make a bad access crash in somewhat unexpected circumstances. Code to reproduce:<div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">import</span> Foundation</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">class</span> Storage<T> {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #ba2da2" class="">var</span> val : <span style="color: #4f8187" class="">T</span>?</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class="">class<span style="" class=""> A {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #ba2da2" class="">let</span> s : <span style="color: #4f8187" class="">Storage</span><<span style="color: #4f8187" class="">A</span>></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #ba2da2" class="">init</span>(s : <span style="color: #4f8187" class="">Storage</span><<span style="color: #4f8187" class="">A</span>>) {</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #ba2da2" class="">self</span>.<span style="color: #4f8187" class="">s</span> = s</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> }</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><span style="" class=""> </span>deinit<span style="" class=""> {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #4f8187" class="">s</span>.<span style="color: #4f8187" class="">val</span> = <span style="color: #ba2da2" class="">self</span>;</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> }</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">var</span> storage : <span style="color: #4f8187" class="">Storage</span><<span style="color: #4f8187" class="">A</span>> = <span style="color: #4f8187" class="">Storage</span>()</div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">var</span> a : <span style="color: #4f8187" class="">A</span>? = <span style="color: #4f8187" class="">A</span>(s: <span style="color: #4f8187" class="">storage</span>)</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #4f8187" class="">a</span> = <span style="color: #ba2da2" class="">nil</span></div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170); background-color: rgb(255, 255, 255);" class="">DispatchQueue<span style="" class="">.</span>main<span style="" class="">.</span><span style="color: #3e1e81" class="">async</span><span style="" class=""> {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);" class=""><span style="" class=""> </span><span style="color: #3e1e81" class="">print</span><span style="" class="">(</span>storage<span style="" class="">.</span>val<span style="" class=""> </span><span style="color: #ba2da2" class="">as</span><span style="" class=""> </span><span style="color: #ba2da2" class="">Any</span><span style="" class="">)</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(62, 30, 129); background-color: rgb(255, 255, 255);" class="">dispatchMain<span style="" class="">()</span></div></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(62, 30, 129); background-color: rgb(255, 255, 255);" class=""><span style="" class=""><br class=""></span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(62, 30, 129); background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">We saving self in storage on deinit. Storage will retain `a`, but after it `a` will be destroyed. So, `val` will point to object that was deallocated. When we will try to access it, it will crash.</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(62, 30, 129); background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(62, 30, 129); background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">Can we do something about it? Of course, this very evil thing to do, but, unfortunately, swift allows to do that. I have two suggestions:</span></div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class="">1. Completely forbid accessing self in deinit, allowing readonly access only to properties with default getter method. This is very strict, but will catch such problems in compile time.</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class="">2. The bigger problem here, not just that it will crash, but it will crash in very unpredictable place. So, we can make it crash just after deinit method, if retain count was changed after deinit.</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class="">I'm new to swift evolution, so please forgive me if I'm doing something wrong :) Thanks!</div></div></div></blockquote><br class=""></div><div>deinit isn't allowed to "resurrect" the object in this way by escaping new references to the dying object. We could, and probably should, have a runtime check to catch this during object destruction.</div><div><br class=""></div><div>-Joe</div><br class=""></body></html>