<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Jul 31, 2014 at 5:19 AM, Jordan Rose <span dir="ltr"><<a href="mailto:jordan_rose@apple.com" target="_blank">jordan_rose@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div class="h5"><br>
<div><div>On Jul 30, 2014, at 8:14 , Manuel Klimek <<a href="mailto:klimek@google.com" target="_blank">klimek@google.com</a>> wrote:</div><br><blockquote type="cite"><div dir="ltr">Hi Jordan,<div><br></div><div>I made some progress on inlining temporary destructors. My main problem currently is that somehow the initializer values in my constructor get lost if I don't also reference 'this' via some other way.</div>

<div><br></div><div>An examples shows that best. Consider:</div><div>struct A {</div><div>  A(int* y) : z(y) {}</div><div>  ~A() { *z = 23; }</div><div>  int *z;</div><div>};</div><div>void f() {</div><div>  int x = 0;</div>

<div>  {(A(&x));}</div><div>}</div><div><br></div><div>This leads to a "Dereference of undefined pointer value" warning on *z = 23.</div><div>Funnily enough this warning goes away (and all values get correctly propagated) if change the constructor to be:</div>

<div>A(int* y) : z(y) { (void)this; }</div><div><br></div><div>Obviously this also works fine if I use a local variable instead of a temporary.</div><div><br></div><div>Any ideas what might be going wrong here would be greatly appreciated.</div>

</div></blockquote><br></div></div></div><div>My guess is that the temporary is an rvalue, and in the analyzer a NonLoc, and that the only reason this even appears to work is because we needed to be able to call <i>methods</i> on temporaries and so will create a temporary region for them on demand to serve as the 'this' pointer. However, I don't think we expect that to happen for <i>constructors,</i> and so we don't keep the region around after the constructor has finished executing. (That is, when it's just a method being called—and neither the constructor nor destructor are inlined—it doesn't actually matter what you do to the contents of the region, because nothing else can access it.)</div>
<div><br></div></div></blockquote><div><br></div><div>So, funnily enough if I remove this code:</div><div><div>  if (isTemporaryPRValue(CCE, ThisV))</div><div><span style="white-space:pre">    </span>ThisV = state->getSVal(ThisV.castAs<Loc>());</div>
</div><div>which puts the temp region into a lazycompoundregion, the memory seems to be correctly handled. I have not yet looked what else this breaks though.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word"><div></div><div>I am a little confused as to how your workaround actually changes anything, but regardless there is an issue here.</div><div><br></div><div>To fix this, we may need to treat temporaries as Loc values always, and figure out how to teach the rest of the analyzer to ignore the fact that the Expr says it's an rvalue. Alternately, we could update the compiler to actually treat these as xvalues (which are glvalues), and therefore we'd have a location we could deal with. I vaguely remember talking to Richard about this at one point and him thinking it to be a reasonable idea.</div>
<div><br></div><div>Or I could be totally off-base on this, because I'm coming up with this from memory rather than actually digging into the program trace.</div><span class=""><font color="#888888"><div><br></div><div>
Jordan</div></font></span></div></blockquote></div><br></div></div>