Skip to content

Commit 560dbdf

Browse files
committed
C++: Test demonstrating chi node back edge bug
This test shows that the back-edge detection does not properly account for chi nodes in the translation to aliased SSA.
1 parent 9963270 commit 560dbdf

File tree

7 files changed

+175
-0
lines changed

7 files changed

+175
-0
lines changed

cpp/ql/test/library-tests/ir/ir/PrintAST.expected

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6782,3 +6782,47 @@ ir.cpp:
67826782
# 1055| 0: i
67836783
# 1055| Type = int
67846784
# 1055| ValueCategory = prvalue(load)
6785+
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
6786+
# 1058| params:
6787+
# 1058| 0: n
6788+
# 1058| Type = int
6789+
# 1058| 1: p
6790+
# 1058| Type = char *
6791+
# 1058| body: { ... }
6792+
# 1059| 0: while (...) ...
6793+
# 1059| 0: ... > ...
6794+
# 1059| Type = bool
6795+
# 1059| ValueCategory = prvalue
6796+
# 1059| 0: ... --
6797+
# 1059| Type = int
6798+
# 1059| ValueCategory = prvalue
6799+
# 1059| 0: n
6800+
# 1059| Type = int
6801+
# 1059| ValueCategory = lvalue
6802+
# 1059| 1: 0
6803+
# 1059| Type = int
6804+
# 1059| Value = 0
6805+
# 1059| ValueCategory = prvalue
6806+
# 1060| 1: ExprStmt
6807+
# 1060| 0: ... = ...
6808+
# 1060| Type = char
6809+
# 1060| ValueCategory = lvalue
6810+
# 1060| 0: * ...
6811+
# 1060| Type = char
6812+
# 1060| ValueCategory = lvalue
6813+
# 1060| 0: ... ++
6814+
# 1060| Type = char *
6815+
# 1060| ValueCategory = prvalue
6816+
# 1060| 0: p
6817+
# 1060| Type = char *
6818+
# 1060| ValueCategory = lvalue
6819+
# 1060| 1: (char)...
6820+
# 1060| Conversion = integral conversion
6821+
# 1060| Type = char
6822+
# 1060| Value = 0
6823+
# 1060| ValueCategory = prvalue
6824+
# 1060| expr: 0
6825+
# 1060| Type = int
6826+
# 1060| Value = 0
6827+
# 1060| ValueCategory = prvalue
6828+
# 1061| 1: return ...

cpp/ql/test/library-tests/ir/ir/aliased_ssa_ir.expected

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4646,3 +4646,46 @@ ir.cpp:
46464646

46474647
# 1049| Block 2
46484648
# 1049| v2_0(void) = Unreached :
4649+
4650+
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
4651+
# 1058| Block 0
4652+
# 1058| v0_0(void) = EnterFunction :
4653+
# 1058| m0_1(unknown) = AliasedDefinition :
4654+
# 1058| mu0_2(unknown) = UnmodeledDefinition :
4655+
# 1058| r0_3(glval<int>) = VariableAddress[n] :
4656+
# 1058| m0_4(int) = InitializeParameter[n] : r0_3
4657+
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
4658+
# 1058| m0_6(char *) = InitializeParameter[p] : r0_5
4659+
#-----| Goto -> Block 3
4660+
4661+
# 1060| Block 1
4662+
# 1060| r1_0(char) = Constant[0] :
4663+
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
4664+
# 1060| r1_2(char *) = Load : r1_1, m3_2
4665+
# 1060| r1_3(int) = Constant[1] :
4666+
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
4667+
# 1060| m1_5(char *) = Store : r1_1, r1_4
4668+
# 1060| m1_6(char) = Store : r1_2, r1_0
4669+
# 1060| m1_7(unknown) = Chi : m3_0, m1_6
4670+
#-----| Goto (back edge) -> Block 3
4671+
4672+
# 1061| Block 2
4673+
# 1061| v2_0(void) = NoOp :
4674+
# 1058| v2_1(void) = ReturnVoid :
4675+
# 1058| v2_2(void) = UnmodeledUse : mu*
4676+
# 1058| v2_3(void) = ExitFunction :
4677+
4678+
# 1059| Block 3
4679+
# 1059| m3_0(unknown) = Phi : from 0:m0_1, from 1:m1_7
4680+
# 1059| m3_1(int) = Phi : from 0:m0_4, from 1:m3_7
4681+
# 1059| m3_2(char *) = Phi : from 0:m0_6, from 1:m1_5
4682+
# 1059| r3_3(glval<int>) = VariableAddress[n] :
4683+
# 1059| r3_4(int) = Load : r3_3, m3_1
4684+
# 1059| r3_5(int) = Constant[1] :
4685+
# 1059| r3_6(int) = Sub : r3_4, r3_5
4686+
# 1059| m3_7(int) = Store : r3_3, r3_6
4687+
# 1059| r3_8(int) = Constant[0] :
4688+
# 1059| r3_9(bool) = CompareGT : r3_4, r3_8
4689+
# 1059| v3_10(void) = ConditionalBranch : r3_9
4690+
#-----| False (back edge) -> Block 2
4691+
#-----| True (back edge) -> Block 1

cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ operandAcrossFunctions
88
instructionWithoutUniqueBlock
99
containsLoopOfForwardEdges
1010
lostReachability
11+
| ir.cpp:1060:12:1060:12 | Constant: (char)... |
12+
| ir.cpp:1061:1:1061:1 | NoOp: return ... |
1113
backEdgeCountMismatch

cpp/ql/test/library-tests/ir/ir/ir.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,4 +1055,9 @@ int DoWhileFalse() {
10551055
return i;
10561056
}
10571057

