Commit 250c110
[CIR][CodeGen] Emit RunCleanupsScope's dtor properly for ExprWithCleanups (llvm#1581)
The following code snippet crashes during CIR CodeGen using `clang
tmp.cpp -Xclang -emit-cir -S -o -`:
```
#include <vector>
void foo() {
std::vector<int> v(1);
}
```
The crash is:
```
mlir::Operation* mlir::Block::getTerminator(): Assertion `mightHaveTerminator()' failed.
```
What happens is the scope created
[here](https://github.com/llvm/clangir/blob/c7b27ece0971c632f2ebec26bc855ee9b118ffcc/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp#L2370C1-L2381C10)
is malformed. The operations inside the scope using
`--mlir-print-assume-verified` looks something like:
```
%0 = cir.alloca !cir.record<class "std::allocator<int>" padded {!cir.int<u, 8>} #cir.record.decl.ast>, !cir.ptr<!cir.record<class "std::allocator<int>" padded {!cir.int<u, 8>} #cir.record.decl.ast>>, ["ref.tmp0"] {alignment = 1 : i64}
%1 = cir.load <<UNKNOWN SSA VALUE>> : !cir.ptr<!cir.int<u, 64>>, !cir.int<u, 64>
%2 = cir.load <<UNKNOWN SSA VALUE>> : !cir.ptr<!cir.ptr<!cir.record<class "std::allocator<int>" padded {!cir.int<u, 8>} #cir.record.decl.ast>>>, !cir.ptr<!cir.record<class "std::allocator<int>" padded {!cir.int<u, 8>} #cir.record.decl.ast>>
cir.call @_ZNSaIiEC1ERKS_(%0, %2) : (!cir.ptr<!cir.record<class "std::allocator<int>" padded {!cir.int<u, 8>} #cir.record.decl.ast>>, !cir.ptr<!cir.record<class "std::allocator<int>" padded {!cir.int<u, 8>} #cir.record.decl.ast>>) -> () extra(#cir<extra({nothrow = #cir.nothrow})>)
%3 = cir.call @_ZNSt6vectorIiSaIiEE11_S_max_sizeERKS0_(%0) : (!cir.ptr<!cir.record<class "std::allocator<int>" padded {!cir.int<u, 8>} #cir.record.decl.ast>>) -> !cir.int<u, 64> extra(#cir<extra({nothrow = #cir.nothrow})>)
%4 = cir.cmp(gt, %1, %3) : !cir.int<u, 64>, !cir.bool
cir.yield %4 : !cir.bool
cir.call @_ZNSaIiED1Ev(%0) : (!cir.ptr<!cir.record<class "std::allocator<int>" padded {!cir.int<u, 8>} #cir.record.decl.ast>>) -> () extra(#cir<extra({nothrow = #cir.nothrow})>)
```
`_ZNSaIiED1Ev` is `std::allocator<int>::~allocator()`. So, the
destructor comes after the YieldOp has been created, which is wrong. The
destructor comes from the destruction of
[`RunCleanupScope`](https://github.com/llvm/clangir/blob/c7b27ece0971c632f2ebec26bc855ee9b118ffcc/clang/lib/CIR/CodeGen/CIRGenFunction.h#L1369)
since `LexicalScope` inherits from it. RunCleanupsScope's dtor should
come before the yield is created!
This PR fixes this by calling `ForceCleanup` before creating the yield,
so the YieldOp becomes the last operation in the scope. I found this bug
using the code snippet above, but I have added a reduced version, using
[creduce](https://github.com/csmith-project/creduce), as a test, because
[std-cxx.h](https://github.com/llvm/clangir/blob/main/clang/test/CIR/Inputs/std-cxx.h)
doesn't quite replicate `std::vector` correctly.1 parent 1d2f4f8 commit 250c110
File tree
2 files changed
+49
-3
lines changed- clang
- lib/CIR/CodeGen
- test/CIR/CodeGen
2 files changed
+49
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2375 | 2375 | | |
2376 | 2376 | | |
2377 | 2377 | | |
| 2378 | + | |
| 2379 | + | |
| 2380 | + | |
| 2381 | + | |
2378 | 2382 | | |
2379 | 2383 | | |
2380 | 2384 | | |
2381 | 2385 | | |
2382 | 2386 | | |
2383 | | - | |
2384 | | - | |
2385 | | - | |
2386 | 2387 | | |
2387 | 2388 | | |
2388 | 2389 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
0 commit comments