@@ -43,26 +43,25 @@ void test_member_expr_byval(void *buf, struct TestWithCap t, struct TestNoCap t2
43
43
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
44
44
// CHECK-SAME: , i64 32, i1 false) [[MUST_PRESERVE_CHARPTR:#[0-9]+]]{{$}}
45
45
// No attribute for the following four cases:
46
- __builtin_memcpy (buf, &t.not_a_cap , 32 );
46
+ __builtin_memcpy (buf, &t.not_a_cap , 64 );
47
47
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
48
- // CHECK-SAME: , i64 32 , i1 false){{$}}
49
- __builtin_memcpy (buf, t.array , 32 );
48
+ // CHECK-SAME: , i64 64 , i1 false){{$}}
49
+ __builtin_memcpy (buf, t.array , 48 );
50
50
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
51
- // CHECK-SAME: , i64 32 , i1 false){{$}}
51
+ // CHECK-SAME: , i64 48 , i1 false){{$}}
52
52
__builtin_memcpy (buf, &t.n , 32 );
53
53
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
54
54
// CHECK-SAME: , i64 32, i1 false){{$}}
55
- __builtin_memcpy (buf, (&t)->array , 32 );
55
+ __builtin_memcpy (buf, (&t)->array , 48 );
56
56
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
57
- // CHECK-SAME: , i64 32 , i1 false){{$}}
57
+ // CHECK-SAME: , i64 48 , i1 false){{$}}
58
58
__builtin_memcpy (buf, &(&t)->not_a_cap , 32 );
59
59
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
60
60
// CHECK-SAME: , i64 32, i1 false){{$}}
61
61
62
62
// However, for the struct without capabilities all of these should be safe:
63
63
// However, we don't know here that there is no subclass that could have
64
- // capabilities following the current object.
65
- // TODO: If we know the size of the copy <= sizeof(T), we should set the attribute.
64
+ // capabilities following the current object, so we have to look at the copy size.
66
65
__builtin_memcpy (buf, &t2, sizeof (t2));
67
66
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
68
67
// CHECK-SAME: , i64 80, i1 false) [[NO_PRESERVE_TAGS:#[0-9]+]]{{$}}
@@ -72,24 +71,24 @@ void test_member_expr_byval(void *buf, struct TestWithCap t, struct TestNoCap t2
72
71
// CHECK-SAME: , i64 96, i1 false){{$}}
73
72
__builtin_memcpy (buf, &t2.not_a_cap , 40 );
74
73
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
75
- // CHECK-SAME: , i64 40, i1 false){{$}}
76
- // TODO-CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
74
+ // CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
75
+ __builtin_memcpy (buf, t2.array , 32 );
76
+ // CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
77
+ // CHECK-SAME: , i64 32, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
78
+ // / Check that we also set the attribute if we are copying beyond
79
+ // / the end of the array-decay expressions.
77
80
__builtin_memcpy (buf, t2.array , 40 );
78
81
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
79
- // CHECK-SAME: , i64 40, i1 false){{$}}
80
- // TODO-CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
82
+ // CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
81
83
__builtin_memcpy (buf, &t2.n , 40 );
82
84
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
83
- // CHECK-SAME: , i64 40, i1 false){{$}}
84
- // TODO-CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
85
+ // CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
85
86
__builtin_memcpy (buf, (&t2)->array , 40 );
86
87
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
87
- // CHECK-SAME: , i64 40, i1 false){{$}}
88
- // TODO-CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
88
+ // CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
89
89
__builtin_memcpy (buf, &(&t2)->not_a_cap , 40 );
90
90
// CHECK: call void @llvm.memcpy.p200i8.p200i8.i64(
91
- // CHECK-SAME: , i64 40, i1 false){{$}}
92
- // TODO-CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
91
+ // CHECK-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
93
92
94
93
// Direct assignment should always the no_preserve_tags attribute (the C2x
95
94
// 6.5 memcpy+"Allocated objects have no declared type." case does not apply):
@@ -177,15 +176,15 @@ void test_member_expr_ref(void *buf, struct TestWithCap &t, struct TestNoCap &t2
177
176
__builtin_memcpy (buf, &t.not_a_cap , 32 );
178
177
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
179
178
// CHECK-CXX-SAME: , i64 32, i1 false){{$}}
180
- __builtin_memcpy (buf, t.array , 32 );
179
+ __builtin_memcpy (buf, t.array , 40 );
181
180
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
182
- // CHECK-CXX-SAME: , i64 32 , i1 false){{$}}
181
+ // CHECK-CXX-SAME: , i64 40 , i1 false){{$}}
183
182
__builtin_memcpy (buf, &t.n , 32 );
184
183
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
185
184
// CHECK-CXX-SAME: , i64 32, i1 false){{$}}
186
- __builtin_memcpy (buf, (&t)->array , 32 );
185
+ __builtin_memcpy (buf, (&t)->array , 40 );
187
186
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
188
- // CHECK-CXX-SAME: , i64 32 , i1 false){{$}}
187
+ // CHECK-CXX-SAME: , i64 40 , i1 false){{$}}
189
188
__builtin_memcpy (buf, &(&t)->not_a_cap , 32 );
190
189
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
191
190
// CHECK-CXX-SAME: , i64 32, i1 false){{$}}
@@ -196,24 +195,19 @@ void test_member_expr_ref(void *buf, struct TestWithCap &t, struct TestNoCap &t2
196
195
// CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
197
196
__builtin_memcpy (buf, &t2.not_a_cap , 40 );
198
197
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
199
- // CHECK-CXX-SAME: , i64 40, i1 false){{$}}
200
- // TODO-CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
198
+ // CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
201
199
__builtin_memcpy (buf, t2.array , 40 );
202
200
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
203
- // CHECK-CXX-SAME: , i64 40, i1 false){{$}}
204
- // TODO-CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
201
+ // CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
205
202
__builtin_memcpy (buf, &t2.n , 40 );
206
203
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
207
- // CHECK-CXX-SAME: , i64 40, i1 false){{$}}
208
- // TODO-CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
204
+ // CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
209
205
__builtin_memcpy (buf, (&t2)->array , 40 );
210
206
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
211
- // CHECK-CXX-SAME: , i64 40, i1 false){{$}}
212
- // TODO-CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
207
+ // CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
213
208
__builtin_memcpy (buf, &(&t2)->not_a_cap , 40 );
214
209
// CHECK-CXX: call void @llvm.memcpy.p200i8.p200i8.i64(
215
- // CHECK-CXX-SAME: , i64 40, i1 false){{$}}
216
- // TODO-CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
210
+ // CHECK-CXX-SAME: , i64 40, i1 false) [[NO_PRESERVE_TAGS]]{{$}}
217
211
218
212
// Direct assignment should always the no_preserve_tags attribute (the C2x
219
213
// 6.5 memcpy+"Allocated objects have no declared type." case does not apply):
@@ -225,4 +219,4 @@ void test_member_expr_ref(void *buf, struct TestWithCap &t, struct TestNoCap &t2
225
219
226
220
// CHECK: attributes [[MUST_PRESERVE_STRUCT_WITHCAP]] = { must_preserve_cheri_tags "frontend-memtransfer-type"="'struct TestWithCap'" }
227
221
// CHECK: attributes [[MUST_PRESERVE_CHARPTR]] = { must_preserve_cheri_tags "frontend-memtransfer-type"="'char * __capability'" }
228
- // CHECK-C : attributes [[NO_PRESERVE_TAGS]] = { no_preserve_cheri_tags }
222
+ // CHECK: attributes [[NO_PRESERVE_TAGS]] = { no_preserve_cheri_tags }
0 commit comments