1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++17 -fsyntax-only -verify -fptrauth-intrinsics -fptrauth-calls %s
struct Incomplete0; // expected-note 3 {{forward declaration of 'Incomplete0'}}
template <class T>
struct Incomplete1; // expected-note {{template is declared here}}
struct Complete0 {
};
template <class T>
struct Complete1 {
};
struct S {
virtual int foo();
virtual Incomplete0 virtual0(); // expected-note 2 {{'Incomplete0' is incomplete}}
virtual void virtual1(Incomplete1<int>); // expected-note {{'Incomplete1<int>' is incomplete}}
virtual Complete0 virtual2();
virtual Complete1<int> virtual3();
Incomplete0 nonvirtual0();
template <class T>
void m0() {
(void)&S::virtual0; // expected-error {{incomplete type 'Incomplete0'}} expected-note {{cannot take an address of a virtual}}
}
};
template <bool T>
struct S2 {
virtual Incomplete0 virtual0() noexcept(T); // expected-note {{'Incomplete0' is incomplete}}
void m0() {
(void)&S2<T>::virtual0;
}
void m1() {
(void)&S2<T>::virtual0; // expected-error {{incomplete type 'Incomplete0'}} expected-note {{cannot take an address of a virtual}}
}
};
template <class T>
constexpr unsigned dependentOperandDisc() {
return __builtin_ptrauth_type_discriminator(T);
}
void test_builtin_ptrauth_type_discriminator(unsigned s) {
typedef int (S::*MemFnTy)();
MemFnTy memFnPtr;
int (S::*memFnPtr2)();
constexpr unsigned d = __builtin_ptrauth_type_discriminator(MemFnTy);
static_assert(d == 60844);
static_assert(__builtin_ptrauth_type_discriminator(int (S::*)()) == d);
static_assert(__builtin_ptrauth_type_discriminator(decltype(memFnPtr)) == d);
static_assert(__builtin_ptrauth_type_discriminator(decltype(memFnPtr2)) == d);
static_assert(__builtin_ptrauth_type_discriminator(decltype(&S::foo)) == d);
static_assert(dependentOperandDisc<decltype(&S::foo)>() == d);
static_assert(__builtin_ptrauth_type_discriminator(void (S::*)(int)) == 39121);
static_assert(__builtin_ptrauth_type_discriminator(void (S::*)(float)) == 52453);
static_assert(__builtin_ptrauth_type_discriminator(int *) == 42396);
int t;
int vmarray[s];
(void)__builtin_ptrauth_type_discriminator(t); // expected-error {{unknown type name 't'}}
(void)__builtin_ptrauth_type_discriminator(&t); // expected-error {{expected a type}}
(void)__builtin_ptrauth_type_discriminator(decltype(vmarray)); // expected-error {{cannot pass variably-modified type 'decltype(vmarray)'}}
}
void test_incomplete_virtual_member_function_return_arg_type() {
(void)&S::virtual0; // expected-error {{incomplete type 'Incomplete0}} expected-note {{cannot take an address of a virtual member function}}
(void)&S::virtual1; // expected-error {{implicit instantiation of undefined template 'Incomplete1<int>'}} expected-note {{cannot take an address of a virtual member function}}
(void)&S::virtual2;
(void)&S::virtual3;
(void)&S::nonvirtual0;
int s = sizeof(&S::virtual0);
S2<true>().m1(); // expected-note {{in instantiation of}}
}
|