// 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 <typename T>
struct generic_authenticated ExplicitlyAuthedMonomorphicTemplateClass : T {};
// expected-error@-1{{cannot set vtable pointer authentication on 'ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidPolymorphic>' which is a subclass of polymorphic type 'ValidPolymorphic'}}
// expected-error@-2{{cannot set vtable pointer authentication on monomorphic type 'ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidMonomorphic>'}}
template <typename T>
struct generic_authenticated ExplicitlyAuthedPolymorphicTemplateClass : T { // expected-error{{cannot set vtable pointer authentication on 'ExplicitlyAuthedPolymorphicTemplateClass<basic::ValidPolymorphic>' which is a subclass of polymorphic type 'ValidPolymorphic'}}
virtual ~ExplicitlyAuthedPolymorphicTemplateClass(){};
};
template <typename T>
struct UnauthedMonomorphicTemplateClass : T {};
template <typename T>
struct UnauthedPolymorphicTemplateClass : T {
virtual ~UnauthedPolymorphicTemplateClass(){};
};
ExplicitlyAuthedMonomorphicTemplateClass<ValidPolymorphic> test1;
// expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidPolymorphic>' requested here}}
ExplicitlyAuthedMonomorphicTemplateClass<ValidMonomorphic> test2;
// expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClass<basic::ValidMonomorphic>' requested here}}
ExplicitlyAuthedPolymorphicTemplateClass<ValidPolymorphic> test3;
// expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedPolymorphicTemplateClass<basic::ValidPolymorphic>' requested here}}
ExplicitlyAuthedPolymorphicTemplateClass<ValidMonomorphic> test4;
UnauthedMonomorphicTemplateClass<ValidPolymorphic> test5;
UnauthedMonomorphicTemplateClass<ValidMonomorphic> test6;
UnauthedPolymorphicTemplateClass<ValidPolymorphic> test7;
UnauthedPolymorphicTemplateClass<ValidMonomorphic> 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 <typename T>
struct generic_authenticated ExplicitlyAuthedPolymorphicTemplateClassNoBase {
virtual ~ExplicitlyAuthedPolymorphicTemplateClassNoBase();
};
ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> v;
struct ValidSubclassOfTemplate : ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> {
};
struct generic_authenticated InvalidSubclassOfTemplate : ExplicitlyAuthedPolymorphicTemplateClassNoBase<int> {
// expected-error@-1{{cannot set vtable pointer authentication on 'InvalidSubclassOfTemplate' which is a subclass of polymorphic type 'ExplicitlyAuthedPolymorphicTemplateClassNoBase<int>'}}
};
template <typename T>
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<int>'}}
};
ExplicitlyAuthedMonomorphicTemplateClassNoBase<int> X;
// expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedMonomorphicTemplateClassNoBase<int>' requested here}}
template <typename T>
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<int>'}}
};
ExplicitlyAuthedTemplateClassValidBase<int> Y;
// expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedTemplateClassValidBase<int>' requested here}}
template <typename T>
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<int>' which is a subclass of polymorphic type 'ValidPolymorphic'}}
};
ExplicitlyAuthedTemplateClassInvalidBase<int> Z;
// expected-note@-1{{in instantiation of template class 'basic::ExplicitlyAuthedTemplateClassInvalidBase<int>' requested here}}
template <class test1, class test2>
class generic_authenticated TestPolymorphicTemplateSpecialization;
template <>
class TestPolymorphicTemplateSpecialization<double, float> {
MissingDecl *zl;
// expected-error@-1 {{unknown type name 'MissingDecl'}}
public:
virtual ~TestPolymorphicTemplateSpecialization();
};
template <class test1>
class generic_authenticated TestPolymorphicTemplateSpecialization<test1, double>
// expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'TestPolymorphicTemplateSpecialization<test1, double>'}}
// expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestPolymorphicTemplateSpecialization<double, double>'}}
{
};
TestPolymorphicTemplateSpecialization<double, float> b;
TestPolymorphicTemplateSpecialization<double, double> b2;
// expected-note@-1 {{in instantiation of template class 'basic::TestPolymorphicTemplateSpecialization<double, double>' requested here}}
template <typename A> 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<double>'}}
template <> class generic_authenticated TestMonomorphic<int> {
public:
virtual ~TestMonomorphic();
};
struct TestMonomorphicSubclass : TestMonomorphic<int> {
};
template <typename T> struct generic_authenticated TestMonomorphicSubclass2 : TestMonomorphic<T> {
// expected-error@-1 {{cannot set vtable pointer authentication on 'TestMonomorphicSubclass2<int>' which is a subclass of polymorphic type 'TestMonomorphic<int>'}}
// expected-error@-2 {{cannot set vtable pointer authentication on monomorphic type 'TestMonomorphicSubclass2<double>'}}
// expected-note@-3 {{in instantiation of template class 'basic::TestMonomorphic<double>' requested here}}
};
TestMonomorphicSubclass tms_1;
TestMonomorphicSubclass2<int> tms2_1;
// expected-note@-1 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<int>' requested here}}
TestMonomorphicSubclass2<double> tms2_2;
// expected-note@-1 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<double>' requested here}}
// expected-note@-2 {{in instantiation of template class 'basic::TestMonomorphicSubclass2<double>' requested here}}
template <typename T>
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 <typename... T>
class generic_authenticated dependent_type2 : public T... {
// expected-error@-1 {{cannot set vtable pointer authentication on 'dependent_type2<basic::Foo>' 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<Foo> thing;
// expected-note@-1 {{in instantiation of template class 'basic::dependent_type2<basic::Foo>' requested here}}
template <class>
class task;
template <unsigned align> struct alignedthing {
char buffer[align];
};
template <class R, class... Args>
class generic_authenticated task<R(Args...)> {
// expected-error@-1 {{cannot set vtable pointer authentication on monomorphic type 'task<R (Args...)>'}}
static constexpr __SIZE_TYPE__ small_object_size = 256;
alignedthing<small_object_size> _model;
};
} // namespace basic