1 // RUN: %clang_cc1 -std=c++1z -verify %s
7 virtual void f() = 0; // expected-note 1+{{unimplemented}}
10 template<typename
> struct SecretlyAbstract
{
12 SecretlyAbstract(int);
13 virtual void f() = 0; // expected-note 1+{{unimplemented}}
15 using B
= SecretlyAbstract
<int>;
16 using C
= SecretlyAbstract
<float>;
17 using D
= SecretlyAbstract
<char>[1];
19 B b
; // expected-error {{abstract class}}
20 D d
; // expected-error {{abstract class}}
22 template<int> struct N
{};
24 // Note: C is not instantiated anywhere in this file, so we never discover that
25 // it is in fact abstract. The C++ standard suggests that we need to
26 // instantiate in all cases where abstractness could affect the validity of a
27 // program, but that breaks a *lot* of code, so we don't do that.
29 // FIXME: Once DR1640 is resolved, remove the check on forming an abstract
30 // array type entirely. The only restriction we need is that you can't create
31 // an object of abstract (most-derived) type.
34 // An abstract class shall not be used
36 // - as a parameter type
38 void f(A
){} // expected-error {{abstract class}}
39 void f(A
[1]){} // expected-error {{abstract class}}
40 void f(B
){} // expected-error {{abstract class}}
41 void f(B
[1]){} // expected-error {{abstract class}}
44 void f(D
){} // expected-error {{abstract class}}
45 void f(D
[1]){} // expected-error {{abstract class}}
47 // - as a function return type
50 A
f(N
<2>){} // expected-error {{abstract class}}
51 A (&f(N
<3>))[2]; // expected-error {{abstract class}}
52 B
f(N
<4>){} // expected-error {{abstract class}}
53 B (&f(N
<5>))[2]; // expected-error {{abstract class}}
57 // - as the type of an explicit conversion
60 A(); // expected-error {{abstract class}}
61 A(0); // expected-error {{abstract class}}
62 A
{}; // expected-error {{abstract class}}
63 A
{0}; // expected-error {{abstract class}}
64 (A
)(0); // expected-error {{abstract class}}
65 (A
){}; // expected-error {{abstract class}}
66 (A
){0}; // expected-error {{abstract class}}
68 D(); // expected-error {{array type}}
69 D
{}; // expected-error {{abstract class}}
70 D
{0}; // expected-error {{abstract class}}
71 (D
){}; // expected-error {{abstract class}}
72 (D
){0}; // expected-error {{abstract class}}
75 template<typename T
> void t(T
);
76 void i(A
&a
, B
&b
, C
&c
, D
&d
) {
77 t(a
); // expected-error {{allocating an object of abstract class type 'A'}}
78 t(b
); // expected-error {{allocating an object of abstract class type 'SecretlyAbstract<int>'}}
79 t(c
); // expected-error {{allocating an object of abstract class type}}
80 t(d
); // ok, decays to pointer
85 E(int n
) : A( A(n
) ) {} // expected-error {{abstract class}}
89 template<typename T
> struct initializer_list
{
94 std::initializer_list
<A
> ila
= {1, 2, 3, 4}; // expected-error {{abstract class}}