[cfe-commits] r159733 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/CodeGenCXX/const-init-cxx11.cpp test/CodeGenCXX/constructor-init.cpp test/SemaCXX/constant-expression-cxx11.cpp test/SemaCXX/cxx0x-initializer-constructor.cpp

Richard Smith richard at metafoo.co.uk
Sun Jul 8 13:03:19 PDT 2012


On Sun, Jul 8, 2012 at 12:18 PM, Johannes Schaub <
schaub.johannes at googlemail.com> wrote:

>
>
> Am 08.07.2012 20:30, schrieb Richard Smith:
>
>> On Sun, Jul 8, 2012 at 6:41 AM, Johannes Schaub
>> <schaub.johannes-gM/Ye1E23mwN+**BqQ9rBEUg at public.gmane.org<Ye1E23mwN%2BBqQ9rBEUg at public.gmane.org>
>>
>> <mailto:schaub.johannes-gM/Ye1**E23mwN+BqQ9rBEUg at public.gmane.**org<Ye1E23mwN%2BBqQ9rBEUg at public.gmane.org>>>
>> wrote:
>>
>>
>>
>>     Am 05.07.2012 10:39, schrieb Richard Smith:
>>
>>         Author: rsmith
>>         Date: Thu Jul  5 03:39:21 2012
>>         New Revision: 159733
>>
>>         URL: http://llvm.org/viewvc/llvm-__**project?rev=159733&view=rev<http://llvm.org/viewvc/llvm-__project?rev=159733&view=rev>
>>
>>         <http://llvm.org/viewvc/llvm-**project?rev=159733&view=rev<http://llvm.org/viewvc/llvm-project?rev=159733&view=rev>
>> >
>>         Log:
>>         PR13273: When performing list-initialization with an empty
>>         initializer list,
>>         actually perform value initialization rather than trying to fake
>>         it with a call
>>         to the default constructor. Fixes various bugs related to the
>>         previously-missing
>>         zero-initialization in this case.
>>
>>         I've also moved this and the other list initialization 'special
>>         case' from
>>         TryConstructorInitialization into TryListInitialization where
>>         they belong.
>>
>>     ...
>>
>>         +namespace explicit_default {
>>         +  struct A {
>>         +    explicit A(); // expected-note{{here}}
>>         +  };
>>         +  A a {}; // ok
>>         +  // This is copy-list-initialization, and we choose an
>>         explicit constructor
>>         +  // (even though we do so via value-initialization), so the
>>         initialization is
>>         +  // ill-formed.
>>         +  A b = {}; // expected-error{{chosen constructor is explicit}}
>>         +}
>>         +
>>
>>
>>     Richard, I'm pretty sure that this is valid code. A
>>     value-initialization doesn't respect "explicit". Are you assuming a
>>     C++ Standard defect here?
>>
>>
>> Here's my reading of the standard:
>>
>> By 8.5.4/1, this is copy-list-initialization. By 8.5.4/3, the object is
>> value-initialized. By 8.5/7, "the default constructor for T is called".
>> That's all normal.
>>
>> Now, the question is, does 13.3.1.7 apply when choosing the default
>> constructor to call, in the case where T has a default constructor and
>> so list-initialization delegates to value-initialization? If so, "In
>> copy-list-
>> initialization, if an explicit constructor is chosen, the initialization
>> is ill-formed." And I think 13.3.1.7 is actually pretty clearly intended
>> to apply to this case, because it says "If the initializer list has no
>> elements and T has a default constructor, the first phase is omitted." So
>> I think the standard is clear here that this should be ill-formed.
>>
>>
> The special casing of default constructors at 13.3.1.7 was not intended to
> make calls of explicit default constructors during value initialization
> ill-formed.
>
> It was intended to harmonize clause 13 with clause 8, because clause 13
> directly invokes 13.3.1.7 from 13.3.3.1.5 instead of special casing default
> constructors at that place.
>
> They fixed that by modifying 13.3.1.7 instead of introducing a new bullet
> in 13.3.3.1.5. See http://www.open-std.org/jtc1/**
> sc22/wg21/docs/cwg_defects.**html#1229<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1229>


What about this case, then:

struct S { explicit S(); };
void f(S);
void g() { f({}); }

Here, we do take the 13.3.3.1.5 route into 13.3.1.7. As with the other
form, g++ accepts the above, clang rejects it -- I think you are suggesting
that in this case clang is right, and in the other case, g++ is right? It
would seem surprising to me if this is intended to behave so differently
from other cases of copy-list-initialization from an empty initializer list.

My approach fares slightly better, but still has a surprise: with the
classes from my prior email, the above is legal under my interpretation if
S is replaced by A (because it's an aggregate), but ill-formed for B, C,
and D. The trivial default constructor exemption does not apply for B in
this case, because 13.3.3.1.5 doesn't mention it.

Regarding 8.5.4/3, it doesn't necessarily state that overload resolution is
> done. It simply says the "default constructor of T is called".
>

T could have multiple default constructors, so it seems to me that overload
resolution is implied by this.

The way that DR1229 was fixed however makes this thing way less clear than
> I initially felt it is, so I will partially agree with you that clang's
> trunk position is not all that bad, but I still feel like this should be
> talked with core (GCC does not implement it like this, for one).
>

g++ doesn't follow (my understanding of) your approach either, based on the
example above. I definitely think we have enough confusion here to warrant
a core issue :)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120708/44b1d1e8/attachment.html>


More information about the cfe-commits mailing list