1
- // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
2
- // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefix =CHECK-GNU- C
3
- // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix =CHECK-GNU- CXX
1
+ // RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,DARWIN
2
+ // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefixes =CHECK, C
3
+ // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes =CHECK, CXX
4
4
5
5
// Empty structs are ignored for PCS purposes on Darwin and in C mode elsewhere.
6
6
// In C++ mode on ELF they consume a register slot though. Functions are
15
15
16
16
struct Empty {};
17
17
18
- // CHECK : define{{.*}} i32 @empty_arg(i32 noundef %a)
19
- // CHECK-GNU- C: define{{.*}} i32 @empty_arg(i32 noundef %a)
20
- // CHECK-GNU- CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a)
18
+ // DARWIN : define{{.*}} i32 @empty_arg(i32 noundef %a)
19
+ // C: define{{.*}} i32 @empty_arg(i32 noundef %a)
20
+ // CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a)
21
21
EXTERNC int empty_arg (struct Empty e, int a) {
22
22
return a;
23
23
}
24
24
25
- // CHECK : define{{.*}} void @empty_ret()
26
- // CHECK-GNU- C: define{{.*}} void @empty_ret()
27
- // CHECK-GNU- CXX: define{{.*}} void @empty_ret()
25
+ // DARWIN : define{{.*}} void @empty_ret()
26
+ // C: define{{.*}} void @empty_ret()
27
+ // CXX: define{{.*}} void @empty_ret()
28
28
EXTERNC struct Empty empty_ret (void ) {
29
29
struct Empty e;
30
30
return e;
@@ -38,30 +38,75 @@ struct SuperEmpty {
38
38
int arr[0 ];
39
39
};
40
40
41
- // CHECK : define{{.*}} i32 @super_empty_arg(i32 noundef %a)
42
- // CHECK-GNU- C: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
43
- // CHECK-GNU- CXX: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
41
+ // DARWIN : define{{.*}} i32 @super_empty_arg(i32 noundef %a)
42
+ // C: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
43
+ // CXX: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
44
44
EXTERNC int super_empty_arg (struct SuperEmpty e, int a) {
45
45
return a;
46
46
}
47
47
48
- // This is not empty. It has 0 size but consumes a register slot for GCC.
48
+ // This is also not empty, and non-standard. We previously considered it to
49
+ // consume a register slot, but GCC does not, so we match that.
49
50
50
51
struct SortOfEmpty {
51
52
struct SuperEmpty e;
52
53
};
53
54
54
- // CHECK : define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
55
- // CHECK-GNU- C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
56
- // CHECK-GNU- CXX: define{{.*}} i32 @sort_of_empty_arg(i8 %e.coerce, i32 noundef %a)
57
- EXTERNC int sort_of_empty_arg (struct Empty e, int a) {
55
+ // DARWIN : define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
56
+ // C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
57
+ // CXX: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
58
+ EXTERNC int sort_of_empty_arg (struct SortOfEmpty e, int a) {
58
59
return a;
59
60
}
60
61
61
- // CHECK : define{{.*}} void @sort_of_empty_ret()
62
- // CHECK-GNU- C: define{{.*}} void @sort_of_empty_ret()
63
- // CHECK-GNU- CXX: define{{.*}} void @sort_of_empty_ret()
62
+ // DARWIN : define{{.*}} void @sort_of_empty_ret()
63
+ // C: define{{.*}} void @sort_of_empty_ret()
64
+ // CXX: define{{.*}} void @sort_of_empty_ret()
64
65
EXTERNC struct SortOfEmpty sort_of_empty_ret (void ) {
65
66
struct SortOfEmpty e;
66
67
return e;
67
68
}
69
+
70
+ #include < stdarg.h>
71
+
72
+ // va_arg matches the above rules, consuming an incoming argument in cases
73
+ // where one would be passed, and not doing so when the argument should be
74
+ // ignored.
75
+
76
+ EXTERNC struct Empty empty_arg_variadic (int a, ...) {
77
+ // CHECK-LABEL: @empty_arg_variadic(
78
+ // DARWIN-NOT: {{ getelementptr }}
79
+ // C-NOT: {{ getelementptr }}
80
+ // CXX: %new_reg_offs = add i32 %gr_offs, 8
81
+ // CXX: %new_stack = getelementptr inbounds i8, ptr %stack, i64 8
82
+ va_list vl;
83
+ va_start (vl, a);
84
+ struct Empty b = va_arg (vl, struct Empty );
85
+ va_end (vl);
86
+ return b;
87
+ }
88
+
89
+ EXTERNC struct SuperEmpty super_empty_arg_variadic (int a, ...) {
90
+ // CHECK-LABEL: @super_empty_arg_variadic(
91
+ // DARWIN-NOT: {{ getelementptr }}
92
+ // C-NOT: {{ getelementptr }}
93
+ // CXX-NOT: {{ getelementptr }}
94
+ va_list vl;
95
+ va_start (vl, a);
96
+ struct SuperEmpty b = va_arg (vl, struct SuperEmpty );
97
+ va_end (vl);
98
+ return b;
99
+ }
100
+
101
+ EXTERNC struct SortOfEmpty sort_of_empty_arg_variadic (int a, ...) {
102
+ // CHECK-LABEL: @sort_of_empty_arg_variadic(
103
+ // DARWIN: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 0
104
+ // C-NOT: {{ getelementptr }}
105
+ // CXX-NOT: {{ getelementptr }}
106
+ va_list vl;
107
+ va_start (vl, a);
108
+ struct SortOfEmpty b = va_arg (vl, struct SortOfEmpty );
109
+ va_end (vl);
110
+ return b;
111
+ }
112
+
0 commit comments