1058+
void chiNodeAtEndOfLoop(int n, char *p) {
1059+
while (n-- > 0)
1060+
*p++ = 0;
1061+
}
1062+
10581063
// semmle-extractor-options: -std=c++17

cpp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4544,3 +4544,42 @@ ir.cpp:
45444544
# 1049| v2_5(void) = ReturnValue : r2_4, mu0_2
45454545
# 1049| v2_6(void) = UnmodeledUse : mu*
45464546
# 1049| v2_7(void) = ExitFunction :
4547+
4548+
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
4549+
# 1058| Block 0
4550+
# 1058| v0_0(void) = EnterFunction :
4551+
# 1058| mu0_1(unknown) = AliasedDefinition :
4552+
# 1058| mu0_2(unknown) = UnmodeledDefinition :
4553+
# 1058| r0_3(glval<int>) = VariableAddress[n] :
4554+
# 1058| mu0_4(int) = InitializeParameter[n] : r0_3
4555+
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
4556+
# 1058| mu0_6(char *) = InitializeParameter[p] : r0_5
4557+
#-----| Goto -> Block 3
4558+
4559+
# 1060| Block 1
4560+
# 1060| r1_0(char) = Constant[0] :
4561+
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
4562+
# 1060| r1_2(char *) = Load : r1_1, mu0_2
4563+
# 1060| r1_3(int) = Constant[1] :
4564+
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
4565+
# 1060| mu1_5(char *) = Store : r1_1, r1_4
4566+
# 1060| mu1_6(char) = Store : r1_2, r1_0
4567+
#-----| Goto (back edge) -> Block 3
4568+
4569+
# 1061| Block 2
4570+
# 1061| v2_0(void) = NoOp :
4571+
# 1058| v2_1(void) = ReturnVoid :
4572+
# 1058| v2_2(void) = UnmodeledUse : mu*
4573+
# 1058| v2_3(void) = ExitFunction :
4574+
4575+
# 1059| Block 3
4576+
# 1059| r3_0(glval<int>) = VariableAddress[n] :
4577+
# 1059| r3_1(int) = Load : r3_0, mu0_2
4578+
# 1059| r3_2(int) = Constant[1] :
4579+
# 1059| r3_3(int) = Sub : r3_1, r3_2
4580+
# 1059| mu3_4(int) = Store : r3_0, r3_3
4581+
# 1059| r3_5(int) = Constant[0] :
4582+
# 1059| r3_6(bool) = CompareGT : r3_1, r3_5
4583+
# 1059| v3_7(void) = ConditionalBranch : r3_6
4584+
#-----| False -> Block 2
4585+
#-----| True -> Block 1

cpp/ql/test/library-tests/ir/ir/ssa_block_count.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
| IR: VirtualMemberFunction | 1 |
102102
| IR: WhileStatements | 4 |
103103
| IR: WhileStmtWithDeclaration | 8 |
104+
| IR: chiNodeAtEndOfLoop | 4 |
104105
| IR: designatedInit | 1 |
105106
| IR: min | 4 |
106107
| IR: operator= | 1 |

cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ir.expected

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4517,3 +4517,44 @@ ir.cpp:
45174517

45184518
# 1049| Block 2
45194519
# 1049| v2_0(void) = Unreached :
4520+
4521+
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
4522+
# 1058| Block 0
4523+
# 1058| v0_0(void) = EnterFunction :
4524+
# 1058| mu0_1(unknown) = AliasedDefinition :
4525+
# 1058| mu0_2(unknown) = UnmodeledDefinition :
4526+
# 1058| r0_3(glval<int>) = VariableAddress[n] :
4527+
# 1058| m0_4(int) = InitializeParameter[n] : r0_3
4528+
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
4529+
# 1058| m0_6(char *) = InitializeParameter[p] : r0_5
4530+
#-----| Goto -> Block 3
4531+
4532+
# 1060| Block 1
4533+
# 1060| r1_0(char) = Constant[0] :
4534+
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
4535+
# 1060| r1_2(char *) = Load : r1_1, m3_1
4536+
# 1060| r1_3(int) = Constant[1] :
4537+
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
4538+
# 1060| m1_5(char *) = Store : r1_1, r1_4
4539+
# 1060| mu1_6(char) = Store : r1_2, r1_0
4540+
#-----| Goto (back edge) -> Block 3
4541+
4542+
# 1061| Block 2
4543+
# 1061| v2_0(void) = NoOp :
4544+
# 1058| v2_1(void) = ReturnVoid :
4545+
# 1058| v2_2(void) = UnmodeledUse : mu*
4546+
# 1058| v2_3(void) = ExitFunction :
4547+
4548+
# 1059| Block 3
4549+
# 1059| m3_0(int) = Phi : from 0:m0_4, from 1:m3_6
4550+
# 1059| m3_1(char *) = Phi : from 0:m0_6, from 1:m1_5
4551+
# 1059| r3_2(glval<int>) = VariableAddress[n] :
4552+
# 1059| r3_3(int) = Load : r3_2, m3_0
4553+
# 1059| r3_4(int) = Constant[1] :
4554+
# 1059| r3_5(int) = Sub : r3_3, r3_4
4555+
# 1059| m3_6(int) = Store : r3_2, r3_5
4556+
# 1059| r3_7(int) = Constant[0] :
4557+
# 1059| r3_8(bool) = CompareGT : r3_3, r3_7
4558+
# 1059| v3_9(void) = ConditionalBranch : r3_8
4559+
#-----| False -> Block 2
4560+
#-----| True -> Block 1

0 commit comments

Comments
 (0)