зеркало из https://github.com/github/codeql.git
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.
This commit is contained in:
Родитель
9963270d63
Коммит
560dbdf984
|
@ -6782,3 +6782,47 @@ ir.cpp:
|
||||||
# 1055| 0: i
|
# 1055| 0: i
|
||||||
# 1055| Type = int
|
# 1055| Type = int
|
||||||
# 1055| ValueCategory = prvalue(load)
|
# 1055| ValueCategory = prvalue(load)
|
||||||
|
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
|
||||||
|
# 1058| params:
|
||||||
|
# 1058| 0: n
|
||||||
|
# 1058| Type = int
|
||||||
|
# 1058| 1: p
|
||||||
|
# 1058| Type = char *
|
||||||
|
# 1058| body: { ... }
|
||||||
|
# 1059| 0: while (...) ...
|
||||||
|
# 1059| 0: ... > ...
|
||||||
|
# 1059| Type = bool
|
||||||
|
# 1059| ValueCategory = prvalue
|
||||||
|
# 1059| 0: ... --
|
||||||
|
# 1059| Type = int
|
||||||
|
# 1059| ValueCategory = prvalue
|
||||||
|
# 1059| 0: n
|
||||||
|
# 1059| Type = int
|
||||||
|
# 1059| ValueCategory = lvalue
|
||||||
|
# 1059| 1: 0
|
||||||
|
# 1059| Type = int
|
||||||
|
# 1059| Value = 0
|
||||||
|
# 1059| ValueCategory = prvalue
|
||||||
|
# 1060| 1: ExprStmt
|
||||||
|
# 1060| 0: ... = ...
|
||||||
|
# 1060| Type = char
|
||||||
|
# 1060| ValueCategory = lvalue
|
||||||
|
# 1060| 0: * ...
|
||||||
|
# 1060| Type = char
|
||||||
|
# 1060| ValueCategory = lvalue
|
||||||
|
# 1060| 0: ... ++
|
||||||
|
# 1060| Type = char *
|
||||||
|
# 1060| ValueCategory = prvalue
|
||||||
|
# 1060| 0: p
|
||||||
|
# 1060| Type = char *
|
||||||
|
# 1060| ValueCategory = lvalue
|
||||||
|
# 1060| 1: (char)...
|
||||||
|
# 1060| Conversion = integral conversion
|
||||||
|
# 1060| Type = char
|
||||||
|
# 1060| Value = 0
|
||||||
|
# 1060| ValueCategory = prvalue
|
||||||
|
# 1060| expr: 0
|
||||||
|
# 1060| Type = int
|
||||||
|
# 1060| Value = 0
|
||||||
|
# 1060| ValueCategory = prvalue
|
||||||
|
# 1061| 1: return ...
|
||||||
|
|
|
@ -4646,3 +4646,46 @@ ir.cpp:
|
||||||
|
|
||||||
# 1049| Block 2
|
# 1049| Block 2
|
||||||
# 1049| v2_0(void) = Unreached :
|
# 1049| v2_0(void) = Unreached :
|
||||||
|
|
||||||
|
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
|
||||||
|
# 1058| Block 0
|
||||||
|
# 1058| v0_0(void) = EnterFunction :
|
||||||
|
# 1058| m0_1(unknown) = AliasedDefinition :
|
||||||
|
# 1058| mu0_2(unknown) = UnmodeledDefinition :
|
||||||
|
# 1058| r0_3(glval<int>) = VariableAddress[n] :
|
||||||
|
# 1058| m0_4(int) = InitializeParameter[n] : r0_3
|
||||||
|
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
|
||||||
|
# 1058| m0_6(char *) = InitializeParameter[p] : r0_5
|
||||||
|
#-----| Goto -> Block 3
|
||||||
|
|
||||||
|
# 1060| Block 1
|
||||||
|
# 1060| r1_0(char) = Constant[0] :
|
||||||
|
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
|
||||||
|
# 1060| r1_2(char *) = Load : r1_1, m3_2
|
||||||
|
# 1060| r1_3(int) = Constant[1] :
|
||||||
|
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
|
||||||
|
# 1060| m1_5(char *) = Store : r1_1, r1_4
|
||||||
|
# 1060| m1_6(char) = Store : r1_2, r1_0
|
||||||
|
# 1060| m1_7(unknown) = Chi : m3_0, m1_6
|
||||||
|
#-----| Goto (back edge) -> Block 3
|
||||||
|
|
||||||
|
# 1061| Block 2
|
||||||
|
# 1061| v2_0(void) = NoOp :
|
||||||
|
# 1058| v2_1(void) = ReturnVoid :
|
||||||
|
# 1058| v2_2(void) = UnmodeledUse : mu*
|
||||||
|
# 1058| v2_3(void) = ExitFunction :
|
||||||
|
|
||||||
|
# 1059| Block 3
|
||||||
|
# 1059| m3_0(unknown) = Phi : from 0:m0_1, from 1:m1_7
|
||||||
|
# 1059| m3_1(int) = Phi : from 0:m0_4, from 1:m3_7
|
||||||
|
# 1059| m3_2(char *) = Phi : from 0:m0_6, from 1:m1_5
|
||||||
|
# 1059| r3_3(glval<int>) = VariableAddress[n] :
|
||||||
|
# 1059| r3_4(int) = Load : r3_3, m3_1
|
||||||
|
# 1059| r3_5(int) = Constant[1] :
|
||||||
|
# 1059| r3_6(int) = Sub : r3_4, r3_5
|
||||||
|
# 1059| m3_7(int) = Store : r3_3, r3_6
|
||||||
|
# 1059| r3_8(int) = Constant[0] :
|
||||||
|
# 1059| r3_9(bool) = CompareGT : r3_4, r3_8
|
||||||
|
# 1059| v3_10(void) = ConditionalBranch : r3_9
|
||||||
|
#-----| False (back edge) -> Block 2
|
||||||
|
#-----| True (back edge) -> Block 1
|
||||||
|
|
|
@ -8,4 +8,6 @@ operandAcrossFunctions
|
||||||
instructionWithoutUniqueBlock
|
instructionWithoutUniqueBlock
|
||||||
containsLoopOfForwardEdges
|
containsLoopOfForwardEdges
|
||||||
lostReachability
|
lostReachability
|
||||||
|
| ir.cpp:1060:12:1060:12 | Constant: (char)... |
|
||||||
|
| ir.cpp:1061:1:1061:1 | NoOp: return ... |
|
||||||
backEdgeCountMismatch
|
backEdgeCountMismatch
|
||||||
|
|
|
@ -1055,4 +1055,9 @@ int DoWhileFalse() {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void chiNodeAtEndOfLoop(int n, char *p) {
|
||||||
|
while (n-- > 0)
|
||||||
|
*p++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// semmle-extractor-options: -std=c++17
|
// semmle-extractor-options: -std=c++17
|
||||||
|
|
|
@ -4544,3 +4544,42 @@ ir.cpp:
|
||||||
# 1049| v2_5(void) = ReturnValue : r2_4, mu0_2
|
# 1049| v2_5(void) = ReturnValue : r2_4, mu0_2
|
||||||
# 1049| v2_6(void) = UnmodeledUse : mu*
|
# 1049| v2_6(void) = UnmodeledUse : mu*
|
||||||
# 1049| v2_7(void) = ExitFunction :
|
# 1049| v2_7(void) = ExitFunction :
|
||||||
|
|
||||||
|
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
|
||||||
|
# 1058| Block 0
|
||||||
|
# 1058| v0_0(void) = EnterFunction :
|
||||||
|
# 1058| mu0_1(unknown) = AliasedDefinition :
|
||||||
|
# 1058| mu0_2(unknown) = UnmodeledDefinition :
|
||||||
|
# 1058| r0_3(glval<int>) = VariableAddress[n] :
|
||||||
|
# 1058| mu0_4(int) = InitializeParameter[n] : r0_3
|
||||||
|
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
|
||||||
|
# 1058| mu0_6(char *) = InitializeParameter[p] : r0_5
|
||||||
|
#-----| Goto -> Block 3
|
||||||
|
|
||||||
|
# 1060| Block 1
|
||||||
|
# 1060| r1_0(char) = Constant[0] :
|
||||||
|
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
|
||||||
|
# 1060| r1_2(char *) = Load : r1_1, mu0_2
|
||||||
|
# 1060| r1_3(int) = Constant[1] :
|
||||||
|
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
|
||||||
|
# 1060| mu1_5(char *) = Store : r1_1, r1_4
|
||||||
|
# 1060| mu1_6(char) = Store : r1_2, r1_0
|
||||||
|
#-----| Goto (back edge) -> Block 3
|
||||||
|
|
||||||
|
# 1061| Block 2
|
||||||
|
# 1061| v2_0(void) = NoOp :
|
||||||
|
# 1058| v2_1(void) = ReturnVoid :
|
||||||
|
# 1058| v2_2(void) = UnmodeledUse : mu*
|
||||||
|
# 1058| v2_3(void) = ExitFunction :
|
||||||
|
|
||||||
|
# 1059| Block 3
|
||||||
|
# 1059| r3_0(glval<int>) = VariableAddress[n] :
|
||||||
|
# 1059| r3_1(int) = Load : r3_0, mu0_2
|
||||||
|
# 1059| r3_2(int) = Constant[1] :
|
||||||
|
# 1059| r3_3(int) = Sub : r3_1, r3_2
|
||||||
|
# 1059| mu3_4(int) = Store : r3_0, r3_3
|
||||||
|
# 1059| r3_5(int) = Constant[0] :
|
||||||
|
# 1059| r3_6(bool) = CompareGT : r3_1, r3_5
|
||||||
|
# 1059| v3_7(void) = ConditionalBranch : r3_6
|
||||||
|
#-----| False -> Block 2
|
||||||
|
#-----| True -> Block 1
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
| IR: VirtualMemberFunction | 1 |
|
| IR: VirtualMemberFunction | 1 |
|
||||||
| IR: WhileStatements | 4 |
|
| IR: WhileStatements | 4 |
|
||||||
| IR: WhileStmtWithDeclaration | 8 |
|
| IR: WhileStmtWithDeclaration | 8 |
|
||||||
|
| IR: chiNodeAtEndOfLoop | 4 |
|
||||||
| IR: designatedInit | 1 |
|
| IR: designatedInit | 1 |
|
||||||
| IR: min | 4 |
|
| IR: min | 4 |
|
||||||
| IR: operator= | 1 |
|
| IR: operator= | 1 |
|
||||||
|
|
|
@ -4517,3 +4517,44 @@ ir.cpp:
|
||||||
|
|
||||||
# 1049| Block 2
|
# 1049| Block 2
|
||||||
# 1049| v2_0(void) = Unreached :
|
# 1049| v2_0(void) = Unreached :
|
||||||
|
|
||||||
|
# 1058| chiNodeAtEndOfLoop(int, char *) -> void
|
||||||
|
# 1058| Block 0
|
||||||
|
# 1058| v0_0(void) = EnterFunction :
|
||||||
|
# 1058| mu0_1(unknown) = AliasedDefinition :
|
||||||
|
# 1058| mu0_2(unknown) = UnmodeledDefinition :
|
||||||
|
# 1058| r0_3(glval<int>) = VariableAddress[n] :
|
||||||
|
# 1058| m0_4(int) = InitializeParameter[n] : r0_3
|
||||||
|
# 1058| r0_5(glval<char *>) = VariableAddress[p] :
|
||||||
|
# 1058| m0_6(char *) = InitializeParameter[p] : r0_5
|
||||||
|
#-----| Goto -> Block 3
|
||||||
|
|
||||||
|
# 1060| Block 1
|
||||||
|
# 1060| r1_0(char) = Constant[0] :
|
||||||
|
# 1060| r1_1(glval<char *>) = VariableAddress[p] :
|
||||||
|
# 1060| r1_2(char *) = Load : r1_1, m3_1
|
||||||
|
# 1060| r1_3(int) = Constant[1] :
|
||||||
|
# 1060| r1_4(char *) = PointerAdd[1] : r1_2, r1_3
|
||||||
|
# 1060| m1_5(char *) = Store : r1_1, r1_4
|
||||||
|
# 1060| mu1_6(char) = Store : r1_2, r1_0
|
||||||
|
#-----| Goto (back edge) -> Block 3
|
||||||
|
|
||||||
|
# 1061| Block 2
|
||||||
|
# 1061| v2_0(void) = NoOp :
|
||||||
|
# 1058| v2_1(void) = ReturnVoid :
|
||||||
|
# 1058| v2_2(void) = UnmodeledUse : mu*
|
||||||
|
# 1058| v2_3(void) = ExitFunction :
|
||||||
|
|
||||||
|
# 1059| Block 3
|
||||||
|
# 1059| m3_0(int) = Phi : from 0:m0_4, from 1:m3_6
|
||||||
|
# 1059| m3_1(char *) = Phi : from 0:m0_6, from 1:m1_5
|
||||||
|
# 1059| r3_2(glval<int>) = VariableAddress[n] :
|
||||||
|
# 1059| r3_3(int) = Load : r3_2, m3_0
|
||||||
|
# 1059| r3_4(int) = Constant[1] :
|
||||||
|
# 1059| r3_5(int) = Sub : r3_3, r3_4
|
||||||
|
# 1059| m3_6(int) = Store : r3_2, r3_5
|
||||||
|
# 1059| r3_7(int) = Constant[0] :
|
||||||
|
# 1059| r3_8(bool) = CompareGT : r3_3, r3_7
|
||||||
|
# 1059| v3_9(void) = ConditionalBranch : r3_8
|
||||||
|
#-----| False -> Block 2
|
||||||
|
#-----| True -> Block 1
|
||||||
|
|
Загрузка…
Ссылка в новой задаче