1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu | FileCheck %s 2 3 // Verifying that we do, in fact, select the correct function in the following 4 // cases. 5 6 void foo(int m) __attribute__((overloadable, enable_if(m > 0, ""))); 7 void foo(int m) __attribute__((overloadable)); 8 9 // CHECK-LABEL: define void @test1 10 void test1() { 11 // CHECK: store void (i32)* @_Z3fooi 12 void (*p)(int) = foo; 13 // CHECK: store void (i32)* @_Z3fooi 14 void (*p2)(int) = &foo; 15 // CHECK: store void (i32)* @_Z3fooi 16 p = foo; 17 // CHECK: store void (i32)* @_Z3fooi 18 p = &foo; 19 20 // CHECK: store i8* bitcast (void (i32)* @_Z3fooi to i8*) 21 void *vp1 = (void*)&foo; 22 // CHECK: store i8* bitcast (void (i32)* @_Z3fooi to i8*) 23 void *vp2 = (void*)foo; 24 // CHECK: store i8* bitcast (void (i32)* @_Z3fooi to i8*) 25 vp1 = (void*)&foo; 26 // CHECK: store i8* bitcast (void (i32)* @_Z3fooi to i8*) 27 vp1 = (void*)foo; 28 } 29 30 void bar(int m) __attribute__((overloadable, enable_if(m > 0, ""))); 31 void bar(int m) __attribute__((overloadable, enable_if(1, ""))); 32 // CHECK-LABEL: define void @test2 33 void test2() { 34 // CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi 35 void (*p)(int) = bar; 36 // CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi 37 void (*p2)(int) = &bar; 38 // CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi 39 p = bar; 40 // CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi 41 p = &bar; 42 43 // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*) 44 void *vp1 = (void*)&bar; 45 // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*) 46 void *vp2 = (void*)bar; 47 // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*) 48 vp1 = (void*)&bar; 49 // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*) 50 vp1 = (void*)bar; 51 } 52 53 void baz(int m) __attribute__((overloadable, enable_if(1, ""))); 54 void baz(int m) __attribute__((overloadable)); 55 // CHECK-LABEL: define void @test3 56 void test3() { 57 // CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi 58 void (*p)(int) = baz; 59 // CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi 60 void (*p2)(int) = &baz; 61 // CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi 62 p = baz; 63 // CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi 64 p = &baz; 65 } 66 67 68 const int TRUEFACTS = 1; 69 void qux(int m) __attribute__((overloadable, enable_if(1, ""), 70 enable_if(TRUEFACTS, ""))); 71 void qux(int m) __attribute__((overloadable, enable_if(1, ""))); 72 // CHECK-LABEL: define void @test4 73 void test4() { 74 // CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXL_Z9TRUEFACTSEEEi 75 void (*p)(int) = qux; 76 // CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXL_Z9TRUEFACTSEEEi 77 void (*p2)(int) = &qux; 78 // CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXL_Z9TRUEFACTSEEEi 79 p = qux; 80 // CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXL_Z9TRUEFACTSEEEi 81 p = &qux; 82 } 83 84 // There was a bug where, when enable_if was present, overload resolution 85 // wouldn't pay attention to lower-priority attributes. 86 // (N.B. `foo` with pass_object_size should always be preferred) 87 // CHECK-LABEL: define void @test5 88 void test5() { 89 int foo(char *i) __attribute__((enable_if(1, ""), overloadable)); 90 int foo(char *i __attribute__((pass_object_size(0)))) 91 __attribute__((enable_if(1, ""), overloadable)); 92 93 // CHECK: call i32 @_Z3fooUa9enable_ifIXLi1EEEPcU17pass_object_size0 94 foo((void*)0); 95 } 96