r291955 - PR31606: Generalize our tentative DR resolution for inheriting copy/move
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 14 19:48:05 PST 2017
On 14 February 2017 at 18:14, Akira Hatanaka <ahatanaka at apple.com> wrote:
> Hi Richard,
>
> It looks like this commit causes an assertion failure when the following
> code is compiled:
>
> $ cat test1.cpp
> template<class T>
> struct S3 {
> };
>
> template<class T>
> struct S2 {
> S2(S3<T> &&);
> };
>
> template<class T>
> struct S1 : S2<T> {
> using S2<T>::S2;
> S1();
> };
>
> template<class T>
> struct S0 {
> S0();
> S0(S0&&) = default;
> S1<T> m1;
> };
>
> void foo1() {
> S0<int> s0;
> }
>
> $ clang++ -std=c++1z test1.cpp -c -o /dev/null
>
> Assertion failed: (Loc.isValid() && "point of instantiation must be
> valid!"),
>
> What’s the right way to fix this?
>
We should figure out where the invalid source location is coming from and
pass in a correct location. My current suspicion is the SourceLocation()s
in Sema::LookupSpecialMember.
> The patch I have now just checks whether PointOfInstantiation.isValid()
> returns true before calling Spec->setPointOfInstantiation at
> SemaTemplateInstantiate.cpp:1938.
>
> On Jan 13, 2017, at 12:46 PM, Richard Smith via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
> Author: rsmith
> Date: Fri Jan 13 14:46:54 2017
> New Revision: 291955
>
> URL: http://llvm.org/viewvc/llvm-project?rev=291955&view=rev
> Log:
> PR31606: Generalize our tentative DR resolution for inheriting copy/move
> constructors to better match the pre-P0136R1 behavior.
>
> Modified:
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/lib/Sema/SemaOverload.cpp
> cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
> cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp
> cfe/trunk/test/CXX/drs/dr16xx.cpp
> cfe/trunk/test/CXX/drs/dr19xx.cpp
> cfe/trunk/test/CXX/special/class.inhctor/p1.cpp
> cfe/trunk/test/CXX/special/class.inhctor/p3.cpp
> cfe/trunk/test/CXX/special/class.inhctor/p7.cpp
> cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp
> cfe/trunk/test/SemaTemplate/cxx1z-using-declaration.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
> DiagnosticSemaKinds.td?rev=291955&r1=291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 13
> 14:46:54 2017
> @@ -3344,8 +3344,8 @@ def note_ovl_candidate : Note<"candidate
> def note_ovl_candidate_inherited_constructor : Note<
> "constructor from base class %0 inherited here">;
> def note_ovl_candidate_inherited_constructor_slice : Note<
> - "constructor inherited from base class cannot be used to initialize
> from "
> - "an argument of the derived class type">;
> + "candidate %select{constructor|template}0 ignored: "
> + "inherited constructor cannot be used to %select{copy|move}1 object">;
> def note_ovl_candidate_illegal_constructor : Note<
> "candidate %select{constructor|template}0 ignored: "
> "instantiation %select{takes|would take}0 its own class type by
> value">;
>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaOverload.cpp?rev=291955&r1=291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Jan 13 14:46:54 2017
> @@ -5944,6 +5944,28 @@ Sema::AddOverloadCandidate(FunctionDecl
> Candidate.FailureKind = ovl_fail_illegal_constructor;
> return;
> }
> +
> + // C++ [over.match.funcs]p8: (proposed DR resolution)
> + // A constructor inherited from class type C that has a first
> parameter
> + // of type "reference to P" (including such a constructor
> instantiated
> + // from a template) is excluded from the set of candidate functions
> when
> + // constructing an object of type cv D if the argument list has
> exactly
> + // one argument and D is reference-related to P and P is
> reference-related
> + // to C.
> + auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(
> FoundDecl.getDecl());
> + if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 &&
> + Constructor->getParamDecl(0)->getType()->isReferenceType()) {
> + QualType P = Constructor->getParamDecl(0)->
> getType()->getPointeeType();
> + QualType C = Context.getRecordType(Constructor->getParent());
> + QualType D = Context.getRecordType(Shadow->getParent());
> + SourceLocation Loc = Args.front()->getExprLoc();
> + if ((Context.hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P,
> C)) &&
> + (Context.hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D,
> P))) {
> + Candidate.Viable = false;
> + Candidate.FailureKind = ovl_fail_inhctor_slice;
> + return;
> + }
> + }
> }
>
> unsigned NumParams = Proto->getNumParams();
> @@ -6016,31 +6038,6 @@ Sema::AddOverloadCandidate(FunctionDecl
> }
> }
>
> - // C++ [over.best.ics]p4+: (proposed DR resolution)
> - // If the target is the first parameter of an inherited constructor
> when
> - // constructing an object of type C with an argument list that has
> exactly
> - // one expression, an implicit conversion sequence cannot be formed
> if C is
> - // reference-related to the type that the argument would have after
> the
> - // application of the user-defined conversion (if any) and before the
> final
> - // standard conversion sequence.
> - auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(
> FoundDecl.getDecl());
> - if (Shadow && Args.size() == 1 && !isa<InitListExpr>(Args.front())) {
> - bool DerivedToBase, ObjCConversion, ObjCLifetimeConversion;
> - QualType ConvertedArgumentType = Args.front()->getType();
> - if (Candidate.Conversions[0].isUserDefined())
> - ConvertedArgumentType =
> - Candidate.Conversions[0].UserDefined.After.getFromType();
> - if (CompareReferenceRelationship(Args.front()->getLocStart(),
> - Context.getRecordType(
> Shadow->getParent()),
> - ConvertedArgumentType,
> DerivedToBase,
> - ObjCConversion,
> - ObjCLifetimeConversion) >=
> Ref_Related) {
> - Candidate.Viable = false;
> - Candidate.FailureKind = ovl_fail_inhctor_slice;
> - return;
> - }
> - }
> -
> if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) {
> Candidate.Viable = false;
> Candidate.FailureKind = ovl_fail_enable_if;
> @@ -10222,8 +10219,13 @@ static void NoteFunctionCandidate(Sema &
> return DiagnoseOpenCLExtensionDisabled(S, Cand);
>
> case ovl_fail_inhctor_slice:
> + // It's generally not interesting to note copy/move constructors here.
> + if (cast<CXXConstructorDecl>(Fn)->isCopyOrMoveConstructor())
> + return;
> S.Diag(Fn->getLocation(),
> - diag::note_ovl_candidate_inherited_constructor_slice);
> + diag::note_ovl_candidate_inherited_constructor_slice)
> + << (Fn->getPrimaryTemplate() ? 1 : 0)
> + << Fn->getParamDecl(0)->getType()->isRValueReferenceType();
> MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
> return;
>
>
> Modified: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.
> udecl/p15.cpp
> URL: 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
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
> (original)
> +++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
> Fri Jan 13 14:46:54 2017
> @@ -1,16 +1,16 @@
> // RUN: %clang_cc1 -std=c++11 -verify %s
>
> -struct B1 { // expected-note 2{{candidate}}
> +struct B1 {
> B1(int); // expected-note {{candidate}}
> };
>
> -struct B2 { // expected-note 2{{candidate}}
> +struct B2 {
> B2(int); // expected-note {{candidate}}
> };
>
> struct D1 : B1, B2 { // expected-note 2{{candidate}}
> - using B1::B1; // expected-note 3{{inherited here}}
> - using B2::B2; // expected-note 3{{inherited here}}
> + using B1::B1; // expected-note {{inherited here}}
> + using B2::B2; // expected-note {{inherited here}}
> };
> D1 d1(0); // expected-error {{ambiguous}}
>
> @@ -35,7 +35,7 @@ namespace default_ctor {
> operator D&&();
> };
>
> - struct A { // expected-note 4{{candidate}}
> + struct A { // expected-note 2{{candidate}}
> A(); // expected-note {{candidate}}
>
> A(C &&); // expected-note {{candidate}}
> @@ -47,7 +47,7 @@ namespace default_ctor {
> A(convert_to_D2); // expected-note {{candidate}}
> };
>
> - struct B { // expected-note 4{{candidate}}
> + struct B { // expected-note 2{{candidate}}
> B(); // expected-note {{candidate}}
>
> B(C &&); // expected-note {{candidate}}
> @@ -66,9 +66,9 @@ namespace default_ctor {
> using B::operator=;
> };
> struct D : A, B {
> - using A::A; // expected-note 5{{inherited here}}
> + using A::A; // expected-note 3{{inherited here}}
> using A::operator=;
> - using B::B; // expected-note 5{{inherited here}}
> + using B::B; // expected-note 3{{inherited here}}
> using B::operator=;
>
> D(int);
> @@ -93,13 +93,13 @@ namespace default_ctor {
> }
>
> struct Y;
> - struct X { // expected-note 2{{candidate}}
> + struct X {
> X();
> - X(volatile Y &); // expected-note {{constructor inherited from base
> class cannot be used to initialize from an argument of the derived class
> type}}
> + X(volatile Y &); // expected-note 3{{inherited constructor cannot be
> used to copy object}}
> } x;
> - struct Y : X { using X::X; } volatile y; // expected-note 2{{candidate}}
> - struct Z : Y { using Y::Y; } volatile z; // expected-note
> 3{{candidate}} expected-note 5{{inherited here}}
> - Z z1(x); // ok
> - Z z2(y); // ok, Z is not reference-related to type of y
> + struct Y : X { using X::X; } volatile y;
> + struct Z : Y { using Y::Y; } volatile z; // expected-note 4{{no known
> conversion}} expected-note 2{{would lose volatile}} expected-note
> 3{{requires 0}} expected-note 3{{inherited here}}
> + Z z1(x); // expected-error {{no match}}
> + Z z2(y); // expected-error {{no match}}
> Z z3(z); // expected-error {{no match}}
> }
>
> Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp
> URL: 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
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp (original)
> +++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1.cpp Fri Jan 13
> 14:46:54 2017
> @@ -134,13 +134,13 @@ ExplicitDefaultedAggr eda2{};
>
> struct DefaultedBase {
> int n;
> - DefaultedBase() = default; // expected-note 0+ {{candidate}}
> - DefaultedBase(DefaultedBase const&) = default; // expected-note 0+
> {{candidate}}
> - DefaultedBase(DefaultedBase &&) = default; // expected-note 0+
> {{candidate}}
> + DefaultedBase() = default;
> + DefaultedBase(DefaultedBase const&) = default;
> + DefaultedBase(DefaultedBase &&) = default;
> };
>
> struct InheritingConstructors : DefaultedBase { // expected-note 3
> {{candidate}}
> - using DefaultedBase::DefaultedBase; // expected-note 2 {{inherited
> here}}
> + using DefaultedBase::DefaultedBase;
> };
> InheritingConstructors ic = { 42 }; // expected-error {{no matching
> constructor}}
>
>
> Modified: cfe/trunk/test/CXX/drs/dr16xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> drs/dr16xx.cpp?rev=291955&r1=291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/drs/dr16xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr16xx.cpp Fri Jan 13 14:46:54 2017
> @@ -71,14 +71,14 @@ namespace dr1638 { // dr1638: yes
>
> namespace dr1645 { // dr1645: 3.9
> #if __cplusplus >= 201103L
> - struct A { // expected-note 2{{candidate}}
> + struct A {
> constexpr A(int, float = 0); // expected-note 2{{candidate}}
> explicit A(int, int = 0); // expected-note 2{{candidate}}
> A(int, int, int = 0) = delete; // expected-note {{candidate}}
> };
>
> struct B : A { // expected-note 2{{candidate}}
> - using A::A; // expected-note 7{{inherited here}}
> + using A::A; // expected-note 5{{inherited here}}
> };
>
> constexpr B a(0); // expected-error {{ambiguous}}
>
> Modified: cfe/trunk/test/CXX/drs/dr19xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> drs/dr19xx.cpp?rev=291955&r1=291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/drs/dr19xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr19xx.cpp Fri Jan 13 14:46:54 2017
> @@ -138,18 +138,21 @@ namespace dr1959 { // dr1959: 3.9
> struct c;
> struct a {
> a() = default;
> - a(const a &) = delete; // expected-note 2{{deleted}}
> + a(const a &) = delete; // expected-note {{deleted}}
> a(const b &) = delete; // not inherited
> - a(c &&) = delete;
> - template<typename T> a(T) = delete;
> + a(c &&) = delete; // expected-note {{not viable}}
> + template<typename T> a(T) = delete; // expected-note {{would take its
> own class type by value}}
> };
>
> - struct b : a { // expected-note {{copy constructor of 'b' is implicitly
> deleted because base class 'dr1959::a' has a deleted copy constructor}}
> - using a::a;
> + struct b : a { // expected-note {{cannot bind}} expected-note {{deleted
> because}}
> + using a::a; // expected-note 2{{inherited here}}
> };
>
> a x;
> - b y = x; // expected-error {{deleted}}
> + // FIXME: As a resolution to an open DR against P0136R0, we disallow
> + // use of inherited constructors to construct from a single argument
> + // where the base class is reference-related to the argument type.
> + b y = x; // expected-error {{no viable conversion}}
> b z = z; // expected-error {{deleted}}
>
> struct c : a {
> @@ -158,7 +161,7 @@ namespace dr1959 { // dr1959: 3.9
> };
> // FIXME: As a resolution to an open DR against P0136R0, we disallow
> // use of inherited constructors to construct from a single argument
> - // where the derived class is reference-related to its type.
> + // where the base class is reference-related to the argument type.
> c q(static_cast<c&&>(q));
> #endif
> }
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p1.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p1.cpp?rev=291955&r1=291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p1.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p1.cpp Fri Jan 13 14:46:54
> 2017
> @@ -3,7 +3,7 @@
> // Note: [class.inhctor] was removed by P0136R1. This tests the new
> behavior
> // for the wording that used to be there.
>
> -struct A { // expected-note 8{{candidate is the implicit}}
> +struct A { // expected-note 4{{candidate is the implicit}}
> A(...); // expected-note 4{{candidate constructor}} expected-note
> 4{{candidate inherited constructor}}
> A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note
> 3{{candidate constructor}} expected-note 3{{candidate inherited
> constructor}}
> A(int = 0, int = 0, ...); // expected-note 3{{candidate constructor}}
> expected-note 3{{candidate inherited constructor}}
> @@ -15,7 +15,7 @@ struct A { // expected-note 8{{candidate
> };
>
> struct B : A { // expected-note 4{{candidate is the implicit}}
> - using A::A; // expected-note 19{{inherited here}}
> + using A::A; // expected-note 15{{inherited here}}
> B(void*);
> };
>
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p3.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p3.cpp?rev=291955&r1=291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p3.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p3.cpp Fri Jan 13 14:46:54
> 2017
> @@ -14,21 +14,21 @@ D1 d1a(1), d1b(1, 1);
>
> D1 fd1() { return 1; }
>
> -struct B2 { // expected-note 2{{candidate}}
> +struct B2 {
> explicit B2(int, int = 0, int = 0);
> };
> struct D2 : B2 { // expected-note 2{{candidate constructor}}
> - using B2::B2; // expected-note 2{{inherited here}}
> + using B2::B2;
> };
> D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);
>
> D2 fd2() { return 1; } // expected-error {{no viable conversion}}
>
> -struct B3 { // expected-note 2{{candidate}}
> +struct B3 {
> B3(void*); // expected-note {{candidate}}
> };
> struct D3 : B3 { // expected-note 2{{candidate constructor}}
> - using B3::B3; // expected-note 3{{inherited here}}
> + using B3::B3; // expected-note {{inherited here}}
> };
> D3 fd3() { return 1; } // expected-error {{no viable conversion}}
>
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p7.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p7.cpp?rev=291955&r1=291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p7.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p7.cpp Fri Jan 13 14:46:54
> 2017
> @@ -3,15 +3,15 @@
> // Note: [class.inhctor] was removed by P0136R1. This tests the new
> behavior
> // for the wording that used to be there.
>
> -struct B1 { // expected-note 2{{candidate}}
> +struct B1 {
> B1(int); // expected-note {{candidate}}
> };
> -struct B2 { // expected-note 2{{candidate}}
> +struct B2 {
> B2(int); // expected-note {{candidate}}
> };
> struct D1 : B1, B2 { // expected-note 2{{candidate}}
> - using B1::B1; // expected-note 3{{inherited here}}
> - using B2::B2; // expected-note 3{{inherited here}}
> + using B1::B1; // expected-note {{inherited here}}
> + using B2::B2; // expected-note {{inherited here}}
> };
> struct D2 : B1, B2 {
> using B1::B1;
>
> Modified: cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaCXX/cxx11-inheriting-ctors.cpp?rev=291955&r1=
> 291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp (original)
> +++ cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp Fri Jan 13 14:46:54
> 2017
> @@ -56,9 +56,9 @@ namespace InvalidConstruction {
> }
>
> namespace ExplicitConv {
> - struct B {}; // expected-note 2{{candidate}}
> + struct B {};
> struct D : B { // expected-note 3{{candidate}}
> - using B::B; // expected-note 2{{inherited}}
> + using B::B;
> };
> struct X { explicit operator B(); } x;
> struct Y { explicit operator D(); } y;
> @@ -68,19 +68,40 @@ namespace ExplicitConv {
> }
>
> namespace NestedListInit {
> - struct B { B(); } b; // expected-note 5{{candidate}}
> - struct D : B { // expected-note 3{{candidate}}
> - using B::B; // expected-note 2{{inherited}}
> + struct B { B(); } b; // expected-note 3{{candidate}}
> + struct D : B { // expected-note 14{{not viable}}
> + using B::B;
> };
> // This is a bit weird. We're allowed one pair of braces for overload
> // resolution, and one more pair of braces due to [over.ics.list]/2.
> B b1 = {b};
> B b2 = {{b}};
> B b3 = {{{b}}}; // expected-error {{no match}}
> - // This is the same, but we get one call to D's version of B::B(const
> B&)
> - // before the two permitted calls to D::D(D&&).
> - D d1 = {b};
> - D d2 = {{b}};
> - D d3 = {{{b}}};
> + // Per a proposed defect resolution, we don't get to call
> + // D's version of B::B(const B&) here.
> + D d0 = b; // expected-error {{no viable conversion}}
> + D d1 = {b}; // expected-error {{no match}}
> + D d2 = {{b}}; // expected-error {{no match}}
> + D d3 = {{{b}}}; // expected-error {{no match}}
> D d4 = {{{{b}}}}; // expected-error {{no match}}
> }
> +
> +namespace PR31606 {
> + // PR31606: as part of a proposed defect resolution, do not consider
> + // inherited constructors that would be copy constructors for any class
> + // between the declaring class and the constructed class (inclusive).
> + struct Base {};
> +
> + struct A : Base {
> + using Base::Base;
> + bool operator==(A const &) const; // expected-note {{no known
> conversion from 'PR31606::B' to 'const PR31606::A' for 1st argument}}
> + };
> +
> + struct B : Base {
> + using Base::Base;
> + };
> +
> + bool a = A{} == A{};
> + // Note, we do *not* allow operator=='s argument to use the inherited
> A::A(Base&&) constructor to construct from B{}.
> + bool b = A{} == B{}; // expected-error {{invalid operands}}
> +}
>
> Modified: cfe/trunk/test/SemaTemplate/cxx1z-using-declaration.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaTemplate/cxx1z-using-declaration.cpp?rev=291955&r1=
> 291954&r2=291955&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaTemplate/cxx1z-using-declaration.cpp (original)
> +++ cfe/trunk/test/SemaTemplate/cxx1z-using-declaration.cpp Fri Jan 13
> 14:46:54 2017
> @@ -17,7 +17,7 @@ void test_Unexpanded() {
>
> // Test using non-type members from pack of base classes.
> template<typename ...T> struct A : T... { // expected-note 2{{candidate}}
> - using T::T ...; // expected-note 6{{inherited here}}
> + using T::T ...; // expected-note 2{{inherited here}}
> using T::operator() ...;
> using T::operator T* ...;
> using T::h ...;
> @@ -29,7 +29,7 @@ template<typename ...T> struct A : T...
> };
>
> namespace test_A {
> - struct X { // expected-note 2{{candidate}}
> + struct X {
> X();
> X(int); // expected-note {{candidate}}
> void operator()(int); // expected-note 2{{candidate}}
> @@ -43,7 +43,7 @@ namespace test_A {
> operator Y *();
> void h(int, int); // expected-note {{not viable}}
> };
> - struct Z { // expected-note 2{{candidate}}
> + struct Z {
> Z();
> Z(int); // expected-note {{candidate}}
> void operator()(int); // expected-note 2{{candidate}}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170214/47bfa14c/attachment-0001.html>
More information about the cfe-commits
mailing list