<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Feb 4, 2015 at 11:24 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@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"><div><div><div class="h5"><blockquote type="cite"><div>On Feb 4, 2015, at 11:17 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:</div><br><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Feb 4, 2015 at 11:08 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@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"><div><blockquote type="cite"><span><div>On Feb 4, 2015, at 9:36 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:</div></span><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Wed, Feb 4, 2015 at 6:38 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br></span><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"><span><span>On Jun 5, 2014, at 4:17 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:<br></span><div><div>> John: any chance we could get the ABI document updated with these? (<a href="http://sourcerytools.com/pipermail/cxx-abi-dev/2012-January/000024.html" target="_blank">http://sourcerytools.com/pipermail/cxx-abi-dev/2012-January/000024.html</a>)<br>
<br>
</div></div></span><div><div>After much delay, added.  We don’t seem to get this right, though, at least not when the destination type isn’t dependent:<br>
<br>
template <class T, class U> T fst(T, U);<br>
struct A {<br>
  int x[3];<br>
};<br>
template <class T> decltype(fst(A{1,2},T())) foo(T t) {}<br>
<br>
int main() {<br>
  foo(1);<br>
}<br>
<br>
We produce:<br>
  _Z3fooIiEDTcl3fstcv1AililLi1ELi2EEEcvT__EEES1_<br>
It should be:<br>
  _Z3fooIiEDTcl3fsttl1ALi1ELi2EcvT__EEES1_<br></div></div></blockquote><div><div><div><br></div><div>There are quite a few bugs conspiring to give that result :( Our AST is also poorly-suited to this mangling, because the braces are not considered to be part of the functional cast itself; they're part of its subexpression.</div><div><br></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">
If you parenthesize the argument to A:<br>
  template <class T> decltype(fst(A({1,2}),T())) foo(T t) {}<br>
We produce:<br>
  _Z3fooIiEDTcl3fstcv1AcvS0_ililLi1ELi2EEEcvT__EEES1_<br>
It should be:<br>
  _Z3fooIiEDTcl3fstcv1AliLi1ELi2EcvT__EEES1_<br></blockquote><div><br></div><div>Somewhat related, we also get this wrong:</div><div><br></div><div>struct X { X(int); };</div><div>int f(X);</div><div>template<typename T> void f(decltype(f(0), T())) { f(0); }</div><div>void g() { f<int>(0); }</div><div><br></div><div>... because we explicitly mangle the implicit conversion from int to X. I see</div><div><br></div><div>_Z1fIiEvDTcmcl1fLi0EEcvT__EE from EDG<br></div><div>_Z1fIiEvDTcmclL_Z1f1XELi0EEcvT__EE from GCC<br></div><div>_Z1fIiEvDTcmclL_Z1f1XEcvS0_cvS0_Li0EEcvT__EE from Clang</div></div></div></div></div></div></div></blockquote><div><br></div>Ugh, that’s awful.</div><span><div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>I think GCC and Clang are right to use the resolved name L_Z1f1XE rather than the unresolved name 1f here, and GCC's mangling is right overall. Do you agree?</div></div></div></div>
</div></blockquote></div><div><br></div></span><span><div><div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra">As an aside: if we have a fully-resolved call in an instantiation-dependent expression, should we really be putting any used default arguments into the mangling?</div></div></blockquote></div><br></div></span><div>I feel like both of these points need to be asked on the cxx-abi-dev.  I definitely don’t think we should be mangling default arguments, but I’m not sure that resolving ‘f’ here is really consistent with the general dictate to follow the syntactic tree.</div><div><br></div><div><span><blockquote type="cite"><div dir="ltr"><div class="gmail_extra">All of the above fixed in r228274. I'm not really very happy with our AST representation here; we've overloaded CXXConstructExpr to mean too many different syntactic things that it's hard to reconstruct the right mangling.</div></div></blockquote><div><br></div></span>The rule used to be that a “bare" CXXConstructExpr — neither a specific subclass nor the implementation of a cast — was always implicit, and that there were subclasses which provided additional syntactic information.  I think it would make sense to have a dedicated subclass for the truly implicit case as well.  The implicit case is always a constructor conversion or copy-construction, right?</div></div></blockquote><div><br></div><div>Right. The oddball cases are CXXConstructExpr-used-for-list-initialization:</div><div><br></div><div>  f({1}, {2})</div><div><br></div><div>(which clearly isn't a CXXFunctionalCastExpr but probably shouldn't be just a CXXConstructExpr either)</div></div></div></div></div></blockquote><div><br></div></div></div><div>Yeah, this feels like an obvious candidate for a CXXConstructExpr subclass.  Do we just forget the brace locations completely in this case?  Or is there some sort of “I was written with braces instead of parens” flag on CXXConstructExpr?</div></div></div></blockquote><div><br></div><div>There are two flags ("I was written with braces", and "Just kidding, the braces were for my first constructor argument"), plus source locations for braces or parens, which are usually absent.</div><div><br></div><div>Adding CXXConstructExpr subclasses is annoying because we have the CXXTemporaryObjectExpr subclass, which is orthogonal to these other distinctions (so we risk ending up with two copies of each other CXXConstructExpr subclass we add). But CXXTemporaryObjectExpr is essentially pointless anyway -- it's equivalent to a CXXFunctionalCastExpr containing a CXXConstructExpr, so the best thing to do is probably to ditch it.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><span class=""><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> and CXXConstructExpr-used-for-direct-intiialization:</div><div><br></div><div>  T var(1, 2); // #1</div><div>  T var{1, 2}; // #2</div></div></div></div></div></blockquote><div><br></div></span>Ah, right, this is a weird case.</div><span class=""><div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>According to the rules we use in -ast-print, the parens belong to the initialization of the variable, not to the CXXConstructExpr, so that we can support</div><div><br></div><div>  int var(1);</div><div><br></div><div>with no additional AST nodes beyond the IntegerLiteral expression, but the braces in #2 usually belong to the CXXConstructExpr. Except when T has a constructor that takes std::initializer_list<int>, when they don't, because the braces belong to the construction of the underlying array of int. *sigh*<br></div></div></div></div>
</div></blockquote></div><br></span><div>Yuck.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>John.</div></font></span></div></blockquote></div><br></div></div>