108a4a8c3SGeorge Burgess IV // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 208a4a8c3SGeorge Burgess IV 308a4a8c3SGeorge Burgess IV namespace simple { 408a4a8c3SGeorge Burgess IV int Foo(void *const p __attribute__((pass_object_size(0)))); 508a4a8c3SGeorge Burgess IV 608a4a8c3SGeorge Burgess IV int OvlFoo(void *const p __attribute__((pass_object_size(0)))); 708a4a8c3SGeorge Burgess IV int OvlFoo(void *const p, int); 808a4a8c3SGeorge Burgess IV 908a4a8c3SGeorge Burgess IV struct Statics { 1008a4a8c3SGeorge Burgess IV static int Foo(void *const p __attribute__((pass_object_size(0)))); 1108a4a8c3SGeorge Burgess IV static int OvlFoo(void *const p __attribute__((pass_object_size(0)))); 1208a4a8c3SGeorge Burgess IV 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}} 1308a4a8c3SGeorge Burgess IV static int OvlFoo(double *p); 1408a4a8c3SGeorge Burgess IV }; 1508a4a8c3SGeorge Burgess IV 1608a4a8c3SGeorge Burgess IV struct Members { 1708a4a8c3SGeorge Burgess IV int Foo(void *const p __attribute__((pass_object_size(0)))); 1808a4a8c3SGeorge Burgess IV int OvlFoo(void *const p __attribute__((pass_object_size(0)))); 1908a4a8c3SGeorge Burgess IV int OvlFoo(void *const p, int); 2008a4a8c3SGeorge Burgess IV }; 2108a4a8c3SGeorge Burgess IV Decls()2208a4a8c3SGeorge Burgess IVvoid Decls() { 2308a4a8c3SGeorge Burgess IV int (*A)(void *) = &Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 2408a4a8c3SGeorge Burgess IV int (*B)(void *) = Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 2508a4a8c3SGeorge Burgess IV 2608a4a8c3SGeorge Burgess IV 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)}} 2708a4a8c3SGeorge Burgess IV 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)}} 2808a4a8c3SGeorge Burgess IV 2908a4a8c3SGeorge Burgess IV int (*E)(void *) = &Statics::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 3008a4a8c3SGeorge Burgess IV 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 *')}} 3108a4a8c3SGeorge Burgess IV 3208a4a8c3SGeorge Burgess IV int (*G)(void *) = &Members::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 3308a4a8c3SGeorge Burgess IV 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)}} 3408a4a8c3SGeorge Burgess IV } 3508a4a8c3SGeorge Burgess IV Assigns()3608a4a8c3SGeorge Burgess IVvoid Assigns() { 3708a4a8c3SGeorge Burgess IV int (*A)(void *); 3808a4a8c3SGeorge Burgess IV A = &Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 3908a4a8c3SGeorge Burgess IV A = Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 4008a4a8c3SGeorge Burgess IV 4108a4a8c3SGeorge Burgess IV 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)}} 4208a4a8c3SGeorge Burgess IV 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)}} 4308a4a8c3SGeorge Burgess IV 4408a4a8c3SGeorge Burgess IV A = &Statics::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 4508a4a8c3SGeorge Burgess IV 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 *')}} 4608a4a8c3SGeorge Burgess IV 4708a4a8c3SGeorge Burgess IV int (Members::*M)(void *); 4808a4a8c3SGeorge Burgess IV M = &Members::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} 495e8701c3SGeorge Burgess IV 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)}} 5008a4a8c3SGeorge Burgess IV } 5108a4a8c3SGeorge Burgess IV 5208a4a8c3SGeorge Burgess IV } // namespace simple 5308a4a8c3SGeorge Burgess IV 5408a4a8c3SGeorge Burgess IV namespace templates { 5508a4a8c3SGeorge Burgess IV template <typename T> Foo(void * const)5608a4a8c3SGeorge Burgess IVint Foo(void *const __attribute__((pass_object_size(0)))) { 5708a4a8c3SGeorge Burgess IV return 0; 5808a4a8c3SGeorge Burgess IV } 5908a4a8c3SGeorge Burgess IV 6008a4a8c3SGeorge Burgess IV template <typename T> struct Bar { 6108a4a8c3SGeorge Burgess IV template <typename U> Footemplates::Bar6208a4a8c3SGeorge Burgess IV int Foo(void *const __attribute__((pass_object_size(0)))) { 6308a4a8c3SGeorge Burgess IV return 0; 6408a4a8c3SGeorge Burgess IV } 6508a4a8c3SGeorge Burgess IV }; 6608a4a8c3SGeorge Burgess IV Decls()6708a4a8c3SGeorge Burgess IVvoid Decls() { 6808a4a8c3SGeorge Burgess IV 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}} 695e8701c3SGeorge Burgess IV 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}} 7008a4a8c3SGeorge Burgess IV } 7108a4a8c3SGeorge Burgess IV Assigns()7208a4a8c3SGeorge Burgess IVvoid Assigns() { 7308a4a8c3SGeorge Burgess IV int (*A)(void *); 7408a4a8c3SGeorge Burgess IV 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}} 755e8701c3SGeorge Burgess IV 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}} 7608a4a8c3SGeorge Burgess IV } 7708a4a8c3SGeorge Burgess IV } // namespace templates 7808a4a8c3SGeorge Burgess IV 7908a4a8c3SGeorge Burgess IV namespace virt { 8008a4a8c3SGeorge Burgess IV struct Foo { 8108a4a8c3SGeorge Burgess IV virtual void DoIt(void *const p __attribute__((pass_object_size(0)))); 8208a4a8c3SGeorge Burgess IV }; 8308a4a8c3SGeorge Burgess IV 8408a4a8c3SGeorge Burgess IV struct Bar : public Foo { 8508a4a8c3SGeorge Burgess IV void DoIt(void *const p __attribute__((pass_object_size(0)))) override; // OK 8608a4a8c3SGeorge Burgess IV }; 8708a4a8c3SGeorge Burgess IV 8808a4a8c3SGeorge Burgess IV struct Baz : public Foo { 8908a4a8c3SGeorge Burgess IV 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}} 9008a4a8c3SGeorge Burgess IV }; 9108a4a8c3SGeorge Burgess IV } 9208a4a8c3SGeorge Burgess IV 9308a4a8c3SGeorge Burgess IV namespace why { 9408a4a8c3SGeorge Burgess IV void TakeFn(void (*)(int, void *)); 9508a4a8c3SGeorge Burgess IV void ObjSize(int, void *const __attribute__((pass_object_size(0)))); 9608a4a8c3SGeorge Burgess IV Check()9708a4a8c3SGeorge Burgess IVvoid Check() { 9808a4a8c3SGeorge Burgess IV TakeFn(ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 9908a4a8c3SGeorge Burgess IV TakeFn(&ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 10008a4a8c3SGeorge Burgess IV TakeFn(*ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 10108a4a8c3SGeorge Burgess IV TakeFn(*****ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 10208a4a8c3SGeorge Burgess IV TakeFn(*****&ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 10308a4a8c3SGeorge Burgess IV 10408a4a8c3SGeorge Burgess IV void (*P)(int, void *) = ****ObjSize; //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 10508a4a8c3SGeorge Burgess IV P = ****ObjSize; //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 10608a4a8c3SGeorge Burgess IV 10708a4a8c3SGeorge Burgess IV TakeFn((ObjSize)); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 10808a4a8c3SGeorge Burgess IV TakeFn((void*)ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 10908a4a8c3SGeorge Burgess IV TakeFn((decltype(P))((void*)ObjSize)); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} 11008a4a8c3SGeorge Burgess IV } 11108a4a8c3SGeorge Burgess IV } 11208a4a8c3SGeorge Burgess IV 11308a4a8c3SGeorge Burgess IV namespace constexpr_support { getObjSizeType()11408a4a8c3SGeorge Burgess IVconstexpr int getObjSizeType() { return 0; } 11508a4a8c3SGeorge Burgess IV void Foo(void *p __attribute__((pass_object_size(getObjSizeType())))); 11608a4a8c3SGeorge Burgess IV } 11708a4a8c3SGeorge Burgess IV 11808a4a8c3SGeorge Burgess IV namespace lambdas { Bar()11908a4a8c3SGeorge Burgess IVvoid Bar() { 12008a4a8c3SGeorge Burgess IV (void)+[](void *const p __attribute__((pass_object_size(0)))) {}; //expected-error-re{{invalid argument type '(lambda at {{.*}})' to unary expression}} 12108a4a8c3SGeorge Burgess IV } 12208a4a8c3SGeorge Burgess IV } 123*7204ed97SGeorge Burgess IV 124*7204ed97SGeorge Burgess IV namespace ovlbug { 125*7204ed97SGeorge Burgess IV // Directly calling an address-of function expression (e.g. in (&foo)(args...)) 126*7204ed97SGeorge Burgess IV // doesn't go through regular address-of-overload logic. This caused the above 127*7204ed97SGeorge Burgess IV // code to generate an ICE. 128*7204ed97SGeorge Burgess IV void DirectAddrOf(void *__attribute__((pass_object_size(0)))); 129*7204ed97SGeorge Burgess IV void DirectAddrOfOvl(void *__attribute__((pass_object_size(0)))); 130*7204ed97SGeorge Burgess IV void DirectAddrOfOvl(int *); 131*7204ed97SGeorge Burgess IV Test()132*7204ed97SGeorge Burgess IVvoid Test() { 133*7204ed97SGeorge Burgess IV (&DirectAddrOf)(nullptr); //expected-error{{cannot take address of function 'DirectAddrOf' because parameter 1 has pass_object_size attribute}} 134*7204ed97SGeorge Burgess IV (&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*7204ed97SGeorge Burgess IV } 136*7204ed97SGeorge Burgess IV } 137