r210295 - Remove old proposal notices

Richard Smith richard at metafoo.co.uk
Thu Feb 5 00:25:05 PST 2015


On Wed, Feb 4, 2015 at 11:24 PM, John McCall <rjmccall at apple.com> wrote:

> On Feb 4, 2015, at 11:17 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> On Wed, Feb 4, 2015 at 11:08 PM, John McCall <rjmccall at apple.com> wrote:
>
>> On Feb 4, 2015, at 9:36 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>> On Wed, Feb 4, 2015 at 6:38 PM, John McCall <rjmccall at apple.com> wrote:
>>
>>> On Jun 5, 2014, at 4:17 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>>> > John: any chance we could get the ABI document updated with these? (
>>> http://sourcerytools.com/pipermail/cxx-abi-dev/2012-January/000024.html)
>>>
>>> After much delay, added.  We don’t seem to get this right, though, at
>>> least not when the destination type isn’t dependent:
>>>
>>> template <class T, class U> T fst(T, U);
>>> struct A {
>>>   int x[3];
>>> };
>>> template <class T> decltype(fst(A{1,2},T())) foo(T t) {}
>>>
>>> int main() {
>>>   foo(1);
>>> }
>>>
>>> We produce:
>>>   _Z3fooIiEDTcl3fstcv1AililLi1ELi2EEEcvT__EEES1_
>>> It should be:
>>>   _Z3fooIiEDTcl3fsttl1ALi1ELi2EcvT__EEES1_
>>>
>>
>> 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.
>>
>> If you parenthesize the argument to A:
>>>   template <class T> decltype(fst(A({1,2}),T())) foo(T t) {}
>>> We produce:
>>>   _Z3fooIiEDTcl3fstcv1AcvS0_ililLi1ELi2EEEcvT__EEES1_
>>> It should be:
>>>   _Z3fooIiEDTcl3fstcv1AliLi1ELi2EcvT__EEES1_
>>>
>>
>> Somewhat related, we also get this wrong:
>>
>> struct X { X(int); };
>> int f(X);
>> template<typename T> void f(decltype(f(0), T())) { f(0); }
>> void g() { f<int>(0); }
>>
>> ... because we explicitly mangle the implicit conversion from int to X. I
>> see
>>
>> _Z1fIiEvDTcmcl1fLi0EEcvT__EE from EDG
>> _Z1fIiEvDTcmclL_Z1f1XELi0EEcvT__EE from GCC
>> _Z1fIiEvDTcmclL_Z1f1XEcvS0_cvS0_Li0EEcvT__EE from Clang
>>
>>
>> Ugh, that’s awful.
>>
>> 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?
>>
>>
>> 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?
>>
>>
>> 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.
>>
>> 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.
>>
>>
>> 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?
>>
>
> Right. The oddball cases are CXXConstructExpr-used-for-list-initialization:
>
>   f({1}, {2})
>
> (which clearly isn't a CXXFunctionalCastExpr but probably shouldn't be
> just a CXXConstructExpr either)
>
>
> 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?
>

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.

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.

> and CXXConstructExpr-used-for-direct-intiialization:
>
>   T var(1, 2); // #1
>   T var{1, 2}; // #2
>
>
> Ah, right, this is a weird case.
>
> 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
>
>   int var(1);
>
> 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*
>
>
> Yuck.
>
> John.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150205/c70d7a73/attachment.html>


More information about the cfe-commits mailing list