1 // { dg-do compile }
2 // Contributed by <giovannibajo at gcc dot gnu dot org>,
3 //                <pavel_vozenilek at hotmail dot com>,
4 //                <bangerth at dealii dot org>
5 // c++/9256: Make sure that a pointer to an array of abstract elements
6 //  cannot be created, not even during template substitution (DR337).
7 
8 // Changed massively by P0929R2: now only creating an object of the array type
9 // is ill-formed, not merely forming the array type.
10 
11 struct Abstract { virtual void f() = 0; };  // { dg-message "note" }
12 struct Complete { void f(); };
13 
14 
15 /*
16  * TEST 1
17  * Arrays of abstract elements cannot be defined.
18  */
19 
20 Abstract a0[2];        // { dg-error "" }
21 Abstract (*a1)[2];
22 Abstract (**a2)[2];
23 Abstract (***a3)[2];
24 Abstract *a4;
25 Abstract *a5[2];
26 Abstract (*a6[2])[2];
27 Abstract **a7[2];
28 Abstract *(*a8[2])[2];
29 Abstract (**a9[2])[2];
30 
31 /*
32  * TEST 2
33  * If an array of abstract elements is created during template
34  *  instantiation, an error should occur.
35  */
36 
37 template <class T> struct K {
38   T (*a1)[2];
39   T (a2)[2];   // { dg-error "abstract" }
40 };
41 
42 template struct K<Abstract>;  // { dg-message "required" }
43 
44 
45 
46 /*
47  * TEST 3
48 
49  * Deducing an array of abstract elements during type deduction is no longer a
50  *  silent failure.
51  */
52 
53 template <bool> struct StaticAssert;
54 template <> struct StaticAssert<true> {};
55 
56 typedef char Yes;
57 typedef struct { char x[2]; } No;
58 
59 template<typename U> No  is_abstract(U (*k)[1]);
60 template<typename U> Yes is_abstract(...);
61 
62 StaticAssert<sizeof(is_abstract<Abstract>(0)) == sizeof(No)> b1;
63 StaticAssert<sizeof(is_abstract<Complete>(0)) == sizeof(No)> b2;
64 StaticAssert<sizeof(is_abstract<int>(0)) == sizeof(No)> b3;
65