[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

Johannes Schaub schaub.johannes at googlemail.com
Sun Jul 8 13:42:48 PDT 2012


Am 08.07.2012 22:03, schrieb Richard Smith:
> On Sun, Jul 8, 2012 at 12:18 PM, Johannes Schaub
> <schaub.johannes at googlemail.com
> <mailto: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
>         <mailto:Ye1E23mwN%2BBqQ9rBEUg at public.gmane.org>
>
>         <mailto:schaub.johannes-gM
>         <mailto:schaub.johannes-gM>/Ye1__E23mwN+BqQ9rBEUg at public.gmane.__org
>         <mailto: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.
>

I agree that this doesn't quite match my expectation. IMO that is 
disturbing.

>     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.
>

Honestly I don't know. We have no overload resolution context in clause 
13 for such a thing when the call happens entirely implicitly by default 
initialization, so I assumed that no OR happens and the consequence is 
just "if there are more than one default constructors, it's ill-formed".

But now it's entirely unclear to me what that means for templated 
constructors, so I guess that somehow one is supposed to assume that 
there is a function call with the function call syntax or something. 
Note that prior to C++11, a constructor template could not be able to be 
called as a default constructor, so in C++03, this wasn't an issue. In 
C++11 we got function template default arguments and function parameter 
packs that make it possible.

>     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 :)
>

I think I agree.





More information about the cfe-commits mailing list