xref: /llvm-project/clang/test/SemaCXX/vtable_pointer_authentication_attribute.cpp (revision a1d77caaabbb5279b734c061dab36b2138ec476d)
11b8ab2f0SOliver Hunt // RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios   -verify -fptrauth-calls -std=c++2a %s
2*a1d77caaSDaniil Kovalev // RUN: %clang_cc1 -fsyntax-only -triple aarch64-linux-gnu -verify -fptrauth-calls -std=c++2a %s
31b8ab2f0SOliver Hunt 
41b8ab2f0SOliver Hunt namespace basic {
51b8ab2f0SOliver Hunt 
61b8ab2f0SOliver Hunt #define authenticated(a, b, c...) [[clang::ptrauth_vtable_pointer(a, b, c)]]
71b8ab2f0SOliver Hunt 
81b8ab2f0SOliver Hunt // Basic sanity tests
91b8ab2f0SOliver Hunt #define TEST_AUTH(name, auth...)                        \
101b8ab2f0SOliver Hunt   struct [[clang::ptrauth_vtable_pointer(auth)]] name { \
111b8ab2f0SOliver Hunt     virtual ~name() {}                                  \
121b8ab2f0SOliver Hunt   }
131b8ab2f0SOliver Hunt 
141b8ab2f0SOliver Hunt TEST_AUTH(NoParams);
151b8ab2f0SOliver Hunt // expected-error@-1{{'ptrauth_vtable_pointer' attribute takes at least 3 arguments}}
161b8ab2f0SOliver Hunt TEST_AUTH(NoAuth, no_authentication, default_address_discrimination, default_extra_discrimination);
171b8ab2f0SOliver Hunt TEST_AUTH(InvalidKey, wat, default_address_discrimination, default_extra_discrimination);
181b8ab2f0SOliver Hunt // expected-error@-1{{invalid authentication key 'wat'}}
191b8ab2f0SOliver Hunt TEST_AUTH(InvalidAddressDiscrimination, no_authentication, wat, default_extra_discrimination);
201b8ab2f0SOliver Hunt // expected-error@-1{{invalid address discrimination mode 'wat'}}
211b8ab2f0SOliver Hunt TEST_AUTH(InvalidExtraDiscrimination, no_authentication, default_address_discrimination, wat);
221b8ab2f0SOliver Hunt // expected-error@-1{{invalid extra discrimination selection 'wat'}}
231b8ab2f0SOliver Hunt TEST_AUTH(InvalidNoCustomDiscrimination, no_authentication, default_address_discrimination, custom_discrimination);
241b8ab2f0SOliver Hunt // expected-error@-1{{missing custom discrimination}}
251b8ab2f0SOliver Hunt TEST_AUTH(InvalidCustomDiscrimination, no_authentication, default_address_discrimination, custom_discrimination, wat);
261b8ab2f0SOliver Hunt // expected-error@-1{{invalid custom discrimination}}
271b8ab2f0SOliver Hunt TEST_AUTH(Default, default_key, default_address_discrimination, default_extra_discrimination);
281b8ab2f0SOliver Hunt TEST_AUTH(InvalidDefaultExtra, default_key, default_address_discrimination, default_extra_discrimination, 1);
291b8ab2f0SOliver Hunt // expected-error@-1{{'ptrauth_vtable_pointer' attribute takes no more than 3 arguments}}
301b8ab2f0SOliver Hunt TEST_AUTH(ProcessDependentKey, process_dependent, default_address_discrimination, default_extra_discrimination);
311b8ab2f0SOliver Hunt TEST_AUTH(ProcessIndependentKey, process_independent, default_address_discrimination, default_extra_discrimination);
321b8ab2f0SOliver Hunt TEST_AUTH(DefaultAddressDiscrimination, process_independent, default_address_discrimination, default_extra_discrimination);
331b8ab2f0SOliver Hunt TEST_AUTH(NoAddressDiscrimination, process_independent, no_address_discrimination, default_extra_discrimination);
341b8ab2f0SOliver Hunt TEST_AUTH(AddressDiscrimination, process_independent, address_discrimination, default_extra_discrimination);
351b8ab2f0SOliver Hunt TEST_AUTH(DefaultExtraDiscrimination, process_independent, default_address_discrimination, default_extra_discrimination);
361b8ab2f0SOliver Hunt TEST_AUTH(NoExtraDiscrimination, process_independent, default_address_discrimination, no_extra_discrimination);
371b8ab2f0SOliver Hunt TEST_AUTH(TypeExtraDiscrimination, process_independent, default_address_discrimination, type_discrimination);
381b8ab2f0SOliver Hunt TEST_AUTH(InvalidCustomExtraDiscrimination, process_independent, default_address_discrimination, custom_discrimination);
391b8ab2f0SOliver Hunt // expected-error@-1{{missing custom discrimination}}
401b8ab2f0SOliver Hunt TEST_AUTH(ValidCustomExtraDiscrimination, process_independent, default_address_discrimination, custom_discrimination, 1);
411b8ab2f0SOliver Hunt 
421b8ab2f0SOliver Hunt // Basic valid authentication configuration
431b8ab2f0SOliver Hunt #define generic_authenticated \
441b8ab2f0SOliver Hunt   authenticated(process_independent, address_discrimination, type_discrimination)
451b8ab2f0SOliver Hunt 
461b8ab2f0SOliver Hunt struct generic_authenticated ForwardDecl;
471b8ab2f0SOliver Hunt 
481b8ab2f0SOliver Hunt struct generic_authenticated generic_authenticated InvalidDuplicateAttribute {
491b8ab2f0SOliver Hunt   // expected-error@-1{{multiple vtable pointer authentication policies on 'InvalidDuplicateAttribute'}}
501b8ab2f0SOliver Hunt   virtual ~InvalidDuplicateAttribute(){};
511b8ab2f0SOliver Hunt };
521b8ab2f0SOliver Hunt struct generic_authenticated ValidPolymorphic {
531b8ab2f0SOliver Hunt   virtual ~ValidPolymorphic(){};
541b8ab2f0SOliver Hunt };
551b8ab2f0SOliver Hunt struct generic_authenticated InvalidMonomorphic { // expected-error{{cannot set vtable pointer authentication on monomorphic type 'InvalidMonomorphic'}}
561b8ab2f0SOliver Hunt };
571b8ab2f0SOliver Hunt struct ValidMonomorphic {
581b8ab2f0SOliver Hunt };
591b8ab2f0SOliver Hunt 
601b8ab2f0SOliver Hunt struct ValidSubclass : ValidPolymorphic {};
611b8ab2f0SOliver Hunt struct generic_authenticated InvalidSubclass : ValidPolymorphic {}; // expected-error{{cannot set vtable pointer authentication on 'InvalidSubclass' which is a subclass of polymorphic type 'ValidPolymorphic'}}
621b8ab2f0SOliver Hunt 
631b8ab2f0SOliver Hunt // Awful template time
641b8ab2f0SOliver Hunt template <typename T>
651b8ab2f0SOliver Hunt struct generic_authenticated ExplicitlyAuthedMonomorphicTemplateClass : T {};
661b8ab2f0SOliver Hunt // expected-error@-1{{cannot set vtable pointer authentication on 'ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidPolymorphic>' which is a subclass of polymorphic type 'ValidPolymorphic'}}
671b8ab2f0SOliver Hunt // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidMonomorphic>'}}
681b8ab2f0SOliver Hunt template <typename T>
691b8ab2f0SOliver Hunt struct generic_authenticated ExplicitlyAuthedPolymorphicTemplateClass : T { // expected-error{{cannot set vtable pointer authentication on 'ExplicitlyAuthedPolymorphicTemplateClass<basic::ValidPolymorphic>' which is a subclass of polymorphic type 'ValidPolymorphic'}}
701b8ab2f0SOliver Hunt   virtual ~ExplicitlyAuthedPolymorphicTemplateClass(){};
711b8ab2f0SOliver Hunt };
721b8ab2f0SOliver Hunt template <typename T>
731b8ab2f0SOliver Hunt struct UnauthedMonomorphicTemplateClass : T {};
741b8ab2f0SOliver Hunt template <typename T>
751b8ab2f0SOliver Hunt struct UnauthedPolymorphicTemplateClass : T {
761b8ab2f0SOliver Hunt   virtual ~UnauthedPolymorphicTemplateClass(){};
771b8ab2f0SOliver Hunt };
781b8ab2f0SOliver Hunt 
791b8ab2f0SOliver Hunt ExplicitlyAuthedMonomorphicTemplateClass<ValidPolymorphic> test1;
801b8ab2f0SOliver Hunt // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidPolymorphic>' requested here}}
811b8ab2f0SOliver Hunt ExplicitlyAuthedMonomorphicTemplateClass<ValidMonomorphic> test2;
821b8ab2f0SOliver Hunt // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidMonomorphic>' requested here}}
831b8ab2f0SOliver Hunt ExplicitlyAuthedPolymorphicTemplateClass<ValidPolymorphic> test3;
841b8ab2f0SOliver Hunt // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedPolymorphicTemplateClass<basic::ValidPolymorphic>' requested here}}
851b8ab2f0SOliver Hunt ExplicitlyAuthedPolymorphicTemplateClass<ValidMonomorphic> test4;
861b8ab2f0SOliver Hunt 
871b8ab2f0SOliver Hunt UnauthedMonomorphicTemplateClass<ValidPolymorphic> test5;
881b8ab2f0SOliver Hunt UnauthedMonomorphicTemplateClass<ValidMonomorphic> test6;
891b8ab2f0SOliver Hunt UnauthedPolymorphicTemplateClass<ValidPolymorphic> test7;
901b8ab2f0SOliver Hunt UnauthedPolymorphicTemplateClass<ValidMonomorphic> test8;
911b8ab2f0SOliver Hunt 
921b8ab2f0SOliver Hunt // Just use a different policy from the generic macro to verify we won't complain
931b8ab2f0SOliver Hunt // about the insanity
941b8ab2f0SOliver Hunt struct authenticated(process_independent, no_address_discrimination, type_discrimination) SecondAuthenticatedPolymorphic {
951b8ab2f0SOliver Hunt   virtual ~SecondAuthenticatedPolymorphic(){};
961b8ab2f0SOliver Hunt };
971b8ab2f0SOliver Hunt struct UnauthenticatedPolymorphic {
981b8ab2f0SOliver Hunt   virtual ~UnauthenticatedPolymorphic(){};
991b8ab2f0SOliver Hunt };
1001b8ab2f0SOliver Hunt 
1011b8ab2f0SOliver Hunt struct MultipleParents1 : ValidPolymorphic, SecondAuthenticatedPolymorphic, UnauthenticatedPolymorphic {};
1021b8ab2f0SOliver Hunt struct MultipleParents2 : UnauthenticatedPolymorphic, ValidPolymorphic, SecondAuthenticatedPolymorphic {};
1031b8ab2f0SOliver Hunt struct generic_authenticated InvalidMultipleParents : UnauthenticatedPolymorphic, ValidPolymorphic, SecondAuthenticatedPolymorphic {};
1041b8ab2f0SOliver Hunt // expected-error@-1{{cannot set vtable pointer authentication on 'InvalidMultipleParents' which is a subclass of polymorphic type 'UnauthenticatedPolymorphic'}}
1051b8ab2f0SOliver Hunt 
1061b8ab2f0SOliver Hunt template <typename T>
1071b8ab2f0SOliver Hunt struct generic_authenticated ExplicitlyAuthedPolymorphicTemplateClassNoBase {
1081b8ab2f0SOliver Hunt   virtual ~ExplicitlyAuthedPolymorphicTemplateClassNoBase();
1091b8ab2f0SOliver Hunt };
1101b8ab2f0SOliver Hunt 
1111b8ab2f0SOliver Hunt ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> v;
1121b8ab2f0SOliver Hunt 
1131b8ab2f0SOliver Hunt struct ValidSubclassOfTemplate : ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> {
1141b8ab2f0SOliver Hunt };
1151b8ab2f0SOliver Hunt 
1161b8ab2f0SOliver Hunt struct generic_authenticated InvalidSubclassOfTemplate : ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> {
1171b8ab2f0SOliver Hunt   // expected-error@-1{{cannot set vtable pointer authentication on 'InvalidSubclassOfTemplate' which is a subclass of polymorphic type 'ExplicitlyAuthedPolymorphicTemplateClassNoBase<int>'}}
1181b8ab2f0SOliver Hunt };
1191b8ab2f0SOliver Hunt 
1201b8ab2f0SOliver Hunt template <typename T>
1211b8ab2f0SOliver Hunt struct generic_authenticated ExplicitlyAuthedMonomorphicTemplateClassNoBase {
1221b8ab2f0SOliver Hunt   // expected-error@-1{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClassNoBase'}}
1231b8ab2f0SOliver Hunt   // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClassNoBase<int>'}}
1241b8ab2f0SOliver Hunt };
1251b8ab2f0SOliver Hunt 
1261b8ab2f0SOliver Hunt ExplicitlyAuthedMonomorphicTemplateClassNoBase<int> X;
1271b8ab2f0SOliver Hunt // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClassNoBase<int>' requested here}}
1281b8ab2f0SOliver Hunt 
1291b8ab2f0SOliver Hunt template <typename T>
1301b8ab2f0SOliver Hunt struct generic_authenticated ExplicitlyAuthedTemplateClassValidBase : ValidMonomorphic {
1311b8ab2f0SOliver Hunt   // expected-error@-1{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedTemplateClassValidBase'}}
1321b8ab2f0SOliver Hunt   // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedTemplateClassValidBase<int>'}}
1331b8ab2f0SOliver Hunt };
1341b8ab2f0SOliver Hunt 
1351b8ab2f0SOliver Hunt ExplicitlyAuthedTemplateClassValidBase<int> Y;
1361b8ab2f0SOliver Hunt // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedTemplateClassValidBase<int>' requested here}}
1371b8ab2f0SOliver Hunt 
1381b8ab2f0SOliver Hunt template <typename T>
1391b8ab2f0SOliver Hunt struct generic_authenticated ExplicitlyAuthedTemplateClassInvalidBase : ValidPolymorphic {
1401b8ab2f0SOliver Hunt   // expected-error@-1{{cannot set vtable pointer authentication on 'ExplicitlyAuthedTemplateClassInvalidBase' which is a subclass of polymorphic type 'ValidPolymorphic'}}
1411b8ab2f0SOliver Hunt   // expected-error@-2{{cannot set vtable pointer authentication on 'ExplicitlyAuthedTemplateClassInvalidBase<int>' which is a subclass of polymorphic type 'ValidPolymorphic'}}
1421b8ab2f0SOliver Hunt };
1431b8ab2f0SOliver Hunt 
1441b8ab2f0SOliver Hunt ExplicitlyAuthedTemplateClassInvalidBase<int> Z;
1451b8ab2f0SOliver Hunt // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedTemplateClassInvalidBase<int>' requested here}}
1461b8ab2f0SOliver Hunt 
1471b8ab2f0SOliver Hunt template <class test1, class test2>
1481b8ab2f0SOliver Hunt class generic_authenticated TestPolymorphicTemplateSpecialization;
1491b8ab2f0SOliver Hunt 
1501b8ab2f0SOliver Hunt template <>
1511b8ab2f0SOliver Hunt class TestPolymorphicTemplateSpecialization<double, float> {
1521b8ab2f0SOliver Hunt   MissingDecl *zl;
1531b8ab2f0SOliver Hunt   // expected-error@-1 {{unknown type name 'MissingDecl'}}
1541b8ab2f0SOliver Hunt public:
1551b8ab2f0SOliver Hunt   virtual ~TestPolymorphicTemplateSpecialization();
1561b8ab2f0SOliver Hunt };
1571b8ab2f0SOliver Hunt template <class test1>
1581b8ab2f0SOliver Hunt class generic_authenticated TestPolymorphicTemplateSpecialization<test1, double>
1591b8ab2f0SOliver Hunt // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'TestPolymorphicTemplateSpecialization<test1, double>'}}
1601b8ab2f0SOliver Hunt // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestPolymorphicTemplateSpecialization<double, double>'}}
1611b8ab2f0SOliver Hunt {
1621b8ab2f0SOliver Hunt };
1631b8ab2f0SOliver Hunt 
1641b8ab2f0SOliver Hunt TestPolymorphicTemplateSpecialization<double, float> b;
1651b8ab2f0SOliver Hunt TestPolymorphicTemplateSpecialization<double, double> b2;
1661b8ab2f0SOliver Hunt // expected-note@-1 {{in instantiation of template class 'basic::TestPolymorphicTemplateSpecialization<double, double>' requested here}}
1671b8ab2f0SOliver Hunt 
1681b8ab2f0SOliver Hunt template <typename A> class generic_authenticated TestMonomorphic {};
1691b8ab2f0SOliver Hunt // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphic'}}
1701b8ab2f0SOliver Hunt // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphic<double>'}}
1711b8ab2f0SOliver Hunt 
1721b8ab2f0SOliver Hunt template <> class generic_authenticated TestMonomorphic<int> {
1731b8ab2f0SOliver Hunt public:
1741b8ab2f0SOliver Hunt   virtual ~TestMonomorphic();
1751b8ab2f0SOliver Hunt };
1761b8ab2f0SOliver Hunt 
1771b8ab2f0SOliver Hunt struct TestMonomorphicSubclass : TestMonomorphic<int> {
1781b8ab2f0SOliver Hunt };
1791b8ab2f0SOliver Hunt template <typename T> struct generic_authenticated TestMonomorphicSubclass2 : TestMonomorphic<T> {
1801b8ab2f0SOliver Hunt   // expected-error@-1 {{cannot set vtable pointer authentication on 'TestMonomorphicSubclass2<int>' which is a subclass of polymorphic type 'TestMonomorphic<int>'}}
1811b8ab2f0SOliver Hunt   // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphicSubclass2<double>'}}
1821b8ab2f0SOliver Hunt   // expected-note@-3 {{in instantiation of template class 'basic::TestMonomorphic<double>' requested here}}
1831b8ab2f0SOliver Hunt };
1841b8ab2f0SOliver Hunt 
1851b8ab2f0SOliver Hunt TestMonomorphicSubclass tms_1;
1861b8ab2f0SOliver Hunt TestMonomorphicSubclass2<int> tms2_1;
1871b8ab2f0SOliver Hunt // expected-note@-1 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<int>' requested here}}
1881b8ab2f0SOliver Hunt TestMonomorphicSubclass2<double> tms2_2;
1891b8ab2f0SOliver Hunt // expected-note@-1 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<double>' requested here}}
1901b8ab2f0SOliver Hunt // expected-note@-2 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<double>' requested here}}
1911b8ab2f0SOliver Hunt 
1921b8ab2f0SOliver Hunt template <typename T>
1931b8ab2f0SOliver Hunt class generic_authenticated dependent_type {
1941b8ab2f0SOliver Hunt   // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'dependent_type'}}
1951b8ab2f0SOliver Hunt   static constexpr unsigned small_object_size = 1;
1961b8ab2f0SOliver Hunt   char _model[small_object_size];
1971b8ab2f0SOliver Hunt };
1981b8ab2f0SOliver Hunt 
1991b8ab2f0SOliver Hunt template <typename... T>
2001b8ab2f0SOliver Hunt class generic_authenticated dependent_type2 : public T... {
2011b8ab2f0SOliver Hunt   // expected-error@-1 {{cannot set vtable pointer authentication on 'dependent_type2<basic::Foo>' which is a subclass of polymorphic type 'Foo'}}
2021b8ab2f0SOliver Hunt   static constexpr unsigned small_object_size = 1;
2031b8ab2f0SOliver Hunt   char _model[small_object_size];
2041b8ab2f0SOliver Hunt };
2051b8ab2f0SOliver Hunt 
2061b8ab2f0SOliver Hunt struct Foo {
2071b8ab2f0SOliver Hunt   virtual ~Foo();
2081b8ab2f0SOliver Hunt };
2091b8ab2f0SOliver Hunt 
2101b8ab2f0SOliver Hunt dependent_type2<Foo> thing;
2111b8ab2f0SOliver Hunt // expected-note@-1 {{in instantiation of template class 'basic::dependent_type2<basic::Foo>' requested here}}
2121b8ab2f0SOliver Hunt 
2131b8ab2f0SOliver Hunt template <class>
2141b8ab2f0SOliver Hunt class task;
2151b8ab2f0SOliver Hunt template <unsigned align> struct alignedthing {
2161b8ab2f0SOliver Hunt   char buffer[align];
2171b8ab2f0SOliver Hunt };
2181b8ab2f0SOliver Hunt 
2191b8ab2f0SOliver Hunt template <class R, class... Args>
2201b8ab2f0SOliver Hunt class generic_authenticated task<R(Args...)> {
2211b8ab2f0SOliver Hunt   // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'task<R (Args...)>'}}
2221b8ab2f0SOliver Hunt   static constexpr __SIZE_TYPE__ small_object_size = 256;
2231b8ab2f0SOliver Hunt   alignedthing<small_object_size> _model;
2241b8ab2f0SOliver Hunt };
2251b8ab2f0SOliver Hunt 
2261b8ab2f0SOliver Hunt } // namespace basic
227