1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 2*67e74705SXin Li 3*67e74705SXin Li namespace simple { 4*67e74705SXin Li int Foo(void *const p __attribute__((pass_object_size(0)))); 5*67e74705SXin Li 6*67e74705SXin Li int OvlFoo(void *const p __attribute__((pass_object_size(0)))); 7*67e74705SXin Li int OvlFoo(void *const p, int); 8*67e74705SXin Li 9*67e74705SXin Li struct Statics { 10*67e74705SXin Li static int Foo(void *const p __attribute__((pass_object_size(0)))); 11*67e74705SXin Li static int OvlFoo(void *const p __attribute__((pass_object_size(0)))); 12*67e74705SXin Li static int OvlFoo(void *const p __attribute__((pass_object_size(1)))); // expected-error{{conflicting pass_object_size attributes on parameters}} expected-note@-1{{previous declaration is here}} 13*67e74705SXin Li static int OvlFoo(double *p); 14*67e74705SXin Li }; 15*67e74705SXin Li 16*67e74705SXin Li struct Members { 17*67e74705SXin Li int Foo(void *const p __attribute__((pass_object_size(0)))); 18*67e74705SXin Li int OvlFoo(void *const p __attribute__((pass_object_size(0)))); 19*67e74705SXin Li int OvlFoo(void *const p, int); 20*67e74705SXin Li }; 21*67e74705SXin Li Decls()22*67e74705SXin Livoid Decls() { 23*67e74705SXin Li int (*A)(void *) = &Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 24*67e74705SXin Li int (*B)(void *) = Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 25*67e74705SXin Li 26*67e74705SXin Li int (*C)(void *) = &OvlFoo; //expected-error{{address of overloaded function 'OvlFoo' does not match required type 'int (void *)'}} expected-note@6{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@7{{candidate function has different number of parameters (expected 1 but has 2)}} 27*67e74705SXin Li int (*D)(void *) = OvlFoo; //expected-error{{address of overloaded function 'OvlFoo' does not match required type 'int (void *)'}} expected-note@6{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@7{{candidate function has different number of parameters (expected 1 but has 2)}} 28*67e74705SXin Li 29*67e74705SXin Li int (*E)(void *) = &Statics::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 30*67e74705SXin Li int (*F)(void *) = &Statics::OvlFoo; //expected-error{{address of overloaded function 'OvlFoo' does not match required type 'int (void *)'}} expected-note@11{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@13{{candidate function has type mismatch at 1st parameter (expected 'void *' but has 'double *')}} 31*67e74705SXin Li 32*67e74705SXin Li int (*G)(void *) = &Members::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 33*67e74705SXin Li int (*H)(void *) = &Members::OvlFoo; //expected-error{{address of overloaded function 'OvlFoo' does not match required type 'int (void *)'}} expected-note@18{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@19{{candidate function has different number of parameters (expected 1 but has 2)}} 34*67e74705SXin Li } 35*67e74705SXin Li Assigns()36*67e74705SXin Livoid Assigns() { 37*67e74705SXin Li int (*A)(void *); 38*67e74705SXin Li A = &Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 39*67e74705SXin Li A = Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 40*67e74705SXin Li 41*67e74705SXin Li A = &OvlFoo; //expected-error{{assigning to 'int (*)(void *)' from incompatible type '<overloaded function type>'}} expected-note@6{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@7{{candidate function has different number of parameters (expected 1 but has 2)}} 42*67e74705SXin Li A = OvlFoo; //expected-error{{assigning to 'int (*)(void *)' from incompatible type '<overloaded function type>'}} expected-note@6{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@7{{candidate function has different number of parameters (expected 1 but has 2)}} 43*67e74705SXin Li 44*67e74705SXin Li A = &Statics::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 45*67e74705SXin Li A = &Statics::OvlFoo; //expected-error{{assigning to 'int (*)(void *)' from incompatible type '<overloaded function type>'}} expected-note@11{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@13{{candidate function has type mismatch at 1st parameter (expected 'void *' but has 'double *')}} 46*67e74705SXin Li 47*67e74705SXin Li int (Members::*M)(void *); 48*67e74705SXin Li M = &Members::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 49*67e74705SXin Li M = &Members::OvlFoo; //expected-error-re{{assigning to '{{.*}}' from incompatible type '<overloaded function type>'}} expected-note@18{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@19{{candidate function has different number of parameters (expected 1 but has 2)}} 50*67e74705SXin Li } 51*67e74705SXin Li 52*67e74705SXin Li } // namespace simple 53*67e74705SXin Li 54*67e74705SXin Li namespace templates { 55*67e74705SXin Li template <typename T> Foo(void * const)56*67e74705SXin Liint Foo(void *const __attribute__((pass_object_size(0)))) { 57*67e74705SXin Li return 0; 58*67e74705SXin Li } 59*67e74705SXin Li 60*67e74705SXin Li template <typename T> struct Bar { 61*67e74705SXin Li template <typename U> Footemplates::Bar62*67e74705SXin Li int Foo(void *const __attribute__((pass_object_size(0)))) { 63*67e74705SXin Li return 0; 64*67e74705SXin Li } 65*67e74705SXin Li }; 66*67e74705SXin Li Decls()67*67e74705SXin Livoid Decls() { 68*67e74705SXin Li int (*A)(void *) = &Foo<void*>; //expected-error{{address of overloaded function 'Foo' does not match required type 'int (void *)'}} expected-note@56{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} 69*67e74705SXin Li int (Bar<int>::*B)(void *) = &Bar<int>::Foo<double>; //expected-error{{address of overloaded function 'Foo' does not match required type}} expected-note@62{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} 70*67e74705SXin Li } 71*67e74705SXin Li Assigns()72*67e74705SXin Livoid Assigns() { 73*67e74705SXin Li int (*A)(void *); 74*67e74705SXin Li A = &Foo<void*>; // expected-error{{assigning to 'int (*)(void *)' from incompatible type '<overloaded function type>'}} expected-note@56{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} 75*67e74705SXin Li int (Bar<int>::*B)(void *) = &Bar<int>::Foo<double>; //expected-error{{address of overloaded function 'Foo' does not match required type}} expected-note@62{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} 76*67e74705SXin Li } 77*67e74705SXin Li } // namespace templates 78*67e74705SXin Li 79*67e74705SXin Li namespace virt { 80*67e74705SXin Li struct Foo { 81*67e74705SXin Li virtual void DoIt(void *const p __attribute__((pass_object_size(0)))); 82*67e74705SXin Li }; 83*67e74705SXin Li 84*67e74705SXin Li struct Bar : public Foo { 85*67e74705SXin Li void DoIt(void *const p __attribute__((pass_object_size(0)))) override; // OK 86*67e74705SXin Li }; 87*67e74705SXin Li 88*67e74705SXin Li struct Baz : public Foo { 89*67e74705SXin Li void DoIt(void *const p) override; //expected-error{{non-virtual member function marked 'override' hides virtual member function}} expected-note@81{{hidden overloaded virtual function 'virt::Foo::DoIt' declared here}} 90*67e74705SXin Li }; 91*67e74705SXin Li } 92*67e74705SXin Li 93*67e74705SXin Li namespace why { 94*67e74705SXin Li void TakeFn(void (*)(int, void *)); 95*67e74705SXin Li void ObjSize(int, void *const __attribute__((pass_object_size(0)))); 96*67e74705SXin Li Check()97*67e74705SXin Livoid Check() { 98*67e74705SXin Li TakeFn(ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 99*67e74705SXin Li TakeFn(&ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 100*67e74705SXin Li TakeFn(*ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 101*67e74705SXin Li TakeFn(*****ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 102*67e74705SXin Li TakeFn(*****&ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 103*67e74705SXin Li 104*67e74705SXin Li void (*P)(int, void *) = ****ObjSize; //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 105*67e74705SXin Li P = ****ObjSize; //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 106*67e74705SXin Li 107*67e74705SXin Li TakeFn((ObjSize)); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 108*67e74705SXin Li TakeFn((void*)ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 109*67e74705SXin Li TakeFn((decltype(P))((void*)ObjSize)); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 110*67e74705SXin Li } 111*67e74705SXin Li } 112*67e74705SXin Li 113*67e74705SXin Li namespace constexpr_support { getObjSizeType()114*67e74705SXin Liconstexpr int getObjSizeType() { return 0; } 115*67e74705SXin Li void Foo(void *p __attribute__((pass_object_size(getObjSizeType())))); 116*67e74705SXin Li } 117*67e74705SXin Li 118*67e74705SXin Li namespace lambdas { Bar()119*67e74705SXin Livoid Bar() { 120*67e74705SXin Li (void)+[](void *const p __attribute__((pass_object_size(0)))) {}; //expected-error-re{{invalid argument type '(lambda at {{.*}})' to unary expression}} 121*67e74705SXin Li } 122*67e74705SXin Li } 123*67e74705SXin Li 124*67e74705SXin Li namespace ovlbug { 125*67e74705SXin Li // Directly calling an address-of function expression (e.g. in (&foo)(args...)) 126*67e74705SXin Li // doesn't go through regular address-of-overload logic. This caused the above 127*67e74705SXin Li // code to generate an ICE. 128*67e74705SXin Li void DirectAddrOf(void *__attribute__((pass_object_size(0)))); 129*67e74705SXin Li void DirectAddrOfOvl(void *__attribute__((pass_object_size(0)))); 130*67e74705SXin Li void DirectAddrOfOvl(int *); 131*67e74705SXin Li Test()132*67e74705SXin Livoid Test() { 133*67e74705SXin Li (&DirectAddrOf)(nullptr); //expected-error{{cannot take address of function 'DirectAddrOf' because parameter 1 has pass_object_size attribute}} 134*67e74705SXin Li (&DirectAddrOfOvl)((char*)nullptr); //expected-error{{no matching function}} expected-note@129{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@130{{candidate function not viable: no known conversion from 'char *' to 'int *' for 1st argument}} 135*67e74705SXin Li } 136*67e74705SXin Li } 137