<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Jun 19, 2013, at 3:04 PM, Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.com</a>> wrote:</div><blockquote type="cite"><div dir="ltr">On Wed, Jun 19, 2013 at 5:17 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<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 class="im">On Jun 19, 2013, at 1:44 PM, Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.com</a>> wrote:<br>

>    - Add conditional tests<br>
>    - Deactivate cleanups in reverse<br>
>    - Other comments.<br>
<br>
</div>+  /// \brief Are temporary objects passed by value to a call destroyed by the<br>
+  /// callee?<br>
+  bool isTemporaryDestroyedByCallee() const {<br>
<br>
Please embellish this comment to discuss the ways in which this is<br>
actually a major language difference.<br></blockquote><div><br></div><div style="">Done.</div><div style=""> </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">

+void Sema::CheckByValParamsForDtors(FunctionDecl *FD) {<br>
+  assert(Context.getTargetInfo().getCXXABI().isTemporaryDestroyedByCallee());<br>
+  for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {<br>
+    ParmVarDecl *Param = FD->getParamDecl(p);<br>
+    if (CXXRecordDecl *RD = Param->getType()->getAsCXXRecordDecl()) {<br>
+      if (CXXDestructorDecl *Dtor = LookupDestructor(RD)) {<br>
+        // Don't call CheckDestructorAccess() or we'll reject valid TUs.<br>
+        MarkFunctionReferenced(FD->getLocation(), Dtor);<br>
+        DiagnoseUseOfDecl(Dtor, FD->getLocation());<br>
+      }<br>
+    }<br>
+  }<br>
+}<br>
+<br>
<br>
I think this code is dead now?<br></blockquote><div><br></div><div style="">Oops, deleted.</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">

You should add my test case, and then you'll need to go do some<br>
spelunking to make it pass, because you'll have to disable the check<br>
for a destructor when initializing a parameter temporary.<br></blockquote><div><br></div><div style="">I'd rather err on the side of rejecting because MSVC rejects this for example:</div><div><div><br></div><div>struct A {</div>
<div>  A(const A &a);  // Comment out to accept.</div><div> private:</div><div>  ~A();</div><div>  friend void bar(A);</div><div>};</div><div>void bar(A a) { }</div><div>void foo(A *a) { bar(*a); }  // error C2248: 'A::~A' : cannot access private member declared in class 'A'</div>
</div><div><br></div><div style="">They seem to have some heuristics in their equivalent of Sema to guess whether or not they'll need to call ~A.  I don't know if we want to mirror that or not.</div></div></div></div>
</blockquote><br></div><div>This difference might be about checks for formal temporaries that are in practice elided; I'm not sure.</div><div><br></div><div>Anyhow, if you can't find a reasonable model for what MSVC actually does, I am fine with conservatively requiring the destructor on both sides.  You should capture this in that comment you're embellishing, though.</div><div><br></div><div>John.</div></body></html>