| 1 | // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify %s |
| 2 | // RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only -DCHECK_ALIASES %s |
| 3 | // RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s |
| 4 | |
| 5 | #if defined(_WIN32) |
| 6 | void foo() {} |
| 7 | void bar() __attribute__((ifunc("foo"))); |
| 8 | //expected-warning@-1 {{unknown attribute 'ifunc' ignored}} |
| 9 | |
| 10 | #else |
| 11 | #if defined(CHECK_ALIASES) |
| 12 | void* f1_ifunc(); |
| 13 | void f1() __attribute__((ifunc("f1_ifunc"))); |
| 14 | //expected-error@-1 {{ifunc must point to a defined function}} |
| 15 | |
| 16 | void* f2_a() __attribute__((ifunc("f2_b"))); |
| 17 | //expected-error@-1 {{ifunc definition is part of a cycle}} |
| 18 | void* f2_b() __attribute__((ifunc("f2_a"))); |
| 19 | //expected-error@-1 {{ifunc definition is part of a cycle}} |
| 20 | |
| 21 | void* f3_a() __attribute__((ifunc("f3_b"))); |
| 22 | //expected-warning@-1 {{ifunc will always resolve to f3_c even if weak definition of f3_b is overridden}} |
| 23 | void* f3_b() __attribute__((weak, alias("f3_c"))); |
| 24 | void* f3_c() { return 0; } |
| 25 | |
| 26 | void f4_ifunc() {} |
| 27 | void f4() __attribute__((ifunc("f4_ifunc"))); |
| 28 | //expected-error@-1 {{ifunc resolver function must return a pointer}} |
| 29 | |
| 30 | #else |
| 31 | void f1a() __asm("f1"); |
| 32 | void f1a() {} |
| 33 | //expected-note@-1 {{previous definition is here}} |
| 34 | void f1() __attribute__((ifunc("f1_ifunc"))); |
| 35 | //expected-error@-1 {{definition with same mangled name 'f1' as another definition}} |
| 36 | void* f1_ifunc() { return 0; } |
| 37 | |
| 38 | void* f6_ifunc(int i); |
| 39 | void __attribute__((ifunc("f6_ifunc"))) f6() {} |
| 40 | //expected-error@-1 {{definition 'f6' cannot also be an ifunc}} |
| 41 | |
| 42 | #endif |
| 43 | #endif |
| 44 | |