// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios -verify -fptrauth-calls -std=c++2a %s // RUN: %clang_cc1 -fsyntax-only -triple aarch64-linux-gnu -verify -fptrauth-calls -std=c++2a %s namespace basic { #define authenticated(a, b, c...) [[clang::ptrauth_vtable_pointer(a, b, c)]] // Basic sanity tests #define TEST_AUTH(name, auth...) \ struct [[clang::ptrauth_vtable_pointer(auth)]] name { \ virtual ~name() {} \ } TEST_AUTH(NoParams); // expected-error@-1{{'ptrauth_vtable_pointer' attribute takes at least 3 arguments}} TEST_AUTH(NoAuth, no_authentication, default_address_discrimination, default_extra_discrimination); TEST_AUTH(InvalidKey, wat, default_address_discrimination, default_extra_discrimination); // expected-error@-1{{invalid authentication key 'wat'}} TEST_AUTH(InvalidAddressDiscrimination, no_authentication, wat, default_extra_discrimination); // expected-error@-1{{invalid address discrimination mode 'wat'}} TEST_AUTH(InvalidExtraDiscrimination, no_authentication, default_address_discrimination, wat); // expected-error@-1{{invalid extra discrimination selection 'wat'}} TEST_AUTH(InvalidNoCustomDiscrimination, no_authentication, default_address_discrimination, custom_discrimination); // expected-error@-1{{missing custom discrimination}} TEST_AUTH(InvalidCustomDiscrimination, no_authentication, default_address_discrimination, custom_discrimination, wat); // expected-error@-1{{invalid custom discrimination}} TEST_AUTH(Default, default_key, default_address_discrimination, default_extra_discrimination); TEST_AUTH(InvalidDefaultExtra, default_key, default_address_discrimination, default_extra_discrimination, 1); // expected-error@-1{{'ptrauth_vtable_pointer' attribute takes no more than 3 arguments}} TEST_AUTH(ProcessDependentKey, process_dependent, default_address_discrimination, default_extra_discrimination); TEST_AUTH(ProcessIndependentKey, process_independent, default_address_discrimination, default_extra_discrimination); TEST_AUTH(DefaultAddressDiscrimination, process_independent, default_address_discrimination, default_extra_discrimination); TEST_AUTH(NoAddressDiscrimination, process_independent, no_address_discrimination, default_extra_discrimination); TEST_AUTH(AddressDiscrimination, process_independent, address_discrimination, default_extra_discrimination); TEST_AUTH(DefaultExtraDiscrimination, process_independent, default_address_discrimination, default_extra_discrimination); TEST_AUTH(NoExtraDiscrimination, process_independent, default_address_discrimination, no_extra_discrimination); TEST_AUTH(TypeExtraDiscrimination, process_independent, default_address_discrimination, type_discrimination); TEST_AUTH(InvalidCustomExtraDiscrimination, process_independent, default_address_discrimination, custom_discrimination); // expected-error@-1{{missing custom discrimination}} TEST_AUTH(ValidCustomExtraDiscrimination, process_independent, default_address_discrimination, custom_discrimination, 1); // Basic valid authentication configuration #define generic_authenticated \ authenticated(process_independent, address_discrimination, type_discrimination) struct generic_authenticated ForwardDecl; struct generic_authenticated generic_authenticated InvalidDuplicateAttribute { // expected-error@-1{{multiple vtable pointer authentication policies on 'InvalidDuplicateAttribute'}} virtual ~InvalidDuplicateAttribute(){}; }; struct generic_authenticated ValidPolymorphic { virtual ~ValidPolymorphic(){}; }; struct generic_authenticated InvalidMonomorphic { // expected-error{{cannot set vtable pointer authentication on monomorphic type 'InvalidMonomorphic'}} }; struct ValidMonomorphic { }; struct ValidSubclass : ValidPolymorphic {}; struct generic_authenticated InvalidSubclass : ValidPolymorphic {}; // expected-error{{cannot set vtable pointer authentication on 'InvalidSubclass' which is a subclass of polymorphic type 'ValidPolymorphic'}} // Awful template time template struct generic_authenticated ExplicitlyAuthedMonomorphicTemplateClass : T {}; // expected-error@-1{{cannot set vtable pointer authentication on 'ExplicitlyAuthedMonomorphicTemplateClass' which is a subclass of polymorphic type 'ValidPolymorphic'}} // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClass'}} template struct generic_authenticated ExplicitlyAuthedPolymorphicTemplateClass : T { // expected-error{{cannot set vtable pointer authentication on 'ExplicitlyAuthedPolymorphicTemplateClass' which is a subclass of polymorphic type 'ValidPolymorphic'}} virtual ~ExplicitlyAuthedPolymorphicTemplateClass(){}; }; template struct UnauthedMonomorphicTemplateClass : T {}; template struct UnauthedPolymorphicTemplateClass : T { virtual ~UnauthedPolymorphicTemplateClass(){}; }; ExplicitlyAuthedMonomorphicTemplateClass test1; // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClass' requested here}} ExplicitlyAuthedMonomorphicTemplateClass test2; // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClass' requested here}} ExplicitlyAuthedPolymorphicTemplateClass test3; // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedPolymorphicTemplateClass' requested here}} ExplicitlyAuthedPolymorphicTemplateClass test4; UnauthedMonomorphicTemplateClass test5; UnauthedMonomorphicTemplateClass test6; UnauthedPolymorphicTemplateClass test7; UnauthedPolymorphicTemplateClass test8; // Just use a different policy from the generic macro to verify we won't complain // about the insanity struct authenticated(process_independent, no_address_discrimination, type_discrimination) SecondAuthenticatedPolymorphic { virtual ~SecondAuthenticatedPolymorphic(){}; }; struct UnauthenticatedPolymorphic { virtual ~UnauthenticatedPolymorphic(){}; }; struct MultipleParents1 : ValidPolymorphic, SecondAuthenticatedPolymorphic, UnauthenticatedPolymorphic {}; struct MultipleParents2 : UnauthenticatedPolymorphic, ValidPolymorphic, SecondAuthenticatedPolymorphic {}; struct generic_authenticated InvalidMultipleParents : UnauthenticatedPolymorphic, ValidPolymorphic, SecondAuthenticatedPolymorphic {}; // expected-error@-1{{cannot set vtable pointer authentication on 'InvalidMultipleParents' which is a subclass of polymorphic type 'UnauthenticatedPolymorphic'}} template struct generic_authenticated ExplicitlyAuthedPolymorphicTemplateClassNoBase { virtual ~ExplicitlyAuthedPolymorphicTemplateClassNoBase(); }; ExplicitlyAuthedPolymorphicTemplateClassNoBase v; struct ValidSubclassOfTemplate : ExplicitlyAuthedPolymorphicTemplateClassNoBase { }; struct generic_authenticated InvalidSubclassOfTemplate : ExplicitlyAuthedPolymorphicTemplateClassNoBase { // expected-error@-1{{cannot set vtable pointer authentication on 'InvalidSubclassOfTemplate' which is a subclass of polymorphic type 'ExplicitlyAuthedPolymorphicTemplateClassNoBase'}} }; template struct generic_authenticated ExplicitlyAuthedMonomorphicTemplateClassNoBase { // expected-error@-1{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClassNoBase'}} // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClassNoBase'}} }; ExplicitlyAuthedMonomorphicTemplateClassNoBase X; // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClassNoBase' requested here}} template struct generic_authenticated ExplicitlyAuthedTemplateClassValidBase : ValidMonomorphic { // expected-error@-1{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedTemplateClassValidBase'}} // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedTemplateClassValidBase'}} }; ExplicitlyAuthedTemplateClassValidBase Y; // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedTemplateClassValidBase' requested here}} template struct generic_authenticated ExplicitlyAuthedTemplateClassInvalidBase : ValidPolymorphic { // expected-error@-1{{cannot set vtable pointer authentication on 'ExplicitlyAuthedTemplateClassInvalidBase' which is a subclass of polymorphic type 'ValidPolymorphic'}} // expected-error@-2{{cannot set vtable pointer authentication on 'ExplicitlyAuthedTemplateClassInvalidBase' which is a subclass of polymorphic type 'ValidPolymorphic'}} }; ExplicitlyAuthedTemplateClassInvalidBase Z; // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedTemplateClassInvalidBase' requested here}} template class generic_authenticated TestPolymorphicTemplateSpecialization; template <> class TestPolymorphicTemplateSpecialization { MissingDecl *zl; // expected-error@-1 {{unknown type name 'MissingDecl'}} public: virtual ~TestPolymorphicTemplateSpecialization(); }; template class generic_authenticated TestPolymorphicTemplateSpecialization // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'TestPolymorphicTemplateSpecialization'}} // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestPolymorphicTemplateSpecialization'}} { }; TestPolymorphicTemplateSpecialization b; TestPolymorphicTemplateSpecialization b2; // expected-note@-1 {{in instantiation of template class 'basic::TestPolymorphicTemplateSpecialization' requested here}} template class generic_authenticated TestMonomorphic {}; // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphic'}} // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphic'}} template <> class generic_authenticated TestMonomorphic { public: virtual ~TestMonomorphic(); }; struct TestMonomorphicSubclass : TestMonomorphic { }; template struct generic_authenticated TestMonomorphicSubclass2 : TestMonomorphic { // expected-error@-1 {{cannot set vtable pointer authentication on 'TestMonomorphicSubclass2' which is a subclass of polymorphic type 'TestMonomorphic'}} // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphicSubclass2'}} // expected-note@-3 {{in instantiation of template class 'basic::TestMonomorphic' requested here}} }; TestMonomorphicSubclass tms_1; TestMonomorphicSubclass2 tms2_1; // expected-note@-1 {{in instantiation of template class 'basic::TestMonomorphicSubclass2' requested here}} TestMonomorphicSubclass2 tms2_2; // expected-note@-1 {{in instantiation of template class 'basic::TestMonomorphicSubclass2' requested here}} // expected-note@-2 {{in instantiation of template class 'basic::TestMonomorphicSubclass2' requested here}} template class generic_authenticated dependent_type { // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'dependent_type'}} static constexpr unsigned small_object_size = 1; char _model[small_object_size]; }; template class generic_authenticated dependent_type2 : public T... { // expected-error@-1 {{cannot set vtable pointer authentication on 'dependent_type2' which is a subclass of polymorphic type 'Foo'}} static constexpr unsigned small_object_size = 1; char _model[small_object_size]; }; struct Foo { virtual ~Foo(); }; dependent_type2 thing; // expected-note@-1 {{in instantiation of template class 'basic::dependent_type2' requested here}} template class task; template struct alignedthing { char buffer[align]; }; template class generic_authenticated task { // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'task'}} static constexpr __SIZE_TYPE__ small_object_size = 256; alignedthing _model; }; } // namespace basic