Author: gbiv Date: Thu Dec 3 13:19:09 2015 New Revision: 254632 URL: http://llvm.org/viewvc/llvm-project?rev=254632&view=rev Log: Add tests for pass_object_size.
These additions were meant to go in as a part of r254554; while it's certainly nice to have new functionality, it's nicer if we have tests to go with it. :) Added: cfe/trunk/test/CodeGen/pass-object-size.c cfe/trunk/test/CodeGenCXX/pass-object-size.cpp cfe/trunk/test/Sema/pass-object-size.c cfe/trunk/test/SemaCXX/pass-object-size.cpp Added: cfe/trunk/test/CodeGen/pass-object-size.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pass-object-size.c?rev=254632&view=auto ============================================================================== --- cfe/trunk/test/CodeGen/pass-object-size.c (added) +++ cfe/trunk/test/CodeGen/pass-object-size.c Thu Dec 3 13:19:09 2015 @@ -0,0 +1,353 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 | FileCheck %s + +typedef unsigned long size_t; + +struct Foo { + int t[10]; +}; + +#define PS(N) __attribute__((pass_object_size(N))) + +int gi = 0; + +// CHECK-LABEL: define i32 @ObjectSize0(i8* %{{.*}}, i64) +int ObjectSize0(void *const p PS(0)) { + // CHECK-NOT: @llvm.objectsize + return __builtin_object_size(p, 0); +} + +// CHECK-LABEL: define i32 @ObjectSize1(i8* %{{.*}}, i64) +int ObjectSize1(void *const p PS(1)) { + // CHECK-NOT: @llvm.objectsize + return __builtin_object_size(p, 1); +} + +// CHECK-LABEL: define i32 @ObjectSize2(i8* %{{.*}}, i64) +int ObjectSize2(void *const p PS(2)) { + // CHECK-NOT: @llvm.objectsize + return __builtin_object_size(p, 2); +} + +// CHECK-LABEL: define i32 @ObjectSize3(i8* %{{.*}}, i64) +int ObjectSize3(void *const p PS(3)) { + // CHECK-NOT: @llvm.objectsize + return __builtin_object_size(p, 3); +} + +// CHECK-LABEL: define void @test1 +void test1() { + struct Foo t[10]; + + // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 360) + gi = ObjectSize0(&t[1]); + // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 360) + gi = ObjectSize1(&t[1]); + // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 360) + gi = ObjectSize2(&t[1]); + // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 360) + gi = ObjectSize3(&t[1]); + + // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 356) + gi = ObjectSize0(&t[1].t[1]); + // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 36) + gi = ObjectSize1(&t[1].t[1]); + // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 356) + gi = ObjectSize2(&t[1].t[1]); + // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36) + gi = ObjectSize3(&t[1].t[1]); +} + +// CHECK-LABEL: define void @test2 +void test2(struct Foo *t) { + // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 36) + gi = ObjectSize1(&t->t[1]); + // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36) + gi = ObjectSize3(&t->t[1]); +} + +// CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize0Pv +int NoViableOverloadObjectSize0(void *const p) __attribute__((overloadable)) { + // CHECK: @llvm.objectsize + return __builtin_object_size(p, 0); +} + +// CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize1Pv +int NoViableOverloadObjectSize1(void *const p) __attribute__((overloadable)) { + // CHECK: @llvm.objectsize + return __builtin_object_size(p, 1); +} + +// CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize2Pv +int NoViableOverloadObjectSize2(void *const p) __attribute__((overloadable)) { + // CHECK: @llvm.objectsize + return __builtin_object_size(p, 2); +} + +// CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize3Pv +int NoViableOverloadObjectSize3(void *const p) __attribute__((overloadable)) { + // CHECK-NOT: @llvm.objectsize + return __builtin_object_size(p, 3); +} + +// CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize0Pv +// CHECK-NOT: @llvm.objectsize +int NoViableOverloadObjectSize0(void *const p PS(0)) + __attribute__((overloadable)) { + return __builtin_object_size(p, 0); +} + +int NoViableOverloadObjectSize1(void *const p PS(1)) + __attribute__((overloadable)) { + return __builtin_object_size(p, 1); +} + +int NoViableOverloadObjectSize2(void *const p PS(2)) + __attribute__((overloadable)) { + return __builtin_object_size(p, 2); +} + +int NoViableOverloadObjectSize3(void *const p PS(3)) + __attribute__((overloadable)) { + return __builtin_object_size(p, 3); +} + +const static int SHOULDNT_BE_CALLED = -100; +int NoViableOverloadObjectSize0(void *const p PS(0)) + __attribute__((overloadable, enable_if(p == 0, "never selected"))) { + return SHOULDNT_BE_CALLED; +} + +int NoViableOverloadObjectSize1(void *const p PS(1)) + __attribute__((overloadable, enable_if(p == 0, "never selected"))) { + return SHOULDNT_BE_CALLED; +} + +int NoViableOverloadObjectSize2(void *const p PS(2)) + __attribute__((overloadable, enable_if(p == 0, "never selected"))) { + return SHOULDNT_BE_CALLED; +} + +int NoViableOverloadObjectSize3(void *const p PS(3)) + __attribute__((overloadable, enable_if(p == 0, "never selected"))) { + return SHOULDNT_BE_CALLED; +} + +// CHECK-LABEL: define void @test3 +void test3() { + struct Foo t[10]; + + // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 360) + gi = NoViableOverloadObjectSize0(&t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 360) + gi = NoViableOverloadObjectSize1(&t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 360) + gi = NoViableOverloadObjectSize2(&t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 360) + gi = NoViableOverloadObjectSize3(&t[1]); + + // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 356) + gi = NoViableOverloadObjectSize0(&t[1].t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 36) + gi = NoViableOverloadObjectSize1(&t[1].t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 356) + gi = NoViableOverloadObjectSize2(&t[1].t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36) + gi = NoViableOverloadObjectSize3(&t[1].t[1]); +} + +// CHECK-LABEL: define void @test4 +void test4(struct Foo *t) { + // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}}) + gi = NoViableOverloadObjectSize0(&t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 %{{.*}}) + gi = NoViableOverloadObjectSize1(&t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}}) + gi = NoViableOverloadObjectSize2(&t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 0) + gi = NoViableOverloadObjectSize3(&t[1]); + + // CHECK: call i32 @_Z27NoViableOverloadObjectSize0PvU17pass_object_size0(i8* %{{.*}}, i64 %{{.*}}) + gi = NoViableOverloadObjectSize0(&t[1].t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize1PvU17pass_object_size1(i8* %{{.*}}, i64 36) + gi = NoViableOverloadObjectSize1(&t[1].t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize2PvU17pass_object_size2(i8* %{{.*}}, i64 %{{.*}}) + gi = NoViableOverloadObjectSize2(&t[1].t[1]); + // CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36) + gi = NoViableOverloadObjectSize3(&t[1].t[1]); +} + +void test5() { + struct Foo t[10]; + + int (*f)(void *) = &NoViableOverloadObjectSize0; + gi = f(&t[1]); +} + +// CHECK-LABEL: define i32 @IndirectObjectSize0 +int IndirectObjectSize0(void *const p PS(0)) { + // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 %{{.*}}) + // CHECK-NOT: @llvm.objectsize + return ObjectSize0(p); +} + +// CHECK-LABEL: define i32 @IndirectObjectSize1 +int IndirectObjectSize1(void *const p PS(1)) { + // CHECK: call i32 @ObjectSize1(i8* %{{.*}}, i64 %{{.*}}) + // CHECK-NOT: @llvm.objectsize + return ObjectSize1(p); +} + +// CHECK-LABEL: define i32 @IndirectObjectSize2 +int IndirectObjectSize2(void *const p PS(2)) { + // CHECK: call i32 @ObjectSize2(i8* %{{.*}}, i64 %{{.*}}) + // CHECK-NOT: @llvm.objectsize + return ObjectSize2(p); +} + +// CHECK-LABEL: define i32 @IndirectObjectSize3 +int IndirectObjectSize3(void *const p PS(3)) { + // CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 %{{.*}}) + // CHECK-NOT: @llvm.objectsize + return ObjectSize3(p); +} + +int Overload0(void *, size_t, void *, size_t); +int OverloadNoSize(void *, void *); + +int OverloadedObjectSize(void *const p PS(0), + void *const c PS(0)) + __attribute__((overloadable)) __asm__("Overload0"); + +int OverloadedObjectSize(void *const p, void *const c) + __attribute__((overloadable)) __asm__("OverloadNoSize"); + +// CHECK-LABEL: define void @test6 +void test6() { + int known[10], *opaque; + + // CHECK: call i32 @"\01Overload0" + gi = OverloadedObjectSize(&known[0], &known[0]); + + // CHECK: call i32 @"\01Overload0" + gi = OverloadedObjectSize(&known[0], opaque); + + // CHECK: call i32 @"\01Overload0" + gi = OverloadedObjectSize(opaque, &known[0]); + + // CHECK: call i32 @"\01Overload0" + gi = OverloadedObjectSize(opaque, opaque); +} + +int Identity(void *p, size_t i) { return i; } + +// CHECK-NOT: define void @AsmObjectSize +int AsmObjectSize0(void *const p PS(0)) __asm__("Identity"); + +int AsmObjectSize1(void *const p PS(1)) __asm__("Identity"); + +int AsmObjectSize2(void *const p PS(2)) __asm__("Identity"); + +int AsmObjectSize3(void *const p PS(3)) __asm__("Identity"); + +// CHECK-LABEL: define void @test7 +void test7() { + struct Foo t[10]; + + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) + gi = AsmObjectSize0(&t[1]); + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) + gi = AsmObjectSize1(&t[1]); + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) + gi = AsmObjectSize2(&t[1]); + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 360) + gi = AsmObjectSize3(&t[1]); + + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356) + gi = AsmObjectSize0(&t[1].t[1]); + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) + gi = AsmObjectSize1(&t[1].t[1]); + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 356) + gi = AsmObjectSize2(&t[1].t[1]); + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) + gi = AsmObjectSize3(&t[1].t[1]); +} + +// CHECK-LABEL: define void @test8 +void test8(struct Foo *t) { + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) + gi = AsmObjectSize1(&t[1].t[1]); + // CHECK: call i32 @"\01Identity"(i8* %{{.*}}, i64 36) + gi = AsmObjectSize3(&t[1].t[1]); +} + +void DifferingObjectSize0(void *const p __attribute__((pass_object_size(0)))); +void DifferingObjectSize1(void *const p __attribute__((pass_object_size(1)))); +void DifferingObjectSize2(void *const p __attribute__((pass_object_size(2)))); +void DifferingObjectSize3(void *const p __attribute__((pass_object_size(3)))); + +// CHECK-LABEL: define void @test9 +void test9(void *const p __attribute__((pass_object_size(0)))) { + // CHECK: @llvm.objectsize + DifferingObjectSize2(p); + + // CHECK-NOT: @llvm.objectsize + DifferingObjectSize0(p); + DifferingObjectSize1(p); + + // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0) + DifferingObjectSize3(p); +} + +// CHECK-LABEL: define void @test10 +void test10(void *const p __attribute__((pass_object_size(1)))) { + // CHECK: @llvm.objectsize + DifferingObjectSize2(p); + // CHECK: @llvm.objectsize + DifferingObjectSize0(p); + + // CHECK-NOT: @llvm.objectsize + DifferingObjectSize1(p); + + // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0) + DifferingObjectSize3(p); +} + +// CHECK-LABEL: define void @test11 +void test11(void *const p __attribute__((pass_object_size(2)))) { + // CHECK: @llvm.objectsize + DifferingObjectSize0(p); + // CHECK: @llvm.objectsize + DifferingObjectSize1(p); + + // CHECK-NOT: @llvm.objectsize + DifferingObjectSize2(p); + + // CHECK: call void @DifferingObjectSize3(i8* %{{.*}}, i64 0) + DifferingObjectSize3(p); +} + +// CHECK-LABEL: define void @test12 +void test12(void *const p __attribute__((pass_object_size(3)))) { + // CHECK: @llvm.objectsize + DifferingObjectSize0(p); + // CHECK: @llvm.objectsize + DifferingObjectSize1(p); + + // CHECK-NOT: @llvm.objectsize + DifferingObjectSize2(p); + DifferingObjectSize3(p); +} + +// CHECK-LABEL: define void @test13 +void test13() { + // Ensuring that we don't lower objectsize if the expression has side-effects + char c[10]; + char *p = c; + + // CHECK: @llvm.objectsize + ObjectSize0(p); + + // CHECK-NOT: @llvm.objectsize + ObjectSize0(++p); + ObjectSize0(p++); +} Added: cfe/trunk/test/CodeGenCXX/pass-object-size.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pass-object-size.cpp?rev=254632&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/pass-object-size.cpp (added) +++ cfe/trunk/test/CodeGenCXX/pass-object-size.cpp Thu Dec 3 13:19:09 2015 @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s + +int gi; + +namespace lambdas { +// CHECK-LABEL: define void @_ZN7lambdas7LambdasEPc +void Lambdas(char *ptr) { + auto L1 = [](void *const p __attribute__((pass_object_size(0)))) { + return __builtin_object_size(p, 0); + }; + + int i = 0; + auto L2 = [&i](void *const p __attribute__((pass_object_size(0)))) { + return __builtin_object_size(p, 0) + i; + }; + + // CHECK: @llvm.objectsize + gi = L1(ptr); + // CHECK: @llvm.objectsize + gi = L2(ptr); +} + +// CHECK-DAG: define internal i64 @"_ZZN7lambdas7LambdasEPcENK3$_0clEPvU17pass_object_size0" +// CHECK-NOT: call i64 @llvm.objectsize +// CHECK-DAG: define internal i64 @"_ZZN7lambdas7LambdasEPcENK3$_1clEPvU17pass_object_size0" +// CHECK-NOT: call i64 @llvm.objectsize +} Added: cfe/trunk/test/Sema/pass-object-size.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/pass-object-size.c?rev=254632&view=auto ============================================================================== --- cfe/trunk/test/Sema/pass-object-size.c (added) +++ cfe/trunk/test/Sema/pass-object-size.c Thu Dec 3 13:19:09 2015 @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -Wincompatible-pointer-types +// +// Tests for the pass_object_size attribute +// Non-failure cases are covered in test/CodeGen/pass-object-size.c + +void a(void *p __attribute__((pass_object_size))); //expected-error{{'pass_object_size' attribute takes one argument}} +void b(void *p __attribute__((pass_object_size(1.0)))); //expected-error{{'pass_object_size' attribute requires parameter 1 to be an integer constant}} + +void c(void *p __attribute__((pass_object_size(4)))); //expected-error{{'pass_object_size' attribute requires integer constant between 0 and 3 inclusive}} +void d(void *p __attribute__((pass_object_size(-1)))); //expected-error{{'pass_object_size' attribute requires integer constant between 0 and 3 inclusive}} + +void e(void *p __attribute__((pass_object_size(1ULL<<32)))); //expected-error{{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}} + +void f(char p __attribute__((pass_object_size(0)))); //expected-error{{'pass_object_size' attribute only applies to constant pointer arguments}} +void g(const char p __attribute__((pass_object_size(0)))); //expected-error{{'pass_object_size' attribute only applies to constant pointer arguments}} +void h(char *p __attribute__((pass_object_size(0)))) {} //expected-error{{pass_object_size attribute only applies to constant pointer arguments}} +void i(char *p __attribute__((pass_object_size(0)))); // OK -- const is only necessary on definitions, not decls. +void j(char *p __attribute__((pass_object_size(0), pass_object_size(1)))); //expected-error{{'pass_object_size' attribute can only be applied once per parameter}} + +#define PS(N) __attribute__((pass_object_size(N))) +#define overloaded __attribute__((overloadable)) +void Overloaded(void *p PS(0)) overloaded; //expected-note{{previous declaration is here}} +void Overloaded(void *p PS(1)) overloaded; //expected-error{{conflicting pass_object_size attributes on parameters}} +void Overloaded2(void *p PS(1), void *p2 PS(0)) overloaded; //expected-note{{previous declaration is here}} +void Overloaded2(void *p PS(0), void *p2 PS(1)) overloaded; //expected-error{{conflicting pass_object_size attributes on parameters}} + +void Overloaded3(void *p PS(0), void *p2) overloaded; //expected-note{{previous declaration is here}} +void Overloaded3(void *p, void *p2 PS(0)) overloaded; //expected-error{{conflicting pass_object_size attributes on parameters}} + +void TakeFn(void (*)(void *)); +void TakeFnOvl(void (*)(void *)) overloaded; +void TakeFnOvl(void (*)(int *)) overloaded; + +void NotOverloaded(void *p PS(0)); +void IsOverloaded(void *p PS(0)) overloaded; +void IsOverloaded(char *p) overloaded; +void FunctionPtrs() { + void (*p)(void *) = NotOverloaded; //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}} + void (*p2)(void *) = &NotOverloaded; //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}} + + void (*p3)(void *) = IsOverloaded; //expected-error{{initializing 'void (*)(void *)' with an expression of incompatible type '<overloaded function type>'}} expected-note@-6{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@-5{{type mismatch}} + void (*p4)(void *) = &IsOverloaded; //expected-error{{initializing 'void (*)(void *)' with an expression of incompatible type '<overloaded function type>'}} expected-note@-7{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@-6{{type mismatch}} + + void (*p5)(char *) = IsOverloaded; + void (*p6)(char *) = &IsOverloaded; + + TakeFn(NotOverloaded); //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}} + TakeFn(&NotOverloaded); //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}} + + TakeFnOvl(NotOverloaded); //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}} + TakeFnOvl(&NotOverloaded); //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}} +} Added: cfe/trunk/test/SemaCXX/pass-object-size.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pass-object-size.cpp?rev=254632&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/pass-object-size.cpp (added) +++ cfe/trunk/test/SemaCXX/pass-object-size.cpp Thu Dec 3 13:19:09 2015 @@ -0,0 +1,122 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 + +namespace simple { +int Foo(void *const p __attribute__((pass_object_size(0)))); + +int OvlFoo(void *const p __attribute__((pass_object_size(0)))); +int OvlFoo(void *const p, int); + +struct Statics { + static int Foo(void *const p __attribute__((pass_object_size(0)))); + static int OvlFoo(void *const p __attribute__((pass_object_size(0)))); + 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}} + static int OvlFoo(double *p); +}; + +struct Members { + int Foo(void *const p __attribute__((pass_object_size(0)))); + int OvlFoo(void *const p __attribute__((pass_object_size(0)))); + int OvlFoo(void *const p, int); +}; + +void Decls() { + int (*A)(void *) = &Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} + int (*B)(void *) = Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} + + 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)}} + 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)}} + + int (*E)(void *) = &Statics::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} + 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 *')}} + + int (*G)(void *) = &Members::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} + 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)}} +} + +void Assigns() { + int (*A)(void *); + A = &Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} + A = Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} + + 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)}} + 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)}} + + A = &Statics::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} + 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 *')}} + + int (Members::*M)(void *); + M = &Members::Foo; //expected-error{{cannot take address of function 'Foo' because parameter 1 has pass_object_size attribute}} + M = &Members::OvlFoo; //expected-error{{assigning to 'int (simple::Members::*)(void *)' 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)}} +} + +} // namespace simple + +namespace templates { +template <typename T> +int Foo(void *const __attribute__((pass_object_size(0)))) { + return 0; +} + +template <typename T> struct Bar { + template <typename U> + int Foo(void *const __attribute__((pass_object_size(0)))) { + return 0; + } +}; + +void Decls() { + 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}} + int (Bar<int>::*B)(void *) = &Bar<int>::Foo<double>; //expected-error{{address of overloaded function 'Foo' does not match required type 'int (void *)'}} expected-note@62{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} +} + +void Assigns() { + int (*A)(void *); + 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}} + int (Bar<int>::*B)(void *) = &Bar<int>::Foo<double>; //expected-error{{address of overloaded function 'Foo' does not match required type 'int (void *)'}} expected-note@62{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} +} +} // namespace templates + +namespace virt { +struct Foo { + virtual void DoIt(void *const p __attribute__((pass_object_size(0)))); +}; + +struct Bar : public Foo { + void DoIt(void *const p __attribute__((pass_object_size(0)))) override; // OK +}; + +struct Baz : public Foo { + 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}} +}; +} + +namespace why { +void TakeFn(void (*)(int, void *)); +void ObjSize(int, void *const __attribute__((pass_object_size(0)))); + +void Check() { + TakeFn(ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + TakeFn(&ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + TakeFn(*ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + TakeFn(*****ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + TakeFn(*****&ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + + void (*P)(int, void *) = ****ObjSize; //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + P = ****ObjSize; //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + + TakeFn((ObjSize)); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + TakeFn((void*)ObjSize); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} + TakeFn((decltype(P))((void*)ObjSize)); //expected-error{{cannot take address of function 'ObjSize' because parameter 2 has pass_object_size attribute}} +} +} + +namespace constexpr_support { +constexpr int getObjSizeType() { return 0; } +void Foo(void *p __attribute__((pass_object_size(getObjSizeType())))); +} + +namespace lambdas { +void Bar() { + (void)+[](void *const p __attribute__((pass_object_size(0)))) {}; //expected-error-re{{invalid argument type '(lambda at {{.*}})' to unary expression}} +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits