[clang] [Clang] Fix assertion when __block is used on global variables in C mode (PR #194856)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 30 08:39:30 PDT 2026


TPPPP72 wrote:

@AaronBallman @JustinStitt 
After some research, I now believe there's a more precise fix.

By examining the entire function chain, I discovered that the first line of code, `handleBlocksAttr->CheckVariableDeclarationType`, marks this node as invalid, while the second line, `CheckVariableDeclarationType->MergeVarDecl->CheckCompleteVariableDeclaration`, does not (because before calling `MergeVarDecl`, only the `int x` VarDecl is valid).

Therefore, the fundamental reason this fix works is that we directly intercept the generation of `BlocksAttr` for the guaranteed `MergeVarDecl` call on `x`.

This naturally leads me to wonder, is there a better way than removing `BlocksAttr` from the `AST`?

Naturally, I think there are now three solutions, and I personally prefer the second one:

1. Adopt the current solution.

2. Add a check directly to `MergeVarDecl`; if it doesn't meet the requirement, remove the `BlockAttr` from the current `VarDecl`.

3. Add an additional check in `CheckCompleteVariableDeclaration`.

So the problem is now clear, and I think we should discuss whether we should retain this invalid `BlockAttr` in the `AST`.

Below is my `AST-dump` test for the second solution:
### Code 1
```c
__block int x;
int y = x;
```
```
TranslationUnitDecl 0x7d515a1fb908 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x7d515a2509a8 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x7d515a1fc190 '__int128'
|-TypedefDecl 0x7d515a250a20 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x7d515a1fc1c0 'unsigned __int128'
|-TypedefDecl 0x7d515a250da8 <<invalid sloc>> <invalid sloc> implicit __NSConstantString 'struct __NSConstantString_tag'
| `-RecordType 0x7d515a250d60 'struct __NSConstantString_tag' canonical
|   `-Record 0x7d515a250a80 '__NSConstantString_tag'
|-TypedefDecl 0x7d515a1fc580 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x7d515a1fc530 'char *'
|   `-BuiltinType 0x7d515a1fb9e0 'char'
|-TypedefDecl 0x7d515a250930 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'struct __va_list_tag[1]'
| `-ConstantArrayType 0x7d515a1fc8a0 'struct __va_list_tag[1]' 1
|   `-RecordType 0x7d515a1fc840 'struct __va_list_tag' canonical
|     `-Record 0x7d515a1fc5e0 '__va_list_tag'
|-VarDecl 0x7d515a250e38 <<built-in>:42:17, test.c:1:13> col:13 invalid x 'int'
| `-BlocksAttr 0x7d515a250ea8 <<built-in>:42:32, col:48> ByRef
`-VarDecl 0x7d515a250f30 <test.c:2:1, col:9> col:5 y 'int' cinit
  `-RecoveryExpr 0x7d515a250ff0 <col:9> '<dependent type>' contains-errors lvalue
```
### Code 2
```c
__block int x;
int x;
```
```
TranslationUnitDecl 0x7d8c35bfb908 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x7d8c35c509a8 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x7d8c35bfc190 '__int128'
|-TypedefDecl 0x7d8c35c50a20 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x7d8c35bfc1c0 'unsigned __int128'
|-TypedefDecl 0x7d8c35c50da8 <<invalid sloc>> <invalid sloc> implicit __NSConstantString 'struct __NSConstantString_tag'
| `-RecordType 0x7d8c35c50d60 'struct __NSConstantString_tag' canonical
|   `-Record 0x7d8c35c50a80 '__NSConstantString_tag'
|-TypedefDecl 0x7d8c35bfc580 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x7d8c35bfc530 'char *'
|   `-BuiltinType 0x7d8c35bfb9e0 'char'
|-TypedefDecl 0x7d8c35c50930 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'struct __va_list_tag[1]'
| `-ConstantArrayType 0x7d8c35bfc8a0 'struct __va_list_tag[1]' 1
|   `-RecordType 0x7d8c35bfc840 'struct __va_list_tag' canonical
|     `-Record 0x7d8c35bfc5e0 '__va_list_tag'
|-VarDecl 0x7d8c35c50e38 <<built-in>:42:17, test.c:1:13> col:13 invalid x 'int'
| `-BlocksAttr 0x7d8c35c50ea8 <<built-in>:42:32, col:48> ByRef
`-VarDecl 0x7d8c35c50f30 <test.c:2:1, col:5> col:5 x 'int'
```

https://github.com/llvm/llvm-project/pull/194856


More information about the cfe-commits mailing list