1 // RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios -verify -fptrauth-calls -std=c++2a %s 2 // RUN: %clang_cc1 -fsyntax-only -triple aarch64-linux-gnu -verify -fptrauth-calls -std=c++2a %s 3 4 namespace basic { 5 6 #define authenticated(a, b, c...) [[clang::ptrauth_vtable_pointer(a, b, c)]] 7 8 // Basic sanity tests 9 #define TEST_AUTH(name, auth...) \ 10 struct [[clang::ptrauth_vtable_pointer(auth)]] name { \ 11 virtual ~name() {} \ 12 } 13 14 TEST_AUTH(NoParams); 15 // expected-error@-1{{'ptrauth_vtable_pointer' attribute takes at least 3 arguments}} 16 TEST_AUTH(NoAuth, no_authentication, default_address_discrimination, default_extra_discrimination); 17 TEST_AUTH(InvalidKey, wat, default_address_discrimination, default_extra_discrimination); 18 // expected-error@-1{{invalid authentication key 'wat'}} 19 TEST_AUTH(InvalidAddressDiscrimination, no_authentication, wat, default_extra_discrimination); 20 // expected-error@-1{{invalid address discrimination mode 'wat'}} 21 TEST_AUTH(InvalidExtraDiscrimination, no_authentication, default_address_discrimination, wat); 22 // expected-error@-1{{invalid extra discrimination selection 'wat'}} 23 TEST_AUTH(InvalidNoCustomDiscrimination, no_authentication, default_address_discrimination, custom_discrimination); 24 // expected-error@-1{{missing custom discrimination}} 25 TEST_AUTH(InvalidCustomDiscrimination, no_authentication, default_address_discrimination, custom_discrimination, wat); 26 // expected-error@-1{{invalid custom discrimination}} 27 TEST_AUTH(Default, default_key, default_address_discrimination, default_extra_discrimination); 28 TEST_AUTH(InvalidDefaultExtra, default_key, default_address_discrimination, default_extra_discrimination, 1); 29 // expected-error@-1{{'ptrauth_vtable_pointer' attribute takes no more than 3 arguments}} 30 TEST_AUTH(ProcessDependentKey, process_dependent, default_address_discrimination, default_extra_discrimination); 31 TEST_AUTH(ProcessIndependentKey, process_independent, default_address_discrimination, default_extra_discrimination); 32 TEST_AUTH(DefaultAddressDiscrimination, process_independent, default_address_discrimination, default_extra_discrimination); 33 TEST_AUTH(NoAddressDiscrimination, process_independent, no_address_discrimination, default_extra_discrimination); 34 TEST_AUTH(AddressDiscrimination, process_independent, address_discrimination, default_extra_discrimination); 35 TEST_AUTH(DefaultExtraDiscrimination, process_independent, default_address_discrimination, default_extra_discrimination); 36 TEST_AUTH(NoExtraDiscrimination, process_independent, default_address_discrimination, no_extra_discrimination); 37 TEST_AUTH(TypeExtraDiscrimination, process_independent, default_address_discrimination, type_discrimination); 38 TEST_AUTH(InvalidCustomExtraDiscrimination, process_independent, default_address_discrimination, custom_discrimination); 39 // expected-error@-1{{missing custom discrimination}} 40 TEST_AUTH(ValidCustomExtraDiscrimination, process_independent, default_address_discrimination, custom_discrimination, 1); 41 42 // Basic valid authentication configuration 43 #define generic_authenticated \ 44 authenticated(process_independent, address_discrimination, type_discrimination) 45 46 struct generic_authenticated ForwardDecl; 47 48 struct generic_authenticated generic_authenticated InvalidDuplicateAttribute { 49 // expected-error@-1{{multiple vtable pointer authentication policies on 'InvalidDuplicateAttribute'}} 50 virtual ~InvalidDuplicateAttribute(){}; 51 }; 52 struct generic_authenticated ValidPolymorphic { 53 virtual ~ValidPolymorphic(){}; 54 }; 55 struct generic_authenticated InvalidMonomorphic { // expected-error{{cannot set vtable pointer authentication on monomorphic type 'InvalidMonomorphic'}} 56 }; 57 struct ValidMonomorphic { 58 }; 59 60 struct ValidSubclass : ValidPolymorphic {}; 61 struct generic_authenticated InvalidSubclass : ValidPolymorphic {}; // expected-error{{cannot set vtable pointer authentication on 'InvalidSubclass' which is a subclass of polymorphic type 'ValidPolymorphic'}} 62 63 // Awful template time 64 template <typename T> 65 struct generic_authenticated ExplicitlyAuthedMonomorphicTemplateClass : T {}; 66 // expected-error@-1{{cannot set vtable pointer authentication on 'ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidPolymorphic>' which is a subclass of polymorphic type 'ValidPolymorphic'}} 67 // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidMonomorphic>'}} 68 template <typename T> 69 struct generic_authenticated ExplicitlyAuthedPolymorphicTemplateClass : T { // expected-error{{cannot set vtable pointer authentication on 'ExplicitlyAuthedPolymorphicTemplateClass<basic::ValidPolymorphic>' which is a subclass of polymorphic type 'ValidPolymorphic'}} 70 virtual ~ExplicitlyAuthedPolymorphicTemplateClass(){}; 71 }; 72 template <typename T> 73 struct UnauthedMonomorphicTemplateClass : T {}; 74 template <typename T> 75 struct UnauthedPolymorphicTemplateClass : T { 76 virtual ~UnauthedPolymorphicTemplateClass(){}; 77 }; 78 79 ExplicitlyAuthedMonomorphicTemplateClass<ValidPolymorphic> test1; 80 // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidPolymorphic>' requested here}} 81 ExplicitlyAuthedMonomorphicTemplateClass<ValidMonomorphic> test2; 82 // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidMonomorphic>' requested here}} 83 ExplicitlyAuthedPolymorphicTemplateClass<ValidPolymorphic> test3; 84 // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedPolymorphicTemplateClass<basic::ValidPolymorphic>' requested here}} 85 ExplicitlyAuthedPolymorphicTemplateClass<ValidMonomorphic> test4; 86 87 UnauthedMonomorphicTemplateClass<ValidPolymorphic> test5; 88 UnauthedMonomorphicTemplateClass<ValidMonomorphic> test6; 89 UnauthedPolymorphicTemplateClass<ValidPolymorphic> test7; 90 UnauthedPolymorphicTemplateClass<ValidMonomorphic> test8; 91 92 // Just use a different policy from the generic macro to verify we won't complain 93 // about the insanity 94 struct authenticated(process_independent, no_address_discrimination, type_discrimination) SecondAuthenticatedPolymorphic { 95 virtual ~SecondAuthenticatedPolymorphic(){}; 96 }; 97 struct UnauthenticatedPolymorphic { 98 virtual ~UnauthenticatedPolymorphic(){}; 99 }; 100 101 struct MultipleParents1 : ValidPolymorphic, SecondAuthenticatedPolymorphic, UnauthenticatedPolymorphic {}; 102 struct MultipleParents2 : UnauthenticatedPolymorphic, ValidPolymorphic, SecondAuthenticatedPolymorphic {}; 103 struct generic_authenticated InvalidMultipleParents : UnauthenticatedPolymorphic, ValidPolymorphic, SecondAuthenticatedPolymorphic {}; 104 // expected-error@-1{{cannot set vtable pointer authentication on 'InvalidMultipleParents' which is a subclass of polymorphic type 'UnauthenticatedPolymorphic'}} 105 106 template <typename T> 107 struct generic_authenticated ExplicitlyAuthedPolymorphicTemplateClassNoBase { 108 virtual ~ExplicitlyAuthedPolymorphicTemplateClassNoBase(); 109 }; 110 111 ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> v; 112 113 struct ValidSubclassOfTemplate : ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> { 114 }; 115 116 struct generic_authenticated InvalidSubclassOfTemplate : ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> { 117 // expected-error@-1{{cannot set vtable pointer authentication on 'InvalidSubclassOfTemplate' which is a subclass of polymorphic type 'ExplicitlyAuthedPolymorphicTemplateClassNoBase<int>'}} 118 }; 119 120 template <typename T> 121 struct generic_authenticated ExplicitlyAuthedMonomorphicTemplateClassNoBase { 122 // expected-error@-1{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClassNoBase'}} 123 // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClassNoBase<int>'}} 124 }; 125 126 ExplicitlyAuthedMonomorphicTemplateClassNoBase<int> X; 127 // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClassNoBase<int>' requested here}} 128 129 template <typename T> 130 struct generic_authenticated ExplicitlyAuthedTemplateClassValidBase : ValidMonomorphic { 131 // expected-error@-1{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedTemplateClassValidBase'}} 132 // expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedTemplateClassValidBase<int>'}} 133 }; 134 135 ExplicitlyAuthedTemplateClassValidBase<int> Y; 136 // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedTemplateClassValidBase<int>' requested here}} 137 138 template <typename T> 139 struct generic_authenticated ExplicitlyAuthedTemplateClassInvalidBase : ValidPolymorphic { 140 // expected-error@-1{{cannot set vtable pointer authentication on 'ExplicitlyAuthedTemplateClassInvalidBase' which is a subclass of polymorphic type 'ValidPolymorphic'}} 141 // expected-error@-2{{cannot set vtable pointer authentication on 'ExplicitlyAuthedTemplateClassInvalidBase<int>' which is a subclass of polymorphic type 'ValidPolymorphic'}} 142 }; 143 144 ExplicitlyAuthedTemplateClassInvalidBase<int> Z; 145 // expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedTemplateClassInvalidBase<int>' requested here}} 146 147 template <class test1, class test2> 148 class generic_authenticated TestPolymorphicTemplateSpecialization; 149 150 template <> 151 class TestPolymorphicTemplateSpecialization<double, float> { 152 MissingDecl *zl; 153 // expected-error@-1 {{unknown type name 'MissingDecl'}} 154 public: 155 virtual ~TestPolymorphicTemplateSpecialization(); 156 }; 157 template <class test1> 158 class generic_authenticated TestPolymorphicTemplateSpecialization<test1, double> 159 // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'TestPolymorphicTemplateSpecialization<test1, double>'}} 160 // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestPolymorphicTemplateSpecialization<double, double>'}} 161 { 162 }; 163 164 TestPolymorphicTemplateSpecialization<double, float> b; 165 TestPolymorphicTemplateSpecialization<double, double> b2; 166 // expected-note@-1 {{in instantiation of template class 'basic::TestPolymorphicTemplateSpecialization<double, double>' requested here}} 167 168 template <typename A> class generic_authenticated TestMonomorphic {}; 169 // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphic'}} 170 // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphic<double>'}} 171 172 template <> class generic_authenticated TestMonomorphic<int> { 173 public: 174 virtual ~TestMonomorphic(); 175 }; 176 177 struct TestMonomorphicSubclass : TestMonomorphic<int> { 178 }; 179 template <typename T> struct generic_authenticated TestMonomorphicSubclass2 : TestMonomorphic<T> { 180 // expected-error@-1 {{cannot set vtable pointer authentication on 'TestMonomorphicSubclass2<int>' which is a subclass of polymorphic type 'TestMonomorphic<int>'}} 181 // expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphicSubclass2<double>'}} 182 // expected-note@-3 {{in instantiation of template class 'basic::TestMonomorphic<double>' requested here}} 183 }; 184 185 TestMonomorphicSubclass tms_1; 186 TestMonomorphicSubclass2<int> tms2_1; 187 // expected-note@-1 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<int>' requested here}} 188 TestMonomorphicSubclass2<double> tms2_2; 189 // expected-note@-1 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<double>' requested here}} 190 // expected-note@-2 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<double>' requested here}} 191 192 template <typename T> 193 class generic_authenticated dependent_type { 194 // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'dependent_type'}} 195 static constexpr unsigned small_object_size = 1; 196 char _model[small_object_size]; 197 }; 198 199 template <typename... T> 200 class generic_authenticated dependent_type2 : public T... { 201 // expected-error@-1 {{cannot set vtable pointer authentication on 'dependent_type2<basic::Foo>' which is a subclass of polymorphic type 'Foo'}} 202 static constexpr unsigned small_object_size = 1; 203 char _model[small_object_size]; 204 }; 205 206 struct Foo { 207 virtual ~Foo(); 208 }; 209 210 dependent_type2<Foo> thing; 211 // expected-note@-1 {{in instantiation of template class 'basic::dependent_type2<basic::Foo>' requested here}} 212 213 template <class> 214 class task; 215 template <unsigned align> struct alignedthing { 216 char buffer[align]; 217 }; 218 219 template <class R, class... Args> 220 class generic_authenticated task<R(Args...)> { 221 // expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'task<R (Args...)>'}} 222 static constexpr __SIZE_TYPE__ small_object_size = 256; 223 alignedthing<small_object_size> _model; 224 }; 225 226 } // namespace basic 227