aboutsummaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/cxx11-inheriting-ctors.cpp
blob: c9e01188fd2e26488590ba3dd80c1eafd671a0ae (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// RUN: %clang_cc1 -std=c++11 %s -verify

namespace PR15757 {
  struct S {
  };

  template<typename X, typename Y> struct T {
    template<typename A> T(X x, A &&a) {}

    template<typename A> explicit T(A &&a)
        noexcept(noexcept(T(X(), static_cast<A &&>(a))))
      : T(X(), static_cast<A &&>(a)) {}
  };

  template<typename X, typename Y> struct U : T<X, Y> {
    using T<X, Y>::T;
  };

  U<S, char> foo(char ch) { return U<S, char>(ch); }

  int main() {
    U<S, int> a(42);
    U<S, char> b('4');
    return 0;
  }
}

namespace WrongIdent {
  struct A {};
  struct B : A {};
  struct C : B {
    using B::A;
  };
}

namespace DefaultCtorConflict {
  struct A { A(int = 0); };
  struct B : A {
    using A::A;
  } b; // ok, not ambiguous, inherited constructor suppresses implicit default constructor
  struct C {
    B b;
  } c;
}

namespace InvalidConstruction {
  struct A { A(int); };
  struct B { B() = delete; };
  struct C : A, B { using A::A; };
  // Initialization here is performed as if by a defaulted default constructor,
  // which would be ill-formed (in the immediate context) in this case because
  // it would be defined as deleted.
  template<typename T> void f(decltype(T(0))*);
  template<typename T> int &f(...);
  int &r = f<C>(0);
}

namespace ExplicitConv {
  struct B {};
  struct D : B { // expected-note 3{{candidate}}
    using B::B;
  };
  struct X { explicit operator B(); } x;
  struct Y { explicit operator D(); } y;

  D dx(x); // expected-error {{no matching constructor}}
  D dy(y);
}

namespace NestedListInit {
  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}}
  // 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}}
}