<div dir="ltr">I mean, there's got to be a way to inject some destructor cleanups into the lambda, like:<div><br></div><div>struct A { ~A(); };</div><div>int f(A) { return 42; }</div><div><div>id test_dict()</div><div>{</div><div>        return @{</div><div>                @"a": [x=f(A())]() { return x; },</div><div>                @"b": [x=f(A())]() { return x; }</div><div>        };</div><div>}</div></div><div><br></div><div>Does this change affect where ~A gets called?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 16, 2014 at 5:04 PM, jahanian <span dir="ltr"><<a href="mailto:fjahanian@apple.com" target="_blank">fjahanian@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><div>On Sep 16, 2014, at 4:46 PM, Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>> wrote:</div><br><blockquote type="cite"><div dir="ltr"><div>This will have the observable effect of making cleanups run sooner, right? Can you test for that?</div></div></blockquote><div><br></div></span>Yes. Generally, it now happens at the end of the ‘value’ part dictionary literal evaluation. While before it was happening at where</div><div>expression was considered a full expression (on return statement in this example). I am not sure if this change meshes well with</div><div>rules related to clean up code.</div><div><br></div><div>For this working test case:</div><div><div style="margin:0px;font-size:11px;font-family:Menlo">id test()</div><div style="margin:0px;font-size:11px;font-family:Menlo">{</div><div style="margin:0px;font-size:11px;font-family:Menlo">   int cap_a, cap_b;</div><div style="margin:0px;font-size:11px;font-family:Menlo">        return @{</div><div style="margin:0px;font-size:11px;font-family:Menlo">                @"a": ^(){ cap_a; },</div><div style="margin:0px;font-size:11px;font-family:Menlo">                @"b": ^(){ cap_b;}</div><div style="margin:0px;font-size:11px;font-family:Menlo">        };</div><div style="margin:0px;font-size:11px;font-family:Menlo">}</div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo">Before:</div><div style="margin:0px;font-size:11px;font-family:Menlo">       `-ReturnStmt 0x7fde82076498 <line:20:9, line:23:9></div><div style="margin:0px;font-size:11px;font-family:Menlo">      `-ExprWithCleanups 0x7fde82076470 <line:20:16, line:23:9> 'id':'id'</div><div style="margin:0px;font-size:11px;font-family:Menlo">        |-cleanup Block 0x7fde82076080</div><div style="margin:0px;font-size:11px;font-family:Menlo">        |-cleanup Block 0x7fde82076270</div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo">With this patch:</div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo"><div style="margin:0px">    `-ReturnStmt 0x7ff2a10766a0 <line:20:9, line:23:9></div><div style="margin:0px">      `-ImplicitCastExpr 0x7ff2a1076688 <line:20:16, line:23:9> 'id':'id' <BitCast></div><div style="margin:0px">        `-ObjCDictionaryLiteral 0x7ff2a1076638 <line:20:16, line:23:9> 'NSDictionary *'</div><div style="margin:0px">          |-ImplicitCastExpr 0x7ff2a1076580 <line:21:17, col:18> 'const id<NSCopying>' <BitCast></div><div style="margin:0px">          | `-ObjCStringLiteral 0x7ff2a1076258 <col:17, col:18> 'NSString *'</div><div style="margin:0px">          |   `-StringLiteral 0x7ff2a1076200 <col:18> 'const char [2]' lvalue "a"</div><div style="margin:0px">          |-ExprWithCleanups 0x7ff2a10765b0 <col:23, col:35> 'const id':'const id'</div><div style="margin:0px">          | |-cleanup Block 0x7ff2a1076280</div><div style="margin:0px">          | |-cleanup Block 0x7ff2a1076470</div><div style="margin:0px"><br></div><div style="margin:0px"><br></div><div style="margin:0px">- fariborz</div></div></div><div><div class="h5"><div><br></div><div><br><blockquote type="cite"><div dir="ltr"><div><br></div><div>+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -fblocks</div><div><br></div><div>If you aren't checking the IR, use -emit-llvm-only to avoid writing to stdout. However, IMO you should be checking the IR here.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 16, 2014 at 3:56 PM, jahanian <span dir="ltr"><<a href="mailto:fjahanian@apple.com" target="_blank">fjahanian@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hi John,<div><br></div><div>This test case:</div><div><br></div><div><div style="margin:0px;font-size:11px;font-family:Menlo">id test_dict()</div><div style="margin:0px;font-size:11px;font-family:Menlo">{</div><div style="margin:0px;font-size:11px;font-family:Menlo">        return @{</div><div style="margin:0px;font-size:11px;font-family:Menlo">                @"a": [](){},</div><div style="margin:0px;font-size:11px;font-family:Menlo">                @"b": [](){}</div><div style="margin:0px;font-size:11px;font-family:Menlo">        };</div><div style="margin:0px;font-size:11px;font-family:Menlo">}</div></div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo">Crashes in IRGen because ExprWithCleanups for the dummy BlockDecl we use to facilitate lambda to block conversion</div><div style="margin:0px;font-size:11px;font-family:Menlo">is at the wrong place.</div><div style="margin:0px;font-size:11px;font-family:Menlo">This happens because a lambda expression is considered a full expression so it calls MaybeCreateExprWithCleanups</div><div style="margin:0px;font-size:11px;font-family:Menlo">(see <span style="color:rgb(79,129,135)">Sema</span>::BuildBlockForLambdaConversion).</div><div style="margin:0px;font-size:11px;font-family:Menlo">which ends up adding the clean up code for the BlockDecl of the first lambda to the expression for the 2nd lambda!</div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo">Ideally, MaybeCreateExprWithCleanups should be called when the entire dictionary literal is seen. But in this case,</div><div style="margin:0px;font-size:11px;font-family:Menlo">this does not happen. Attached patch fixes this by making sure that after ‘every’ parse of the ‘value’ expression</div><div style="margin:0px;font-size:11px;font-family:Menlo">MaybeCreateExprWithCleanups is called. This, in effect, assumes that the ‘value’ literal is a full expression.</div><div style="margin:0px;font-size:11px;font-family:Menlo">I don’t know the ramification of this change in the common case as couple of non-lambda literal tests broke.</div><div style="margin:0px;font-size:11px;font-family:Menlo">(it now generates the none-exc version of call instead of exc versions in couple of places).</div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo">Please review. Let me know if you need additional info.</div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo">- Thanks, Fariborz</div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo"></div></div><br><div style="word-wrap:break-word"><div style="margin:0px;font-size:11px;font-family:Menlo"></div></div>
<br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div>
</blockquote></div><br></div></div></div></blockquote></div><br></div>