xref: /llvm-project/clang/test/SemaCXX/vtable_pointer_authentication_attribute.cpp (revision a1d77caaabbb5279b734c061dab36b2138ec476d)
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