On Sun, Jul 8, 2012 at 6:41 AM, Johannes Schaub < [email protected]> 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.
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
