xref: /llvm-project/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp (revision bc713f6a004723d1325bc16e1efc32d0ac82f939)
1 // RUN: %clang_cc1 -std=c++11 -verify %s
2 
3 struct B1 {
4   B1(int); // expected-note {{candidate}}
5 };
6 
7 struct B2 {
8   B2(int); // expected-note {{candidate}}
9 };
10 
11 struct D1 : B1, B2 {
12   using B1::B1; // expected-note {{inherited here}}
13   using B2::B2; // expected-note {{inherited here}}
14 };
15 D1 d1(0); // expected-error {{ambiguous}}
16 
17 struct D2 : B1, B2 {
18   using B1::B1;
19   using B2::B2;
20   D2(int);
21 };
22 D2 d2(0); // ok
23 
24 
25 // The emergent behavior of implicit special members is a bit odd when
26 // inheriting from multiple base classes.
27 namespace default_ctor {
28   struct C;
29   struct D;
30 
31   struct convert_to_D1 {
32     operator D&&();
33   };
34   struct convert_to_D2 {
35     operator D&&();
36   };
37 
38   struct A {
39     A();
40 
41     A(C &&);
42     C &operator=(C&&);
43 
44     A(D &&);
45     D &operator=(D&&); // expected-note {{candidate}}
46 
47     A(convert_to_D2); // expected-note {{candidate}}
48   };
49 
50   struct B {
51     B();
52 
53     B(C &&);
54     C &operator=(C&&);
55 
56     B(D &&);
57     D &operator=(D&&); // expected-note {{candidate}}
58 
59     B(convert_to_D2); // expected-note {{candidate}}
60   };
61 
62   struct C : A, B {
63     using A::A;
64     using A::operator=;
65     using B::B;
66     using B::operator=;
67   };
68   struct D : A, B {
69     using A::A; // expected-note {{inherited here}}
70     using A::operator=;
71     using B::B; // expected-note {{inherited here}}
72     using B::operator=;
73 
74     D(int);
75     D(const D&);
76     D &operator=(const D&);
77   };
78 
79   C c;
f(C c)80   void f(C c) {
81     C c2(static_cast<C&&>(c));
82     c = static_cast<C&&>(c);
83   }
84 
85   // D does not declare D(), D(D&&), nor operator=(D&&), so the base class
86   // versions are inherited.
87   // Exception: we implicitly declare a default constructor so that we can
88   // reason about its properties.
89   D d; // ok, implicitly declared
f(D d)90   void f(D d) {
91     D d2(static_cast<D&&>(d)); // ok, ignores inherited constructors
92     D d3(convert_to_D1{}); // ok, ignores inherited constructors
93     D d4(convert_to_D2{}); // expected-error {{ambiguous}}
94     d = static_cast<D&&>(d); // expected-error {{ambiguous}}
95   }
96 
97   struct Y;
98   struct X {
99     X();
100     X(volatile Y &); // expected-note 3{{inherited constructor cannot be used to copy object}}
101   } x;
102   struct Y : X { using X::X; } volatile y;
103   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}}
104   Z z1(x); // expected-error {{no match}}
105   Z z2(y); // expected-error {{no match}}
106   Z z3(z); // expected-error {{no match}}
107 }
108