simulate-thread tests: Silence gdb debuginfod warning
[official-gcc.git] / gcc / testsuite / g++.dg / cpp0x / inh-ctor32.C
blob5ea2642e415d9a1416d9ddf3e034f308e9f2bd83
1 // { dg-do compile { target c++11 } }
2 // Minimized from the testcase for PR c++/88146,
3 // then turned into multiple variants. 
5 // We issue an error when calling an inherited ctor with at least one
6 // argument passed through a varargs ellipsis, if the call is in an
7 // evaluated context.  Even in nonevaluated contexts, we will
8 // instantiate constexpr templates (unlike non-constexpr templates),
9 // which might then issue errors that in nonevlauated contexts
10 // wouldn't be issued.
12 // In these variants, the inherited ctor is constexpr, but it's only
13 // called in unevaluated contexts, so no error is issued.  The
14 // templateness of the ctor doesn't matter, because the only call that
15 // passes args through the ellipsis is in a noexcept expr, that is not
16 // evaluated.  The ctors in derived classes are created and
17 // instantiated, discarding arguments passed through the ellipsis when
18 // calling base ctors, but that's not reported: we only report a
19 // problem when *calling* ctors that behave this way.
20 namespace unevaled_call {
21   namespace no_arg_before_ellipsis {
22     namespace without_template {
23       struct foo {
24         constexpr foo(...) {}
25       };
26       struct boo : foo {
27         using foo::foo;
28       };
29       struct bar : boo {
30         using boo::boo;
31       };
32       void f() noexcept(noexcept(bar{0}));
33     }
35     namespace with_template {
36       struct foo {
37         template <typename... T>
38         constexpr foo(...) {}
39       };
40       struct boo : foo {
41         using foo::foo;
42       };
43       struct bar : boo {
44         using boo::boo;
45       };
46       void f() noexcept(noexcept(bar{0}));
47     }
48   }
50   namespace one_arg_before_ellipsis {
51     namespace without_template {
52       struct foo {
53         constexpr foo(int, ...) {}
54       };
55       struct boo : foo {
56         using foo::foo;
57       };
58       struct bar : boo {
59         using boo::boo;
60       };
61       void f() noexcept(noexcept(bar{0,1}));
62     }
64     namespace with_template {
65       struct foo {
66         template <typename T>
67         constexpr foo(T, ...) {}
68       };
69       struct boo : foo {
70         using foo::foo;
71       };
72       struct bar : boo {
73         using boo::boo;
74       };
75       void f() noexcept(noexcept(bar{0,1}));
76     }
77   }
80 // In these variants, the inherited ctor is constexpr, and it's called
81 // in unevaluated contexts in ways that would otherwise trigger the
82 // sorry message.  Here we check that the message is not issued at
83 // those calls, nor at subsequent calls that use the same ctor without
84 // passing arguments through its ellipsis.  We check that it is issued
85 // later, when we pass the ctor arguments through the ellipsis.
86 namespace evaled_bad_call_in_u {
87   namespace one_arg_before_ellipsis {
88     namespace without_template {
89       struct foo {
90         constexpr foo(int, ...) {}
91       };
92       struct boo : foo {
93         using foo::foo;
94       };
95       struct bar : boo {
96         using boo::boo;
97       };
98       void f() noexcept(noexcept(bar{0, 1}));
99       bar t(0);
100       bar u(0, 1); // { dg-message "sorry, unimplemented: passing arguments to ellipsis" }
101     }
103     namespace with_template {
104       struct foo {
105         template <typename T>
106         constexpr foo(T, ...) {}
107       };
108       struct boo : foo {
109         using foo::foo;
110       };
111       struct bar : boo {
112         using boo::boo;
113       };
114       void f() noexcept(noexcept(bar{0,1}));
115       bar t(0);
116       bar u(0,1); // { dg-message "sorry, unimplemented: passing arguments to ellipsis" }
117     }
118   }
120   namespace no_arg_before_ellipsis {
121     namespace without_template {
122       struct foo {
123         constexpr foo(...) {}
124       };
125       struct boo : foo {
126         using foo::foo;
127       };
128       struct bar : boo {
129         using boo::boo;
130       };
131       void f() noexcept(noexcept(bar{0}));
132       bar u(0); // { dg-message "sorry, unimplemented: passing arguments to ellipsis" }
133     }
135     namespace with_template {
136       struct foo {
137         template <typename... T>
138         constexpr foo(...) {}
139       };
140       struct boo : foo {
141         using foo::foo;
142       };
143       struct bar : boo {
144         using boo::boo;
145       };
146       void f() noexcept(noexcept(bar{0}));
147       bar u(0); // { dg-message "sorry, unimplemented: passing arguments to ellipsis" }
148     }
149   }
152 // Now, instead of instantiating a class that uses a derived ctor, we
153 // introduce another template ctor that will use the varargs ctor to
154 // initialize its base class.  The idea is to verify that the error
155 // message is issued, even if the instantiation occurs in a
156 // nonevaluated context, e.g., for constexpr templates.  In the
157 // inherited_derived_ctor, we check that even an inherited ctor of a
158 // constexpr ctor is instantiated and have an error message issued.
159 namespace derived_ctor {
160   namespace direct_derived_ctor {
161     namespace constexpr_noninherited_ctor {
162       struct foo {
163         template <typename T>
164         constexpr foo(T, ...) {}
165       };
166       struct boo : foo {
167         using foo::foo;
168       };
169       struct bar : boo {
170         template <typename ...T>
171         constexpr bar(T ... args) : boo(args...) {}
172       };
173       void f() noexcept(noexcept(bar{0,1}));
174     }
176     namespace no_constexpr_noninherited_ctor {
177       struct foo {
178         template <typename T>
179         constexpr foo(T, ...) {}
180       };
181       struct boo : foo {
182         using foo::foo;
183       };
184       struct bar : boo {
185         template <typename ...T>
186         /* constexpr */ bar(T ... args) : boo(args...) {}
187       };
188       void f() noexcept(noexcept(bar{0,1}));
189     }
190   }
192   namespace inherited_derived_ctor {
193     namespace constexpr_noninherited_ctor {
194       struct foo {
195         template <typename T>
196         constexpr foo(T, ...) {}
197       };
198       struct boo : foo {
199         using foo::foo;
200       };
201       struct bor : boo {
202         template <typename ...T>
203         constexpr bor(T ... args) : boo(args...) {}
204       };
205       struct bar : bor {
206         using bor::bor;
207       };
208       void f() noexcept(noexcept(bar{0,1}));
209     }
211     namespace no_constexpr_noninherited_ctor {
212       struct foo {
213         template <typename T>
214         constexpr foo(T, ...) {}
215       };
216       struct boo : foo {
217         using foo::foo;
218       };
219       struct bor : boo {
220         template <typename ...T>
221         /* constexpr */ bor(T ... args) : boo(args...) {}
222       };
223       struct bar : bor {
224         using bor::bor;
225       };
226       void f() noexcept(noexcept(bar{0,1}));
227     }
228   }