[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 11:30:20 PDT 2012


On Sun, Jul 8, 2012 at 6:41 AM, Johannes Schaub <
schaub.johannes at googlemail.com> 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>
>> 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.

That said, maybe this isn't what was intended, and if so, I think we have a
defect. I do find this disturbing:

struct A {
  explicit A() = default;
};
A a = {}; // ok in N3337, aggregate initialization (error in FDIS)
struct B : A {
  explicit B() = default;
};
B b = {}; // ok, trivial and not user-provided
struct C {
  explicit C();
};
C c = {}; // error, default ctor called because it is user-provided
struct D : A {
  C c;
  explicit D() = default;
};
D d = {}; // error, default ctor called because it is non-trivial

Note that CWG issue 1301 (voted into the WP at Kona) resolved that
aggregate initialization beats value-initialization, so A is valid and
clang accepts it. We reject C and D correctly, but incorrectly reject B,
because we don't model that the constructor is sometimes not actually
called by value-initialization.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120708/91cc6bab/attachment.html>


More information about the cfe-commits mailing list