#define MOZ_NEEDS_NO_VTABLE_TYPE __attribute__((annotate("moz_needs_no_vtable_type"))) template struct MOZ_NEEDS_NO_VTABLE_TYPE PickyConsumer { // expected-error {{'PickyConsumer' cannot be instantiated because 'B' has a VTable}} expected-error {{'PickyConsumer' cannot be instantiated because 'E' has a VTable}} expected-error {{'PickyConsumer' cannot be instantiated because 'F' has a VTable}} expected-error {{'PickyConsumer' cannot be instantiated because 'G' has a VTable}} T *m; }; template struct MOZ_NEEDS_NO_VTABLE_TYPE PickyConsumer_A { // expected-error {{'PickyConsumer_A' cannot be instantiated because 'B' has a VTable}} expected-error {{'PickyConsumer_A' cannot be instantiated because 'E' has a VTable}} expected-error {{'PickyConsumer_A' cannot be instantiated because 'F' has a VTable}} expected-error {{'PickyConsumer_A' cannot be instantiated because 'G' has a VTable}} T *m; }; template struct PickyConsumerWrapper { PickyConsumer_A m; // expected-note {{bad instantiation of 'PickyConsumer_A' requested here}} expected-note {{bad instantiation of 'PickyConsumer_A' requested here}} expected-note {{bad instantiation of 'PickyConsumer_A' requested here}} expected-note {{bad instantiation of 'PickyConsumer_A' requested here}} }; template struct MOZ_NEEDS_NO_VTABLE_TYPE PickyConsumer_B { // expected-error {{'PickyConsumer_B' cannot be instantiated because 'B' has a VTable}} expected-error {{'PickyConsumer_B' cannot be instantiated because 'E' has a VTable}} expected-error {{'PickyConsumer_B' cannot be instantiated because 'F' has a VTable}} expected-error {{'PickyConsumer_B' cannot be instantiated because 'G' has a VTable}} T *m; }; template struct PickyConsumerSubclass : PickyConsumer_B {}; // expected-note {{bad instantiation of 'PickyConsumer_B' requested here}} expected-note {{bad instantiation of 'PickyConsumer_B' requested here}} expected-note {{bad instantiation of 'PickyConsumer_B' requested here}} expected-note {{bad instantiation of 'PickyConsumer_B' requested here}} template struct NonPickyConsumer { T *m; }; struct A {}; struct B : virtual A {}; struct C : A {}; struct D { void d(); }; struct E { virtual void e(); }; struct F : E { void e() final; }; struct G { virtual void e() = 0; }; void f() { { PickyConsumer a1; PickyConsumerWrapper a2; PickyConsumerSubclass a3; NonPickyConsumer a4; } { PickyConsumer a1; // expected-note {{bad instantiation of 'PickyConsumer' requested here}} PickyConsumerWrapper a2; PickyConsumerSubclass a3; NonPickyConsumer a4; } { PickyConsumer a1; PickyConsumerWrapper a2; PickyConsumerSubclass a3; NonPickyConsumer a4; } { PickyConsumer a1; PickyConsumerWrapper a2; PickyConsumerSubclass a3; NonPickyConsumer a4; } { PickyConsumer a1; // expected-note {{bad instantiation of 'PickyConsumer' requested here}} PickyConsumerWrapper a2; PickyConsumerSubclass a3; NonPickyConsumer a4; } { PickyConsumer a1; // expected-note {{bad instantiation of 'PickyConsumer' requested here}} PickyConsumerWrapper a2; PickyConsumerSubclass a3; NonPickyConsumer a4; } { PickyConsumer a1; // expected-note {{bad instantiation of 'PickyConsumer' requested here}} PickyConsumerWrapper a2; PickyConsumerSubclass a3; NonPickyConsumer a4; } }