<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/90341>90341</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Invalid examples in ObjC-Block-ABI specification doc examples
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
TheLouisHong
</td>
</tr>
</table>
<pre>
# Context
Referring to the following:
- Clang 19.0.0git documentation `BLOCK IMPLEMENTATION SPECIFICATION`
- `Imported Variables` segment (segment describing objc blocks' behavior when importing variables) https://clang.llvm.org/docs/Block-ABI-Apple.html#imported-const-copy-of-block-reference
- `Imported const copy of Block reference` sub-section
There exists an example in the block ABI doc that is of the following:
```C++
void (^existingBlock)(void) = ...;
void (^vv)(void) = ^{ existingBlock(); }
vv();
struct __block_literal_3 {
...; // existing block
};
struct __block_literal_4 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_4 *);
struct __block_literal_3 *const existingBlock;
};
void __block_invoke_4(struct __block_literal_2 *_block) {
__block->existingBlock->invoke(__block->existingBlock);
}
void __block_copy_4(struct __block_literal_4 *dst, struct __block_literal_4 *src) {
//_Block_copy_assign(&dst->existingBlock, src->existingBlock, 0);
_Block_object_assign(&dst->existingBlock, src->existingBlock, BLOCK_FIELD_IS_BLOCK);
}
void __block_dispose_4(struct __block_literal_4 *src) {
// was _Block_destroy
_Block_object_dispose(src->existingBlock, BLOCK_FIELD_IS_BLOCK);
}
static struct __block_descriptor_4 {
unsigned long int reserved;
unsigned long int Block_size;
void (*copy_helper)(struct __block_literal_4 *dst, struct __block_literal_4 *src);
void (*dispose_helper)(struct __block_literal_4 *);
} __block_descriptor_4 = {
0,
sizeof(struct __block_literal_4),
__block_copy_4,
__block_dispose_4,
};
```
I want to highlight this particular invoke function within the example
```C++
void __block_invoke_4(struct __block_literal_2 *_block) {
__block->existingBlock->invoke(__block->existingBlock);
}
```
# Issue
This function does not make sense within the context, appears to be invalid C++ code, and most importantly, the example contradicts the ABI spec it describes.
1. __block_literal_2 is undefined within the example.
2. the parameter of `__block_invoke_4` is named `_block`, but the function body dereferences `__block` (two underscores)
3. Within the context and my understanding of the block ABI, `__block_invoke_4` should take the parameter of pointer to type `__block_literal_4`, as it is the `invoke` function _of_ `__block_literal_4 `.
Within the example we can see invoke is a function pointer of type `void (*invoke)(struct __block_literal_4 *);`
```C++
struct __block_literal_4 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_4 *);
struct __block_literal_3 *const existingBlock;
};
```
# Verification
`clang -rewrite-objc -o a.c test.m` confirms that the doc is indeed err and typo-ed
`test.m`
```objc
int main (int argc, const char * argv[])
{
void (^existingBlock)(void) = ^{ char* stub = "existingBlockkkkkkkkkk";};
void (^vv)(void) = ^{ existingBlock(); char* stub = "vvvvvvvvvvvvvv";};
vv();
return 0;
}
```
```C
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
char* stub = "existingBlockkkkkkkkkk";}
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
struct __main_block_impl_1 {
struct __block_impl impl;
struct __main_block_desc_1* Desc;
struct __block_impl *existingBlock;
__main_block_impl_1(void *fp, struct __main_block_desc_1 *desc, void *_existingBlock, int flags=0) : existingBlock((struct __block_impl *)_existingBlock) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
// LOUIS
// ===========================
// correctly declared as pointer to own block struct
static void __main_block_func_1(struct __main_block_impl_1 *__cself) {
// correctly uses __cself
void (*existingBlock)() = (void (*)())__cself->existingBlock; // bound by copy
((void (*)(__block_impl *))((__block_impl *)existingBlock)->FuncPtr)((__block_impl *)existingBlock); char* stub = "vvvvvvvvvvvvvv";
}
// ===========================
static void __main_block_copy_1(struct __main_block_impl_1*dst, struct __main_block_impl_1*src) {_Block_object_assign((void*)&dst->existingBlock, (void*)src->existingBlock, 7/*BLOCK_FIELD_IS_BLOCK*/);}
static void __main_block_dispose_1(struct __main_block_impl_1*src) {_Block_object_dispose((void*)src->existingBlock, 7/*BLOCK_FIELD_IS_BLOCK*/);}
static struct __main_block_desc_1 {
size_t reserved;
size_t Block_size;
void (*copy)(struct __main_block_impl_1*, struct __main_block_impl_1*);
void (*dispose)(struct __main_block_impl_1*);
} __main_block_desc_1_DATA = { 0, sizeof(struct __main_block_impl_1), __main_block_copy_1, __main_block_dispose_1};
int main (int argc, const char * argv[])
{
void (*existingBlock)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
void (*vv)(void) = ((void (*)())&__main_block_impl_1((void *)__main_block_func_1, &__main_block_desc_1_DATA, (void *)existingBlock, 570425344));
((void (*)(__block_impl *))((__block_impl *)vv)->FuncPtr)((__block_impl *)vv);
return 0;
}
```
# Comment
The error appears to be copy-paste errors and/or typos.
I noticed similar typos/errors in every example after this one. This particular documentation requires review. https://clang.llvm.org/docs/Block-ABI-Apple.html
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWVuT2joS_jWely4oIy4zPPDAZailNidJbWbPeaSE3YASI3klGTLn12-1fMFXwiSTqkNRCSNLre6vW62v29wYcZCIM2-88MarB57Yo9KzlyN-UIkw_1Ly8LBT4evMY0NYKmnxuwXPX3n-_D-4R62FPIBVYI8IexVF6iLkwRvO0yk9WEZcHmAw7ft9_yAshCpITigtt0JJ8Cb-4sOn5b9h88fnD89_PH98mb9sPn2EL5-fl5v1Zun-8iZ-Kg0AoEdrNqdYaYsh_Mm14LsIjTfxweCBJIPHnvKfIZpAix3pqHZfA9hFKvhmPPYIOzzys1AaLkeUIJxAmnYuJLIpHK2NDRnD1h5bB2RKP4rOp77SB4-tQxUYj60XJLQ3X2x68ziOsH-0p8hjQ5Ep2QuUNLYXqPi1p_Y9p0JPE3YoA8wsq5rlVgCtALUHJx-uKyY-gEl2PYMBgZhKSP99OaJGwO_CWANcAn7npzhCENI5yO0N88WG3AD2yC0IQ1u0e4-Ad9-lxxb0daNnJULC2Bs_u42EPDgNPTb12BM9Jei84Qr6_b43bK46n5tTvfGz97iAmsAnmjhcgPe4yqSci8Gy2cbqJLCw3ToDt5GwqHm0HYL3uChCJ9UGUl8WO6WYZMIeV_cJHpUEZ4bNheHFYgpUIS3sI34wjVGNBvUZw8qDAh82F_KsvmGKUbcCbF7GgUR0o8DmaURV4S1MbZjtlMnlpOpsR93aMNohHXP-LLDJJva8YTVUaCC38qlrUsXNeQC06EfH5JZ2DqvQWI8tuyByU4wOqtrTJ42W7eK6U5ownacmobEtai_B6KB13K-7DDLJavcVA_tLsl0e3a43zx9W282XrfvzXghDYWJlbvr4RxDBhZvcmhCN1eo1D4KKidlWtNH7GGLoKgnqnk0Tf2yVrhzWRLrbLoRIyUP3YWxOS20w4m_sOrUuOI4Yxah_fHTvDseu3XKP3bthDcAOnCgRl33re2xZyi_ib1T7Gxs5NUoL6id0WU0L5bBbtqSi_PYpe3sDFy4tEY6jOBwjcThasEdhIObaiiCJuIY0s8A-ke5-hIuwx-wCzO7DH15v_8zc1wYI0bKNMQlWaYAwV_tDhQaksnDi3xAMSoNlTIKU1FE88jhGrg3BuyPScOaRCCGDBwIVopslQzgpYzPWxKWNXmm8BLATqnkoAmvcOHEOE2MAoiBlaPplnQf9FmyFgUSGuBd0GJt-7GdMlPXdaMw1P6FFTZTGm_gNL058kij5CUP3PHXbhMIcdolNaVAOG7FeCLHgXaYkkiR57MlelNNPm0BpRxlTfYZ9-KsBcIrba7bAchk6WrqvMjNSpUN1c1RJFIIlLzbMjZWQ9JOo-GuMZRnX85layg15QaSO8SZ-Fo0T_2r7Vu23rSJoMEcdiv__angGLggBl2AQ8_MoDPDrDrm-ZH-m789ToOqRAGg_2Z0MaVS70do5XTuhu0Hp3oXU_TytAyhn0xIode9RCvkTtdiLgJcKionvCh7oabxoYbHnKqieAt4PwKKx_RPFTKDkXuiTScsJCgGqLYQBIUPEEFBrF_n2NVY9DCu5a-IXcmopjvZKhwjeExeScKTfXB8CiuKsRjpyTUDQ8DktYYtTWHHq_VVLVoqQZBJsbLJLxxmrrCw-HmMEcwXsyoZvL3jaNj9XPh2b1usjGtRoEy3Bv_dGuR6eag1EXsjT0imOtn752NSilCbQ_RCVNGkTRHfB1idTV2iC6-SW3TIAydv7uMKeGvIcxSJ5bFk-tiu_wV5JdF8YnoE82X78slQy0Gjxi-XBt_qRylasSaBbU8sI6dNEBp-tTp_HldVkpRsPK-ZeK9yyRzNqmzGSkpWURR0gt3zD5tttYDDaV43-mbi-QbdbsC-2IsK4bU2O2ZMWVp2S04bU7Wr-Ms8JquOlLXS0JWSmN2r6-vRBWfVfCOdBM5xb5Xls3pW5W5S7P_wH5fDP12wbdVbzYAznLfmoflvlqntsWpf5m89WMeGdjldOoF35-uHTfzdfKiPecPXO37L0W59AaY2BjYh-BhHXGBJnKzE8dZEZY0ydc0-6GNw6KYOudJFpe9UoMWggn5mhW6I5LXdrceMVAfyU8Zz0qmLTTFyzCrq263YqkSHsXl1TNNs3Dc-GzJZAzTdre1bXmLTIIuwty950a9du4d8ab51R4ary21HR0qlom3NtC3W2szLukzqjs7dVmdfVH3p0eM3b20QpmNPOe6sJQ96E-CESXVZeO1q_X_1bOf-Xrt1GK6tWqbQB8sO4qBLRZvfqrj3qfauG5T9FDQZpr6r9RCy7IqR0ebxHWXI7b1aqhfZUl6e2STtdLlEGl2VbGOQS6qtLfCsT39GCbK1q3qzn4A49B516DjI9l1CV0Th140d_xMbD0ajFpve5Rxwcd14eKXSFDm8t0Nyb2NMJpc3bfUhlttK1Bp575RhzY7PHhgpxj62VdtW4yRs5eWtVKisCDMGIk4h4Nslj62yxkIBn1K9Fj4fvHR85CgNKYh9eao3Y6rtejf9LhEYDGs8CL_1feLv6EM6G4XQ45Q84GzwORoz5YzZ8OM5CjtMnNg2n4XAy3vMxH00ngz0bB4_4hGyCD2LGfDbyR-xxwBjzB_29H0xCxofBwJ_sp_snb-TjiYuo0ORBGJPgbOoPR4OHiO8wMu5dOWMSL-Ae0q0-Xj3oGa3p7ZKD8UZ-JIw1VylW2Ahnm6ylmiHoMP20-7rsFVa6LmnRinG9lHzyQ6KjWRW0g7DHZNcP1Mlja9or-68Xa0WXk8fWTkMC0lnw_wAAAP__TG3Kyw">