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 | |