Commit 594543f
authored
[CIR][CodeGen] Emit dtor properly for objects in TernaryOp (#1614)
Currently, the following code snippet fails with a crash:
```
#include <stdio.h>
struct X {
int a;
X(int a) : a(a) {}
~X() {}
};
bool foo(const X &) { return false; }
bool bar() { return foo(1) || foo(2); }
```
it fails with
```
error: 'cir.yield' op must be the last operation in the parent block
```
The crash can be traced to the [construction of the
TernaryOp](https://github.com/llvm/clangir/blob/5df50096be1a783c26b48ea437523347df8a3110/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp#L2728).
A
[yield](https://github.com/llvm/clangir/blob/5df50096be1a783c26b48ea437523347df8a3110/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp#L2776)
is created and when the LexicalScope is destroyed the destructors for
the object follow.
So, the CIR looks something like:
```
%11 = "cir.ternary"(%10) ({
%13 = "cir.const"() <{value = #cir.bool<true> : !cir.bool}> : () -> !cir.bool
"cir.yield"(%13) : (!cir.bool) -> ()
}, {
%12 = "cir.const"() <{value = #cir.bool<false> : !cir.bool}> : () -> !cir.bool
"cir.yield"(%12) : (!cir.bool) -> ()
}) : (!cir.bool) -> !cir.bool
"cir.yield"(%11) : (!cir.bool) -> ()
"cir.call"(%7) <{callee = @_ZN1XD2Ev, calling_conv = 1 : i32, extra_attrs = #cir<extra({nothrow = #cir.nothrow})>, side_effect = 1 : i32}> ({
})
```
which is wrong, since the yield should come last.
The fix here is forcing a cleanup and then the yield follows. A similar
rule also applies
[here](https://github.com/llvm/clangir/blob/5df50096be1a783c26b48ea437523347df8a3110/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp#L2657)
for the "&&" case, e.g., foo(1) && foo(2) instead in the code snippet.
One more modification I made is adding a check for when the current
lexScope is ternary, when creating dispatch blocks for cleanups. I
believe in this case, we do not want to create a dispatch block, please
correct me if I am wrong.
Finally, I add two tests to verify that everything works as intended.1 parent 1fb346d commit 594543f
File tree
3 files changed
+59
-0
lines changed- clang
- lib/CIR/CodeGen
- test/CIR/CodeGen
3 files changed
+59
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
803 | 803 | | |
804 | 804 | | |
805 | 805 | | |
| 806 | + | |
| 807 | + | |
806 | 808 | | |
807 | 809 | | |
808 | 810 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2677 | 2677 | | |
2678 | 2678 | | |
2679 | 2679 | | |
| 2680 | + | |
2680 | 2681 | | |
2681 | 2682 | | |
2682 | 2683 | | |
| |||
2772 | 2773 | | |
2773 | 2774 | | |
2774 | 2775 | | |
| 2776 | + | |
2775 | 2777 | | |
2776 | 2778 | | |
2777 | 2779 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 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 | + | |
53 | 108 | | |
54 | 109 | | |
55 | 110 | | |
| |||
0 commit comments