================
@@ -23,3 +22,67 @@ void test(A &a, B &b) {
   const A &&ar10 = static_cast<const A&&>(xvalue<A>());
   const A &&ar11 = static_cast<const A&&>(xvalue<B>());
 }
+
+struct C : private A { // expected-note 4 {{declared private here}}
+    C&& that();
+
+    void f() {
+        (void)static_cast<A&&>(*this);
+        (void)static_cast<const A&&>(*this);
+
+        (void)static_cast<A&&>(that());
+        (void)static_cast<const A&&>(that());
+    }
+};
+C c;
+const C cc;
+
+void f() {
+    static_cast<A&&>(c);        // expected-error {{cannot cast 'C' to its 
private base class 'A'}}
+    static_cast<A&&>(c.that()); // expected-error {{cannot cast 'C' to its 
private base class 'A'}}
+
+    static_cast<const A&&>(c);        // expected-error {{cannot cast 'C' to 
its private base class 'const A'}}
+    static_cast<const A&&>(c.that()); // expected-error {{cannot cast 'C' to 
its private base class 'const A'}}
+}
+
+constexpr auto v = (
+    (A&&)c,
+    (A&&)(C&&)c,
+    (A&&)cc,
+    (A&&)(const C&&)c,
+    (const A&&)c,
+    (const A&&)(C&&)c,
+    (const A&&)cc,
+    (const A&&)(const C&&)c
+);
+
+struct D : A, B { // expected-warning {{direct base 'A' is inaccessible due to 
ambiguity}}
+    D&& rv();
+};
+D d;
+
+void g(const D cd) {
+    static_cast<A&&>(d);      // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+    static_cast<A&&>(d.rv()); // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+
+    static_cast<const A&&>(d);      // expected-error {{ambiguous conversion 
from derived class 'D' to base class 'const A'}}
+    static_cast<const A&&>(d.rv()); // expected-error {{ambiguous conversion 
from derived class 'D' to base class 'const A'}}
+
+    (A&&)d;                  // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+    (A&&)(D&&)d;             // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+    (A&&)cd;                 // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+    (A&&)(const D&&)d;       // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+    (const A&&)d;            // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+    (const A&&)(D&&)d;       // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+    (const A&&)cd;           // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+    (const A&&)(const D&&)d; // expected-error {{ambiguous conversion from 
derived class 'D' to base class 'A'}}
+}
+
+template<class T, class U>
+auto h(U u = {}) -> decltype(static_cast<T&&>(u));
+
+template<class, class>
+int h();
+
+int i = h<A, C>();
+int j = h<A, D>();
----------------
Sirraide wrote:

I don’t think we normally test via SFINAE like this; I’d probably just remove 
the second `h()` overload and test that we actually emit an error.

https://github.com/llvm/llvm-project/pull/132285
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to