<div dir="auto">Yes, let's.<div><div class="gmail_extra"><br><div class="gmail_quote">On 17 Jan 2017 9:11 pm, "Hans Wennborg" <<a href="mailto:hans@chromium.org">hans@chromium.org</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">What do you think; time to merge it?<br>
<div class="elided-text"><br>
On Fri, Jan 13, 2017 at 1:21 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
> I'd like to wait a bit to see how the dust settles on this one, but this is<br>
> a bugfix for a previous bugfix for a standard change, and we've had several<br>
> user complaints requesting that we fix the bug in the standard, so it's<br>
> probably a good change to get into Clang 4.<br>
><br>
> ---------- Forwarded message ----------<br>
> From: Richard Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>><br>
> Date: 13 January 2017 at 12:46<br>
> Subject: r291955 - PR31606: Generalize our tentative DR resolution for<br>
> inheriting copy/move<br>
> To: <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
><br>
><br>
> Author: rsmith<br>
> Date: Fri Jan 13 14:46:54 2017<br>
> New Revision: 291955<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=291955&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=291955&view=rev</a><br>
> Log:<br>
> PR31606: Generalize our tentative DR resolution for inheriting copy/move<br>
> constructors to better match the pre-P0136R1 behavior.<br>
><br>
> Modified:<br>
> cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
> cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp<br>
> cfe/trunk/test/CXX/dcl.dcl/<wbr>basic.namespace/namespace.<wbr>udecl/p15.cpp<br>
> cfe/trunk/test/CXX/dcl.decl/<wbr>dcl.init/dcl.init.aggr/p1.cpp<br>
> cfe/trunk/test/CXX/drs/dr16xx.<wbr>cpp<br>
> cfe/trunk/test/CXX/drs/dr19xx.<wbr>cpp<br>
> cfe/trunk/test/CXX/special/<wbr>class.inhctor/p1.cpp<br>
> cfe/trunk/test/CXX/special/<wbr>class.inhctor/p3.cpp<br>
> cfe/trunk/test/CXX/special/<wbr>class.inhctor/p7.cpp<br>
> cfe/trunk/test/SemaCXX/cxx11-<wbr>inheriting-ctors.cpp<br>
> cfe/trunk/test/SemaTemplate/<wbr>cxx1z-using-declaration.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/<wbr>DiagnosticSemaKinds.td?rev=<wbr>291955&r1=291954&r2=291955&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Fri Jan 13 14:46:54<br>
> 2017<br>
> @@ -3344,8 +3344,8 @@ def note_ovl_candidate : Note<"candidate<br>
> def note_ovl_candidate_inherited_<wbr>constructor : Note<<br>
> "constructor from base class %0 inherited here">;<br>
> def note_ovl_candidate_inherited_<wbr>constructor_slice : Note<<br>
> - "constructor inherited from base class cannot be used to initialize<br>
> from "<br>
> - "an argument of the derived class type">;<br>
> + "candidate %select{constructor|template}0 ignored: "<br>
> + "inherited constructor cannot be used to %select{copy|move}1 object">;<br>
> def note_ovl_candidate_illegal_<wbr>constructor : Note<<br>
> "candidate %select{constructor|template}0 ignored: "<br>
> "instantiation %select{takes|would take}0 its own class type by<br>
> value">;<br>
><br>
> Modified: cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp?rev=291955&<wbr>r1=291954&r2=291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp Fri Jan 13 14:46:54 2017<br>
> @@ -5944,6 +5944,28 @@ Sema::AddOverloadCandidate(<wbr>FunctionDecl<br>
> Candidate.FailureKind = ovl_fail_illegal_constructor;<br>
> return;<br>
> }<br>
> +<br>
> + // C++ [over.match.funcs]p8: (proposed DR resolution)<br>
> + // A constructor inherited from class type C that has a first<br>
> parameter<br>
> + // of type "reference to P" (including such a constructor<br>
> instantiated<br>
> + // from a template) is excluded from the set of candidate functions<br>
> when<br>
> + // constructing an object of type cv D if the argument list has<br>
> exactly<br>
> + // one argument and D is reference-related to P and P is<br>
> reference-related<br>
> + // to C.<br>
> + auto *Shadow =<br>
> dyn_cast<<wbr>ConstructorUsingShadowDecl>(<wbr>FoundDecl.getDecl());<br>
> + if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 &&<br>
> + Constructor->getParamDecl(0)-><wbr>getType()->isReferenceType()) {<br>
> + QualType P =<br>
> Constructor->getParamDecl(0)-><wbr>getType()->getPointeeType();<br>
> + QualType C = Context.getRecordType(<wbr>Constructor->getParent());<br>
> + QualType D = Context.getRecordType(Shadow-><wbr>getParent());<br>
> + SourceLocation Loc = Args.front()->getExprLoc();<br>
> + if ((Context.<wbr>hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P,<br>
> C)) &&<br>
> + (Context.<wbr>hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D,<br>
> P))) {<br>
> + Candidate.Viable = false;<br>
> + Candidate.FailureKind = ovl_fail_inhctor_slice;<br>
> + return;<br>
> + }<br>
> + }<br>
> }<br>
><br>
> unsigned NumParams = Proto->getNumParams();<br>
> @@ -6016,31 +6038,6 @@ Sema::AddOverloadCandidate(<wbr>FunctionDecl<br>
> }<br>
> }<br>
><br>
> - // C++ [over.best.ics]p4+: (proposed DR resolution)<br>
> - // If the target is the first parameter of an inherited constructor<br>
> when<br>
> - // constructing an object of type C with an argument list that has<br>
> exactly<br>
> - // one expression, an implicit conversion sequence cannot be formed if<br>
> C is<br>
> - // reference-related to the type that the argument would have after the<br>
> - // application of the user-defined conversion (if any) and before the<br>
> final<br>
> - // standard conversion sequence.<br>
> - auto *Shadow = dyn_cast<<wbr>ConstructorUsingShadowDecl>(<wbr>FoundDecl.getDecl());<br>
> - if (Shadow && Args.size() == 1 && !isa<InitListExpr>(Args.front(<wbr>))) {<br>
> - bool DerivedToBase, ObjCConversion, ObjCLifetimeConversion;<br>
> - QualType ConvertedArgumentType = Args.front()->getType();<br>
> - if (Candidate.Conversions[0].<wbr>isUserDefined())<br>
> - ConvertedArgumentType =<br>
> - Candidate.Conversions[0].<wbr>UserDefined.After.getFromType(<wbr>);<br>
> - if (CompareReferenceRelationship(<wbr>Args.front()->getLocStart(),<br>
> -<br>
> Context.getRecordType(Shadow-><wbr>getParent()),<br>
> - ConvertedArgumentType, DerivedToBase,<br>
> - ObjCConversion,<br>
> - ObjCLifetimeConversion) >=<br>
> Ref_Related) {<br>
> - Candidate.Viable = false;<br>
> - Candidate.FailureKind = ovl_fail_inhctor_slice;<br>
> - return;<br>
> - }<br>
> - }<br>
> -<br>
> if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) {<br>
> Candidate.Viable = false;<br>
> Candidate.FailureKind = ovl_fail_enable_if;<br>
> @@ -10222,8 +10219,13 @@ static void NoteFunctionCandidate(Sema &<br>
> return DiagnoseOpenCLExtensionDisable<wbr>d(S, Cand);<br>
><br>
> case ovl_fail_inhctor_slice:<br>
> + // It's generally not interesting to note copy/move constructors here.<br>
> + if (cast<CXXConstructorDecl>(Fn)-<wbr>>isCopyOrMoveConstructor())<br>
> + return;<br>
> S.Diag(Fn->getLocation(),<br>
> - diag::note_ovl_candidate_<wbr>inherited_constructor_slice);<br>
> + diag::note_ovl_candidate_<wbr>inherited_constructor_slice)<br>
> + << (Fn->getPrimaryTemplate() ? 1 : 0)<br>
> + << Fn->getParamDecl(0)->getType()<wbr>->isRValueReferenceType();<br>
> MaybeEmitInheritedConstructorN<wbr>ote(S, Cand->FoundDecl);<br>
> return;<br>
><br>
><br>
> Modified: cfe/trunk/test/CXX/dcl.dcl/<wbr>basic.namespace/namespace.<wbr>udecl/p15.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>dcl.dcl/basic.namespace/<wbr>namespace.udecl/p15.cpp?rev=<wbr>291955&r1=291954&r2=291955&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CXX/dcl.dcl/<wbr>basic.namespace/namespace.<wbr>udecl/p15.cpp<br>
> (original)<br>
> +++ cfe/trunk/test/CXX/dcl.dcl/<wbr>basic.namespace/namespace.<wbr>udecl/p15.cpp Fri<br>
> Jan 13 14:46:54 2017<br>
> @@ -1,16 +1,16 @@<br>
> // RUN: %clang_cc1 -std=c++11 -verify %s<br>
><br>
> -struct B1 { // expected-note 2{{candidate}}<br>
> +struct B1 {<br>
> B1(int); // expected-note {{candidate}}<br>
> };<br>
><br>
> -struct B2 { // expected-note 2{{candidate}}<br>
> +struct B2 {<br>
> B2(int); // expected-note {{candidate}}<br>
> };<br>
><br>
> struct D1 : B1, B2 { // expected-note 2{{candidate}}<br>
> - using B1::B1; // expected-note 3{{inherited here}}<br>
> - using B2::B2; // expected-note 3{{inherited here}}<br>
> + using B1::B1; // expected-note {{inherited here}}<br>
> + using B2::B2; // expected-note {{inherited here}}<br>
> };<br>
> D1 d1(0); // expected-error {{ambiguous}}<br>
><br>
> @@ -35,7 +35,7 @@ namespace default_ctor {<br>
> operator D&&();<br>
> };<br>
><br>
> - struct A { // expected-note 4{{candidate}}<br>
> + struct A { // expected-note 2{{candidate}}<br>
> A(); // expected-note {{candidate}}<br>
><br>
> A(C &&); // expected-note {{candidate}}<br>
> @@ -47,7 +47,7 @@ namespace default_ctor {<br>
> A(convert_to_D2); // expected-note {{candidate}}<br>
> };<br>
><br>
> - struct B { // expected-note 4{{candidate}}<br>
> + struct B { // expected-note 2{{candidate}}<br>
> B(); // expected-note {{candidate}}<br>
><br>
> B(C &&); // expected-note {{candidate}}<br>
> @@ -66,9 +66,9 @@ namespace default_ctor {<br>
> using B::operator=;<br>
> };<br>
> struct D : A, B {<br>
> - using A::A; // expected-note 5{{inherited here}}<br>
> + using A::A; // expected-note 3{{inherited here}}<br>
> using A::operator=;<br>
> - using B::B; // expected-note 5{{inherited here}}<br>
> + using B::B; // expected-note 3{{inherited here}}<br>
> using B::operator=;<br>
><br>
> D(int);<br>
> @@ -93,13 +93,13 @@ namespace default_ctor {<br>
> }<br>
><br>
> struct Y;<br>
> - struct X { // expected-note 2{{candidate}}<br>
> + struct X {<br>
> X();<br>
> - X(volatile Y &); // expected-note {{constructor inherited from base<br>
> class cannot be used to initialize from an argument of the derived class<br>
> type}}<br>
> + X(volatile Y &); // expected-note 3{{inherited constructor cannot be<br>
> used to copy object}}<br>
> } x;<br>
> - struct Y : X { using X::X; } volatile y; // expected-note 2{{candidate}}<br>
> - struct Z : Y { using Y::Y; } volatile z; // expected-note 3{{candidate}}<br>
> expected-note 5{{inherited here}}<br>
> - Z z1(x); // ok<br>
> - Z z2(y); // ok, Z is not reference-related to type of y<br>
> + struct Y : X { using X::X; } volatile y;<br>
> + struct Z : Y { using Y::Y; } volatile z; // expected-note 4{{no known<br>
> conversion}} expected-note 2{{would lose volatile}} expected-note<br>
> 3{{requires 0}} expected-note 3{{inherited here}}<br>
> + Z z1(x); // expected-error {{no match}}<br>
> + Z z2(y); // expected-error {{no match}}<br>
> Z z3(z); // expected-error {{no match}}<br>
> }<br>
><br>
> Modified: cfe/trunk/test/CXX/dcl.decl/<wbr>dcl.init/dcl.init.aggr/p1.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>dcl.decl/dcl.init/dcl.init.<wbr>aggr/p1.cpp?rev=291955&r1=<wbr>291954&r2=291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CXX/dcl.decl/<wbr>dcl.init/dcl.init.aggr/p1.cpp (original)<br>
> +++ cfe/trunk/test/CXX/dcl.decl/<wbr>dcl.init/dcl.init.aggr/p1.cpp Fri Jan 13<br>
> 14:46:54 2017<br>
> @@ -134,13 +134,13 @@ ExplicitDefaultedAggr eda2{};<br>
><br>
> struct DefaultedBase {<br>
> int n;<br>
> - DefaultedBase() = default; // expected-note 0+ {{candidate}}<br>
> - DefaultedBase(DefaultedBase const&) = default; // expected-note 0+<br>
> {{candidate}}<br>
> - DefaultedBase(DefaultedBase &&) = default; // expected-note 0+<br>
> {{candidate}}<br>
> + DefaultedBase() = default;<br>
> + DefaultedBase(DefaultedBase const&) = default;<br>
> + DefaultedBase(DefaultedBase &&) = default;<br>
> };<br>
><br>
> struct InheritingConstructors : DefaultedBase { // expected-note 3<br>
> {{candidate}}<br>
> - using DefaultedBase::DefaultedBase; // expected-note 2 {{inherited here}}<br>
> + using DefaultedBase::DefaultedBase;<br>
> };<br>
> InheritingConstructors ic = { 42 }; // expected-error {{no matching<br>
> constructor}}<br>
><br>
><br>
> Modified: cfe/trunk/test/CXX/drs/dr16xx.<wbr>cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr16xx.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>drs/dr16xx.cpp?rev=291955&r1=<wbr>291954&r2=291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CXX/drs/dr16xx.<wbr>cpp (original)<br>
> +++ cfe/trunk/test/CXX/drs/dr16xx.<wbr>cpp Fri Jan 13 14:46:54 2017<br>
> @@ -71,14 +71,14 @@ namespace dr1638 { // dr1638: yes<br>
><br>
> namespace dr1645 { // dr1645: 3.9<br>
> #if __cplusplus >= 201103L<br>
> - struct A { // expected-note 2{{candidate}}<br>
> + struct A {<br>
> constexpr A(int, float = 0); // expected-note 2{{candidate}}<br>
> explicit A(int, int = 0); // expected-note 2{{candidate}}<br>
> A(int, int, int = 0) = delete; // expected-note {{candidate}}<br>
> };<br>
><br>
> struct B : A { // expected-note 2{{candidate}}<br>
> - using A::A; // expected-note 7{{inherited here}}<br>
> + using A::A; // expected-note 5{{inherited here}}<br>
> };<br>
><br>
> constexpr B a(0); // expected-error {{ambiguous}}<br>
><br>
> Modified: cfe/trunk/test/CXX/drs/dr19xx.<wbr>cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr19xx.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>drs/dr19xx.cpp?rev=291955&r1=<wbr>291954&r2=291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CXX/drs/dr19xx.<wbr>cpp (original)<br>
> +++ cfe/trunk/test/CXX/drs/dr19xx.<wbr>cpp Fri Jan 13 14:46:54 2017<br>
> @@ -138,18 +138,21 @@ namespace dr1959 { // dr1959: 3.9<br>
> struct c;<br>
> struct a {<br>
> a() = default;<br>
> - a(const a &) = delete; // expected-note 2{{deleted}}<br>
> + a(const a &) = delete; // expected-note {{deleted}}<br>
> a(const b &) = delete; // not inherited<br>
> - a(c &&) = delete;<br>
> - template<typename T> a(T) = delete;<br>
> + a(c &&) = delete; // expected-note {{not viable}}<br>
> + template<typename T> a(T) = delete; // expected-note {{would take its<br>
> own class type by value}}<br>
> };<br>
><br>
> - struct b : a { // expected-note {{copy constructor of 'b' is implicitly<br>
> deleted because base class 'dr1959::a' has a deleted copy constructor}}<br>
> - using a::a;<br>
> + struct b : a { // expected-note {{cannot bind}} expected-note {{deleted<br>
> because}}<br>
> + using a::a; // expected-note 2{{inherited here}}<br>
> };<br>
><br>
> a x;<br>
> - b y = x; // expected-error {{deleted}}<br>
> + // FIXME: As a resolution to an open DR against P0136R0, we disallow<br>
> + // use of inherited constructors to construct from a single argument<br>
> + // where the base class is reference-related to the argument type.<br>
> + b y = x; // expected-error {{no viable conversion}}<br>
> b z = z; // expected-error {{deleted}}<br>
><br>
> struct c : a {<br>
> @@ -158,7 +161,7 @@ namespace dr1959 { // dr1959: 3.9<br>
> };<br>
> // FIXME: As a resolution to an open DR against P0136R0, we disallow<br>
> // use of inherited constructors to construct from a single argument<br>
> - // where the derived class is reference-related to its type.<br>
> + // where the base class is reference-related to the argument type.<br>
> c q(static_cast<c&&>(q));<br>
> #endif<br>
> }<br>
><br>
> Modified: cfe/trunk/test/CXX/special/<wbr>class.inhctor/p1.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.inhctor/p1.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>special/class.inhctor/p1.cpp?<wbr>rev=291955&r1=291954&r2=<wbr>291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CXX/special/<wbr>class.inhctor/p1.cpp (original)<br>
> +++ cfe/trunk/test/CXX/special/<wbr>class.inhctor/p1.cpp Fri Jan 13 14:46:54 2017<br>
> @@ -3,7 +3,7 @@<br>
> // Note: [class.inhctor] was removed by P0136R1. This tests the new<br>
> behavior<br>
> // for the wording that used to be there.<br>
><br>
> -struct A { // expected-note 8{{candidate is the implicit}}<br>
> +struct A { // expected-note 4{{candidate is the implicit}}<br>
> A(...); // expected-note 4{{candidate constructor}} expected-note<br>
> 4{{candidate inherited constructor}}<br>
> A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 3{{candidate<br>
> constructor}} expected-note 3{{candidate inherited constructor}}<br>
> A(int = 0, int = 0, ...); // expected-note 3{{candidate constructor}}<br>
> expected-note 3{{candidate inherited constructor}}<br>
> @@ -15,7 +15,7 @@ struct A { // expected-note 8{{candidate<br>
> };<br>
><br>
> struct B : A { // expected-note 4{{candidate is the implicit}}<br>
> - using A::A; // expected-note 19{{inherited here}}<br>
> + using A::A; // expected-note 15{{inherited here}}<br>
> B(void*);<br>
> };<br>
><br>
><br>
> Modified: cfe/trunk/test/CXX/special/<wbr>class.inhctor/p3.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.inhctor/p3.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>special/class.inhctor/p3.cpp?<wbr>rev=291955&r1=291954&r2=<wbr>291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CXX/special/<wbr>class.inhctor/p3.cpp (original)<br>
> +++ cfe/trunk/test/CXX/special/<wbr>class.inhctor/p3.cpp Fri Jan 13 14:46:54 2017<br>
> @@ -14,21 +14,21 @@ D1 d1a(1), d1b(1, 1);<br>
><br>
> D1 fd1() { return 1; }<br>
><br>
> -struct B2 { // expected-note 2{{candidate}}<br>
> +struct B2 {<br>
> explicit B2(int, int = 0, int = 0);<br>
> };<br>
> struct D2 : B2 { // expected-note 2{{candidate constructor}}<br>
> - using B2::B2; // expected-note 2{{inherited here}}<br>
> + using B2::B2;<br>
> };<br>
> D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);<br>
><br>
> D2 fd2() { return 1; } // expected-error {{no viable conversion}}<br>
><br>
> -struct B3 { // expected-note 2{{candidate}}<br>
> +struct B3 {<br>
> B3(void*); // expected-note {{candidate}}<br>
> };<br>
> struct D3 : B3 { // expected-note 2{{candidate constructor}}<br>
> - using B3::B3; // expected-note 3{{inherited here}}<br>
> + using B3::B3; // expected-note {{inherited here}}<br>
> };<br>
> D3 fd3() { return 1; } // expected-error {{no viable conversion}}<br>
><br>
><br>
> Modified: cfe/trunk/test/CXX/special/<wbr>class.inhctor/p7.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.inhctor/p7.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>special/class.inhctor/p7.cpp?<wbr>rev=291955&r1=291954&r2=<wbr>291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CXX/special/<wbr>class.inhctor/p7.cpp (original)<br>
> +++ cfe/trunk/test/CXX/special/<wbr>class.inhctor/p7.cpp Fri Jan 13 14:46:54 2017<br>
> @@ -3,15 +3,15 @@<br>
> // Note: [class.inhctor] was removed by P0136R1. This tests the new<br>
> behavior<br>
> // for the wording that used to be there.<br>
><br>
> -struct B1 { // expected-note 2{{candidate}}<br>
> +struct B1 {<br>
> B1(int); // expected-note {{candidate}}<br>
> };<br>
> -struct B2 { // expected-note 2{{candidate}}<br>
> +struct B2 {<br>
> B2(int); // expected-note {{candidate}}<br>
> };<br>
> struct D1 : B1, B2 { // expected-note 2{{candidate}}<br>
> - using B1::B1; // expected-note 3{{inherited here}}<br>
> - using B2::B2; // expected-note 3{{inherited here}}<br>
> + using B1::B1; // expected-note {{inherited here}}<br>
> + using B2::B2; // expected-note {{inherited here}}<br>
> };<br>
> struct D2 : B1, B2 {<br>
> using B1::B1;<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/cxx11-<wbr>inheriting-ctors.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/cxx11-inheriting-<wbr>ctors.cpp?rev=291955&r1=<wbr>291954&r2=291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/SemaCXX/cxx11-<wbr>inheriting-ctors.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/cxx11-<wbr>inheriting-ctors.cpp Fri Jan 13 14:46:54<br>
> 2017<br>
> @@ -56,9 +56,9 @@ namespace InvalidConstruction {<br>
> }<br>
><br>
> namespace ExplicitConv {<br>
> - struct B {}; // expected-note 2{{candidate}}<br>
> + struct B {};<br>
> struct D : B { // expected-note 3{{candidate}}<br>
> - using B::B; // expected-note 2{{inherited}}<br>
> + using B::B;<br>
> };<br>
> struct X { explicit operator B(); } x;<br>
> struct Y { explicit operator D(); } y;<br>
> @@ -68,19 +68,40 @@ namespace ExplicitConv {<br>
> }<br>
><br>
> namespace NestedListInit {<br>
> - struct B { B(); } b; // expected-note 5{{candidate}}<br>
> - struct D : B { // expected-note 3{{candidate}}<br>
> - using B::B; // expected-note 2{{inherited}}<br>
> + struct B { B(); } b; // expected-note 3{{candidate}}<br>
> + struct D : B { // expected-note 14{{not viable}}<br>
> + using B::B;<br>
> };<br>
> // This is a bit weird. We're allowed one pair of braces for overload<br>
> // resolution, and one more pair of braces due to [over.ics.list]/2.<br>
> B b1 = {b};<br>
> B b2 = {{b}};<br>
> B b3 = {{{b}}}; // expected-error {{no match}}<br>
> - // This is the same, but we get one call to D's version of B::B(const B&)<br>
> - // before the two permitted calls to D::D(D&&).<br>
> - D d1 = {b};<br>
> - D d2 = {{b}};<br>
> - D d3 = {{{b}}};<br>
> + // Per a proposed defect resolution, we don't get to call<br>
> + // D's version of B::B(const B&) here.<br>
> + D d0 = b; // expected-error {{no viable conversion}}<br>
> + D d1 = {b}; // expected-error {{no match}}<br>
> + D d2 = {{b}}; // expected-error {{no match}}<br>
> + D d3 = {{{b}}}; // expected-error {{no match}}<br>
> D d4 = {{{{b}}}}; // expected-error {{no match}}<br>
> }<br>
> +<br>
> +namespace PR31606 {<br>
> + // PR31606: as part of a proposed defect resolution, do not consider<br>
> + // inherited constructors that would be copy constructors for any class<br>
> + // between the declaring class and the constructed class (inclusive).<br>
> + struct Base {};<br>
> +<br>
> + struct A : Base {<br>
> + using Base::Base;<br>
> + bool operator==(A const &) const; // expected-note {{no known<br>
> conversion from 'PR31606::B' to 'const PR31606::A' for 1st argument}}<br>
> + };<br>
> +<br>
> + struct B : Base {<br>
> + using Base::Base;<br>
> + };<br>
> +<br>
> + bool a = A{} == A{};<br>
> + // Note, we do *not* allow operator=='s argument to use the inherited<br>
> A::A(Base&&) constructor to construct from B{}.<br>
> + bool b = A{} == B{}; // expected-error {{invalid operands}}<br>
> +}<br>
><br>
> Modified: cfe/trunk/test/SemaTemplate/<wbr>cxx1z-using-declaration.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/cxx1z-using-declaration.cpp?rev=291955&r1=291954&r2=291955&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaTemplate/cxx1z-using-<wbr>declaration.cpp?rev=291955&r1=<wbr>291954&r2=291955&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/SemaTemplate/<wbr>cxx1z-using-declaration.cpp (original)<br>
> +++ cfe/trunk/test/SemaTemplate/<wbr>cxx1z-using-declaration.cpp Fri Jan 13<br>
> 14:46:54 2017<br>
> @@ -17,7 +17,7 @@ void test_Unexpanded() {<br>
><br>
> // Test using non-type members from pack of base classes.<br>
> template<typename ...T> struct A : T... { // expected-note 2{{candidate}}<br>
> - using T::T ...; // expected-note 6{{inherited here}}<br>
> + using T::T ...; // expected-note 2{{inherited here}}<br>
> using T::operator() ...;<br>
> using T::operator T* ...;<br>
> using T::h ...;<br>
> @@ -29,7 +29,7 @@ template<typename ...T> struct A : T...<br>
> };<br>
><br>
> namespace test_A {<br>
> - struct X { // expected-note 2{{candidate}}<br>
> + struct X {<br>
> X();<br>
> X(int); // expected-note {{candidate}}<br>
> void operator()(int); // expected-note 2{{candidate}}<br>
> @@ -43,7 +43,7 @@ namespace test_A {<br>
> operator Y *();<br>
> void h(int, int); // expected-note {{not viable}}<br>
> };<br>
> - struct Z { // expected-note 2{{candidate}}<br>
> + struct Z {<br>
> Z();<br>
> Z(int); // expected-note {{candidate}}<br>
> void operator()(int); // expected-note 2{{candidate}}<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
><br>
</div></blockquote></div><br></div></div></div>