mirror of
https://github.com/github/codeql.git
synced 2026-05-05 13:45:19 +02:00
Add working sign and modulus analysis
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import cpp
|
||||
import experimental.semmle.code.cpp.semantic.analysis.ModulusAnalysis
|
||||
import experimental.semmle.code.cpp.semantic.Semantic
|
||||
import semmle.code.cpp.ir.IR as IR
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class ModulusAnalysisTest extends InlineExpectationsTest {
|
||||
ModulusAnalysisTest() { this = "ModulusAnalysisTest" }
|
||||
|
||||
override string getARelevantTag() { result = "mod" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(SemExpr e, IR::CallInstruction call |
|
||||
call.getArgument(0) = e and
|
||||
call.getStaticCallTarget().hasName("mod") and
|
||||
tag = "mod" and
|
||||
element = e.toString() and
|
||||
location = e.getLocation() and
|
||||
value = getAModString(e)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private string getAModString(SemExpr e) {
|
||||
exists(SemBound b, int delta, int mod |
|
||||
semExprModulus(e, b, delta, mod) and
|
||||
result = b.toString() + "," + delta.toString() + "," + mod.toString() and
|
||||
not (delta = 0 and mod = 0)
|
||||
)
|
||||
}
|
||||
630
cpp/ql/test/library-tests/ir/modulus-analysis/PrintIR.expected
Normal file
630
cpp/ql/test/library-tests/ir/modulus-analysis/PrintIR.expected
Normal file
@@ -0,0 +1,630 @@
|
||||
test.cpp:
|
||||
# 6| void m(int, bool, int, int)
|
||||
# 6| Block 0
|
||||
# 6| v6_1(void) = EnterFunction :
|
||||
# 6| mod =
|
||||
# 6| m6_2(unknown) = AliasedDefinition :
|
||||
# 6| mod =
|
||||
# 6| m6_3(unknown) = InitializeNonLocal :
|
||||
# 6| mod =
|
||||
# 6| m6_4(unknown) = Chi : total:m6_2, partial:m6_3
|
||||
# 6| mod =
|
||||
# 6| r6_5(glval<int>) = VariableAddress[i] :
|
||||
# 6| mod =
|
||||
# 6| m6_6(int) = InitializeParameter[i] : &:r6_5
|
||||
# 6| mod = InitializeParameter: i 0 0 (getExpr)
|
||||
# 6| r6_7(glval<bool>) = VariableAddress[cond] :
|
||||
# 6| mod =
|
||||
# 6| m6_8(bool) = InitializeParameter[cond] : &:r6_7
|
||||
# 6| mod =
|
||||
# 6| r6_9(glval<int>) = VariableAddress[x] :
|
||||
# 6| mod =
|
||||
# 6| m6_10(int) = InitializeParameter[x] : &:r6_9
|
||||
# 6| mod = InitializeParameter: x 0 0 (getExpr)
|
||||
# 6| r6_11(glval<int>) = VariableAddress[y] :
|
||||
# 6| mod =
|
||||
# 6| m6_12(int) = InitializeParameter[y] : &:r6_11
|
||||
# 6| mod = InitializeParameter: y 0 0 (getExpr)
|
||||
# 7| r7_1(glval<int>) = VariableAddress[eq] :
|
||||
# 7| mod =
|
||||
# 7| r7_2(glval<int>) = VariableAddress[i] :
|
||||
# 7| mod =
|
||||
# 7| r7_3(int) = Load[i] : &:r7_2, m6_6
|
||||
# 7| mod = InitializeParameter: i 0 0 (getExpr, use)
|
||||
# 7| r7_4(int) = Constant[3] :
|
||||
# 7| mod = 0 3 0 (getExpr)
|
||||
# 7| r7_5(int) = Add : r7_3, r7_4
|
||||
# 7| mod = InitializeParameter: i 3 0 (valueFlowStep), Store: ... + ... 0 0 (getExpr)
|
||||
# 7| m7_6(int) = Store[eq] : &:r7_1, r7_5
|
||||
# 7| mod = InitializeParameter: i 3 0 (valueFlowStep), Store: ... + ... 0 0 (getExpr, valueFlowStep)
|
||||
# 9| r9_1(glval<int>) = VariableAddress[mul] :
|
||||
# 9| mod =
|
||||
# 9| r9_2(glval<int>) = VariableAddress[eq] :
|
||||
# 9| mod =
|
||||
# 9| r9_3(int) = Load[eq] : &:r9_2, m7_6
|
||||
# 9| mod = InitializeParameter: i 3 0 (use), Store: ... + ... 0 0 (getExpr, use)
|
||||
# 9| r9_4(glval<int>) = Constant[42] :
|
||||
# 9| mod = 0 42 0 (getExpr)
|
||||
# 9| r9_5(int) = Load[?] : &:r9_4, ~m6_4
|
||||
# 9| mod =
|
||||
# 9| r9_6(int) = Mul : r9_3, r9_5
|
||||
# 9| mod =
|
||||
# 9| r9_7(int) = Constant[3] :
|
||||
# 9| mod = 0 3 0 (getExpr)
|
||||
# 9| r9_8(int) = Add : r9_6, r9_7
|
||||
# 9| mod = Store: ... + ... 0 0 (getExpr)
|
||||
# 9| m9_9(int) = Store[mul] : &:r9_1, r9_8
|
||||
# 9| mod = Store: ... + ... 0 0 (getExpr, valueFlowStep)
|
||||
# 11| r11_1(glval<int>) = VariableAddress[seven] :
|
||||
# 11| mod =
|
||||
# 11| r11_2(int) = Constant[7] :
|
||||
# 11| mod = 0 7 0 (getExpr)
|
||||
# 11| m11_3(int) = Store[seven] : &:r11_1, r11_2
|
||||
# 11| mod = 0 7 0 (valueFlowStep)
|
||||
# 12| r12_1(glval<int>) = VariableAddress[mul] :
|
||||
# 12| mod =
|
||||
# 12| r12_2(int) = Load[mul] : &:r12_1, m9_9
|
||||
# 12| mod = Store: ... + ... 0 0 (getExpr, use)
|
||||
# 12| r12_3(glval<int>) = Constant[43] :
|
||||
# 12| mod = 0 43 0 (getExpr)
|
||||
# 12| r12_4(int) = Load[?] : &:r12_3, ~m6_4
|
||||
# 12| mod =
|
||||
# 12| r12_5(int) = Rem : r12_2, r12_4
|
||||
# 12| mod =
|
||||
# 12| r12_6(glval<int>) = VariableAddress[seven] :
|
||||
# 12| mod =
|
||||
# 12| r12_7(int) = Load[seven] : &:r12_6, m11_3
|
||||
# 12| mod = 0 7 0 (use)
|
||||
# 12| r12_8(bool) = CompareEQ : r12_5, r12_7
|
||||
# 12| mod =
|
||||
# 12| v12_9(void) = ConditionalBranch : r12_8
|
||||
# 12| mod =
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 13| Block 1
|
||||
# 13| r13_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 13| mod =
|
||||
# 13| r13_2(glval<int>) = VariableAddress[mul] :
|
||||
# 13| mod =
|
||||
# 13| r13_3(int) = Load[mul] : &:r13_2, m9_9
|
||||
# 13| mod = Store: ... + ... 0 0 (getExpr, use)
|
||||
# 13| v13_4(void) = Call[mod] : func:r13_1, 0:r13_3
|
||||
# 13| mod =
|
||||
# 13| m13_5(unknown) = ^CallSideEffect : ~m6_4
|
||||
# 13| mod =
|
||||
# 13| m13_6(unknown) = Chi : total:m6_4, partial:m13_5
|
||||
# 13| mod =
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 16| Block 2
|
||||
# 16| m16_1(unknown) = Phi : from 0:~m6_4, from 1:~m13_6
|
||||
# 16| mod =
|
||||
# 16| r16_2(glval<int>) = VariableAddress[j] :
|
||||
# 16| mod =
|
||||
# 16| r16_3(glval<bool>) = VariableAddress[cond] :
|
||||
# 16| mod =
|
||||
# 16| r16_4(bool) = Load[cond] : &:r16_3, m6_8
|
||||
# 16| mod =
|
||||
# 16| v16_5(void) = ConditionalBranch : r16_4
|
||||
# 16| mod =
|
||||
#-----| False -> Block 5
|
||||
#-----| True -> Block 4
|
||||
|
||||
# 16| Block 3
|
||||
# 16| m16_6(int) = Phi : from 4:m16_11, from 5:m16_13
|
||||
# 16| mod = Phi: ... ? ... : ... 0 0 (getExpr)
|
||||
# 16| r16_7(glval<int>) = VariableAddress[#temp16:13] :
|
||||
# 16| mod =
|
||||
# 16| r16_8(int) = Load[#temp16:13] : &:r16_7, m16_6
|
||||
# 16| mod = 0 3 4 (use), Phi: ... ? ... : ... 0 0 (getExpr, use)
|
||||
# 16| m16_9(int) = Store[j] : &:r16_2, r16_8
|
||||
# 16| mod = 0 3 4 (valueFlowStep), Phi: ... ? ... : ... 0 0 (getExpr, valueFlowStep)
|
||||
# 19| r19_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 19| mod =
|
||||
# 19| r19_2(glval<int>) = VariableAddress[j] :
|
||||
# 19| mod =
|
||||
# 19| r19_3(int) = Load[j] : &:r19_2, m16_9
|
||||
# 19| mod = 0 3 4 (use), Phi: ... ? ... : ... 0 0 (getExpr, use)
|
||||
# 19| v19_4(void) = Call[mod] : func:r19_1, 0:r19_3
|
||||
# 19| mod =
|
||||
# 19| m19_5(unknown) = ^CallSideEffect : ~m16_1
|
||||
# 19| mod =
|
||||
# 19| m19_6(unknown) = Chi : total:m16_1, partial:m19_5
|
||||
# 19| mod =
|
||||
# 21| r21_1(glval<int>) = VariableAddress[x] :
|
||||
# 21| mod =
|
||||
# 21| r21_2(int) = Load[x] : &:r21_1, m6_10
|
||||
# 21| mod = InitializeParameter: x 0 0 (getExpr, use)
|
||||
# 21| r21_3(glval<int>) = Constant[42] :
|
||||
# 21| mod = 0 42 0 (getExpr)
|
||||
# 21| r21_4(int) = Load[?] : &:r21_3, ~m19_6
|
||||
# 21| mod =
|
||||
# 21| r21_5(int) = Rem : r21_2, r21_4
|
||||
# 21| mod =
|
||||
# 21| r21_6(int) = Constant[3] :
|
||||
# 21| mod = 0 3 0 (getExpr)
|
||||
# 21| r21_7(bool) = CompareEQ : r21_5, r21_6
|
||||
# 21| mod =
|
||||
# 21| v21_8(void) = ConditionalBranch : r21_7
|
||||
# 21| mod =
|
||||
#-----| False -> Block 8
|
||||
#-----| True -> Block 6
|
||||
|
||||
# 17| Block 4
|
||||
# 17| r17_1(glval<int>) = VariableAddress[i] :
|
||||
# 17| mod =
|
||||
# 17| r17_2(int) = Load[i] : &:r17_1, m6_6
|
||||
# 17| mod = InitializeParameter: i 0 0 (getExpr, use)
|
||||
# 17| r17_3(int) = Constant[4] :
|
||||
# 17| mod = 0 4 0 (getExpr)
|
||||
# 17| r17_4(int) = Mul : r17_2, r17_3
|
||||
# 17| mod = 0 0 4 (evenlyDivisible)
|
||||
# 17| r17_5(int) = Constant[3] :
|
||||
# 17| mod = 0 3 0 (getExpr)
|
||||
# 17| r17_6(int) = Add : r17_4, r17_5
|
||||
# 17| mod = 0 3 4 (valueFlowStep)
|
||||
# 16| r16_10(glval<int>) = VariableAddress[#temp16:13] :
|
||||
# 16| mod =
|
||||
# 16| m16_11(int) = Store[#temp16:13] : &:r16_10, r17_6
|
||||
# 16| mod = 0 3 4 (valueFlowStep)
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 18| Block 5
|
||||
# 18| r18_1(glval<int>) = VariableAddress[i] :
|
||||
# 18| mod =
|
||||
# 18| r18_2(int) = Load[i] : &:r18_1, m6_6
|
||||
# 18| mod = InitializeParameter: i 0 0 (getExpr, use)
|
||||
# 18| r18_3(int) = Constant[8] :
|
||||
# 18| mod = 0 8 0 (getExpr)
|
||||
# 18| r18_4(int) = Mul : r18_2, r18_3
|
||||
# 18| mod = 0 0 8 (evenlyDivisible)
|
||||
# 18| r18_5(int) = Constant[7] :
|
||||
# 18| mod = 0 7 0 (getExpr)
|
||||
# 18| r18_6(int) = Add : r18_4, r18_5
|
||||
# 18| mod = 0 7 8 (valueFlowStep)
|
||||
# 16| r16_12(glval<int>) = VariableAddress[#temp16:13] :
|
||||
# 16| mod =
|
||||
# 16| m16_13(int) = Store[#temp16:13] : &:r16_12, r18_6
|
||||
# 16| mod = 0 7 8 (valueFlowStep)
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 21| Block 6
|
||||
# 21| r21_9(glval<int>) = VariableAddress[y] :
|
||||
# 21| mod =
|
||||
# 21| r21_10(int) = Load[y] : &:r21_9, m6_12
|
||||
# 21| mod = InitializeParameter: y 0 0 (getExpr, use)
|
||||
# 21| r21_11(glval<int>) = Constant[42] :
|
||||
# 21| mod = 0 42 0 (getExpr)
|
||||
# 21| r21_12(int) = Load[?] : &:r21_11, ~m19_6
|
||||
# 21| mod =
|
||||
# 21| r21_13(int) = Rem : r21_10, r21_12
|
||||
# 21| mod =
|
||||
# 21| r21_14(int) = Constant[7] :
|
||||
# 21| mod = 0 7 0 (getExpr)
|
||||
# 21| r21_15(bool) = CompareEQ : r21_13, r21_14
|
||||
# 21| mod =
|
||||
# 21| v21_16(void) = ConditionalBranch : r21_15
|
||||
# 21| mod =
|
||||
#-----| False -> Block 8
|
||||
#-----| True -> Block 7
|
||||
|
||||
# 23| Block 7
|
||||
# 23| r23_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 23| mod =
|
||||
# 23| r23_2(glval<int>) = VariableAddress[x] :
|
||||
# 23| mod =
|
||||
# 23| r23_3(int) = Load[x] : &:r23_2, m6_10
|
||||
# 23| mod = InitializeParameter: x 0 0 (getExpr, use)
|
||||
# 23| r23_4(glval<int>) = VariableAddress[y] :
|
||||
# 23| mod =
|
||||
# 23| r23_5(int) = Load[y] : &:r23_4, m6_12
|
||||
# 23| mod = InitializeParameter: y 0 0 (getExpr, use)
|
||||
# 23| r23_6(int) = Add : r23_3, r23_5
|
||||
# 23| mod =
|
||||
# 23| v23_7(void) = Call[mod] : func:r23_1, 0:r23_6
|
||||
# 23| mod =
|
||||
# 23| m23_8(unknown) = ^CallSideEffect : ~m19_6
|
||||
# 23| mod =
|
||||
# 23| m23_9(unknown) = Chi : total:m19_6, partial:m23_8
|
||||
# 23| mod =
|
||||
#-----| Goto -> Block 8
|
||||
|
||||
# 26| Block 8
|
||||
# 26| m26_1(unknown) = Phi : from 3:~m19_6, from 6:~m19_6, from 7:~m23_9
|
||||
# 26| mod =
|
||||
# 26| r26_2(glval<int>) = VariableAddress[x] :
|
||||
# 26| mod =
|
||||
# 26| r26_3(int) = Load[x] : &:r26_2, m6_10
|
||||
# 26| mod = InitializeParameter: x 0 0 (getExpr, use)
|
||||
# 26| r26_4(glval<int>) = Constant[42] :
|
||||
# 26| mod = 0 42 0 (getExpr)
|
||||
# 26| r26_5(int) = Load[?] : &:r26_4, ~m26_1
|
||||
# 26| mod =
|
||||
# 26| r26_6(int) = Rem : r26_3, r26_5
|
||||
# 26| mod =
|
||||
# 26| r26_7(int) = Constant[3] :
|
||||
# 26| mod = 0 3 0 (getExpr)
|
||||
# 26| r26_8(bool) = CompareEQ : r26_6, r26_7
|
||||
# 26| mod =
|
||||
# 26| v26_9(void) = ConditionalBranch : r26_8
|
||||
# 26| mod =
|
||||
#-----| False -> Block 11
|
||||
#-----| True -> Block 9
|
||||
|
||||
# 26| Block 9
|
||||
# 26| r26_10(glval<int>) = VariableAddress[y] :
|
||||
# 26| mod =
|
||||
# 26| r26_11(int) = Load[y] : &:r26_10, m6_12
|
||||
# 26| mod = InitializeParameter: y 0 0 (getExpr, use)
|
||||
# 26| r26_12(glval<int>) = Constant[42] :
|
||||
# 26| mod = 0 42 0 (getExpr)
|
||||
# 26| r26_13(int) = Load[?] : &:r26_12, ~m26_1
|
||||
# 26| mod =
|
||||
# 26| r26_14(int) = Rem : r26_11, r26_13
|
||||
# 26| mod =
|
||||
# 26| r26_15(int) = Constant[7] :
|
||||
# 26| mod = 0 7 0 (getExpr)
|
||||
# 26| r26_16(bool) = CompareEQ : r26_14, r26_15
|
||||
# 26| mod =
|
||||
# 26| v26_17(void) = ConditionalBranch : r26_16
|
||||
# 26| mod =
|
||||
#-----| False -> Block 11
|
||||
#-----| True -> Block 10
|
||||
|
||||
# 28| Block 10
|
||||
# 28| r28_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 28| mod =
|
||||
# 28| r28_2(glval<int>) = VariableAddress[x] :
|
||||
# 28| mod =
|
||||
# 28| r28_3(int) = Load[x] : &:r28_2, m6_10
|
||||
# 28| mod = InitializeParameter: x 0 0 (getExpr, use)
|
||||
# 28| r28_4(glval<int>) = VariableAddress[y] :
|
||||
# 28| mod =
|
||||
# 28| r28_5(int) = Load[y] : &:r28_4, m6_12
|
||||
# 28| mod = InitializeParameter: y 0 0 (getExpr, use)
|
||||
# 28| r28_6(int) = Sub : r28_3, r28_5
|
||||
# 28| mod =
|
||||
# 28| v28_7(void) = Call[mod] : func:r28_1, 0:r28_6
|
||||
# 28| mod =
|
||||
# 28| m28_8(unknown) = ^CallSideEffect : ~m26_1
|
||||
# 28| mod =
|
||||
# 28| m28_9(unknown) = Chi : total:m26_1, partial:m28_8
|
||||
# 28| mod =
|
||||
#-----| Goto -> Block 11
|
||||
|
||||
# 31| Block 11
|
||||
# 31| m31_1(unknown) = Phi : from 8:~m26_1, from 9:~m26_1, from 10:~m28_9
|
||||
# 31| mod =
|
||||
# 31| r31_2(glval<bool>) = VariableAddress[cond] :
|
||||
# 31| mod =
|
||||
# 31| r31_3(bool) = Load[cond] : &:r31_2, m6_8
|
||||
# 31| mod =
|
||||
# 31| v31_4(void) = ConditionalBranch : r31_3
|
||||
# 31| mod =
|
||||
#-----| False -> Block 13
|
||||
#-----| True -> Block 12
|
||||
|
||||
# 32| Block 12
|
||||
# 32| r32_1(glval<int>) = VariableAddress[i] :
|
||||
# 32| mod =
|
||||
# 32| r32_2(int) = Load[i] : &:r32_1, m6_6
|
||||
# 32| mod = InitializeParameter: i 0 0 (getExpr, use)
|
||||
# 32| r32_3(int) = Constant[4] :
|
||||
# 32| mod = 0 4 0 (getExpr)
|
||||
# 32| r32_4(int) = Mul : r32_2, r32_3
|
||||
# 32| mod = 0 0 4 (evenlyDivisible)
|
||||
# 32| r32_5(int) = Constant[3] :
|
||||
# 32| mod = 0 3 0 (getExpr)
|
||||
# 32| r32_6(int) = Add : r32_4, r32_5
|
||||
# 32| mod = 0 3 4 (valueFlowStep)
|
||||
# 32| r32_7(glval<int>) = VariableAddress[j] :
|
||||
# 32| mod =
|
||||
# 32| m32_8(int) = Store[j] : &:r32_7, r32_6
|
||||
# 32| mod = 0 3 4 (valueFlowStep)
|
||||
#-----| Goto -> Block 14
|
||||
|
||||
# 35| Block 13
|
||||
# 35| r35_1(glval<int>) = VariableAddress[i] :
|
||||
# 35| mod =
|
||||
# 35| r35_2(int) = Load[i] : &:r35_1, m6_6
|
||||
# 35| mod = InitializeParameter: i 0 0 (getExpr, use)
|
||||
# 35| r35_3(int) = Constant[8] :
|
||||
# 35| mod = 0 8 0 (getExpr)
|
||||
# 35| r35_4(int) = Mul : r35_2, r35_3
|
||||
# 35| mod = 0 0 8 (evenlyDivisible)
|
||||
# 35| r35_5(int) = Constant[7] :
|
||||
# 35| mod = 0 7 0 (getExpr)
|
||||
# 35| r35_6(int) = Add : r35_4, r35_5
|
||||
# 35| mod = 0 7 8 (valueFlowStep)
|
||||
# 35| r35_7(glval<int>) = VariableAddress[j] :
|
||||
# 35| mod =
|
||||
# 35| m35_8(int) = Store[j] : &:r35_7, r35_6
|
||||
# 35| mod = 0 7 8 (valueFlowStep)
|
||||
#-----| Goto -> Block 14
|
||||
|
||||
# 37| Block 14
|
||||
# 37| m37_1(int) = Phi : from 12:m32_8, from 13:m35_8
|
||||
# 37| mod = Phi: call to mod 0 0 (getExpr)
|
||||
# 37| r37_2(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 37| mod =
|
||||
# 37| r37_3(glval<int>) = VariableAddress[j] :
|
||||
# 37| mod =
|
||||
# 37| r37_4(int) = Load[j] : &:r37_3, m37_1
|
||||
# 37| mod = 0 3 4 (use), Phi: call to mod 0 0 (getExpr, use)
|
||||
# 37| v37_5(void) = Call[mod] : func:r37_2, 0:r37_4
|
||||
# 37| mod =
|
||||
# 37| m37_6(unknown) = ^CallSideEffect : ~m31_1
|
||||
# 37| mod =
|
||||
# 37| m37_7(unknown) = Chi : total:m31_1, partial:m37_6
|
||||
# 37| mod =
|
||||
# 39| r39_1(glval<bool>) = VariableAddress[cond] :
|
||||
# 39| mod =
|
||||
# 39| r39_2(bool) = Load[cond] : &:r39_1, m6_8
|
||||
# 39| mod =
|
||||
# 39| v39_3(void) = ConditionalBranch : r39_2
|
||||
# 39| mod =
|
||||
#-----| False -> Block 16
|
||||
#-----| True -> Block 15
|
||||
|
||||
# 40| Block 15
|
||||
# 40| r40_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 40| mod =
|
||||
# 40| r40_2(glval<int>) = VariableAddress[j] :
|
||||
# 40| mod =
|
||||
# 40| r40_3(int) = Load[j] : &:r40_2, m37_1
|
||||
# 40| mod = 0 3 4 (use), Phi: call to mod 0 0 (getExpr, use)
|
||||
# 40| v40_4(void) = Call[mod] : func:r40_1, 0:r40_3
|
||||
# 40| mod =
|
||||
# 40| m40_5(unknown) = ^CallSideEffect : ~m37_7
|
||||
# 40| mod =
|
||||
# 40| m40_6(unknown) = Chi : total:m37_7, partial:m40_5
|
||||
# 40| mod =
|
||||
#-----| Goto -> Block 17
|
||||
|
||||
# 42| Block 16
|
||||
# 42| r42_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 42| mod =
|
||||
# 42| r42_2(glval<int>) = VariableAddress[j] :
|
||||
# 42| mod =
|
||||
# 42| r42_3(int) = Load[j] : &:r42_2, m37_1
|
||||
# 42| mod = 0 3 4 (use), Phi: call to mod 0 0 (getExpr, use)
|
||||
# 42| v42_4(void) = Call[mod] : func:r42_1, 0:r42_3
|
||||
# 42| mod =
|
||||
# 42| m42_5(unknown) = ^CallSideEffect : ~m37_7
|
||||
# 42| mod =
|
||||
# 42| m42_6(unknown) = Chi : total:m37_7, partial:m42_5
|
||||
# 42| mod =
|
||||
#-----| Goto -> Block 17
|
||||
|
||||
# 45| Block 17
|
||||
# 45| m45_1(unknown) = Phi : from 15:~m40_6, from 16:~m42_6
|
||||
# 45| mod =
|
||||
# 45| r45_2(glval<int>) = VariableAddress[x] :
|
||||
# 45| mod =
|
||||
# 45| r45_3(int) = Load[x] : &:r45_2, m6_10
|
||||
# 45| mod = InitializeParameter: x 0 0 (getExpr, use)
|
||||
# 45| r45_4(int) = Constant[15] :
|
||||
# 45| mod = 0 15 0 (getExpr)
|
||||
# 45| r45_5(int) = BitAnd : r45_3, r45_4
|
||||
# 45| mod =
|
||||
# 45| r45_6(int) = Constant[3] :
|
||||
# 45| mod = 0 3 0 (getExpr)
|
||||
# 45| r45_7(bool) = CompareEQ : r45_5, r45_6
|
||||
# 45| mod =
|
||||
# 45| v45_8(void) = ConditionalBranch : r45_7
|
||||
# 45| mod =
|
||||
#-----| False -> Block 19
|
||||
#-----| True -> Block 18
|
||||
|
||||
# 46| Block 18
|
||||
# 46| r46_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 46| mod =
|
||||
# 46| r46_2(glval<int>) = VariableAddress[x] :
|
||||
# 46| mod =
|
||||
# 46| r46_3(int) = Load[x] : &:r46_2, m6_10
|
||||
# 46| mod = 0 3 16 (use), InitializeParameter: x 0 0 (getExpr, use)
|
||||
# 46| v46_4(void) = Call[mod] : func:r46_1, 0:r46_3
|
||||
# 46| mod =
|
||||
# 46| m46_5(unknown) = ^CallSideEffect : ~m45_1
|
||||
# 46| mod =
|
||||
# 46| m46_6(unknown) = Chi : total:m45_1, partial:m46_5
|
||||
# 46| mod =
|
||||
#-----| Goto -> Block 19
|
||||
|
||||
# 48| Block 19
|
||||
# 48| m48_1(unknown) = Phi : from 17:~m45_1, from 18:~m46_6
|
||||
# 48| mod =
|
||||
# 48| v48_2(void) = NoOp :
|
||||
# 48| mod =
|
||||
# 6| v6_13(void) = ReturnVoid :
|
||||
# 6| mod =
|
||||
# 6| v6_14(void) = AliasedUse : ~m48_1
|
||||
# 6| mod =
|
||||
# 6| v6_15(void) = ExitFunction :
|
||||
# 6| mod =
|
||||
|
||||
# 50| void loops(int)
|
||||
# 50| Block 0
|
||||
# 50| v50_1(void) = EnterFunction :
|
||||
# 50| mod =
|
||||
# 50| m50_2(unknown) = AliasedDefinition :
|
||||
# 50| mod =
|
||||
# 50| m50_3(unknown) = InitializeNonLocal :
|
||||
# 50| mod =
|
||||
# 50| m50_4(unknown) = Chi : total:m50_2, partial:m50_3
|
||||
# 50| mod =
|
||||
# 50| r50_5(glval<int>) = VariableAddress[cap] :
|
||||
# 50| mod =
|
||||
# 50| m50_6(int) = InitializeParameter[cap] : &:r50_5
|
||||
# 50| mod = InitializeParameter: cap 0 0 (getExpr)
|
||||
# 52| r52_1(glval<int>) = VariableAddress[i] :
|
||||
# 52| mod =
|
||||
# 52| r52_2(int) = Constant[0] :
|
||||
# 52| mod = 0 0 0 (getExpr)
|
||||
# 52| m52_3(int) = Store[i] : &:r52_1, r52_2
|
||||
# 52| mod = 0 0 0 (valueFlowStep)
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 52| Block 1
|
||||
# 52| m52_4(unknown) = Phi : from 0:~m50_4, from 2:~m53_6
|
||||
# 52| mod =
|
||||
# 52| m52_5(int) = Phi : from 0:m52_3, from 2:m52_16
|
||||
# 52| mod = Phi: i 0 0 (getExpr)
|
||||
# 52| r52_6(glval<int>) = VariableAddress[i] :
|
||||
# 52| mod =
|
||||
# 52| r52_7(int) = Load[i] : &:r52_6, m52_5
|
||||
# 52| mod = Phi: i 0 0 (getExpr, use)
|
||||
# 52| r52_8(glval<int>) = VariableAddress[cap] :
|
||||
# 52| mod =
|
||||
# 52| r52_9(int) = Load[cap] : &:r52_8, m50_6
|
||||
# 52| mod = InitializeParameter: cap 0 0 (getExpr, use)
|
||||
# 52| r52_10(bool) = CompareLT : r52_7, r52_9
|
||||
# 52| mod =
|
||||
# 52| v52_11(void) = ConditionalBranch : r52_10
|
||||
# 52| mod =
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 53| Block 2
|
||||
# 53| r53_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 53| mod =
|
||||
# 53| r53_2(glval<int>) = VariableAddress[i] :
|
||||
# 53| mod =
|
||||
# 53| r53_3(int) = Load[i] : &:r53_2, m52_5
|
||||
# 53| mod = Phi: i 0 0 (getExpr, use)
|
||||
# 53| v53_4(void) = Call[mod] : func:r53_1, 0:r53_3
|
||||
# 53| mod =
|
||||
# 53| m53_5(unknown) = ^CallSideEffect : ~m52_4
|
||||
# 53| mod =
|
||||
# 53| m53_6(unknown) = Chi : total:m52_4, partial:m53_5
|
||||
# 53| mod =
|
||||
# 52| r52_12(glval<int>) = VariableAddress[i] :
|
||||
# 52| mod =
|
||||
# 52| r52_13(int) = Load[i] : &:r52_12, m52_5
|
||||
# 52| mod = Phi: i 0 0 (getExpr, use)
|
||||
# 52| r52_14(int) = Constant[1] :
|
||||
# 52| mod = 0 1 0 (getExpr)
|
||||
# 52| r52_15(int) = Add : r52_13, r52_14
|
||||
# 52| mod = Phi: i 1 0 (valueFlowStep)
|
||||
# 52| m52_16(int) = Store[i] : &:r52_12, r52_15
|
||||
# 52| mod = Phi: i 1 0 (valueFlowStep)
|
||||
#-----| Goto (back edge) -> Block 1
|
||||
|
||||
# 55| Block 3
|
||||
# 55| r55_1(glval<int>) = VariableAddress[j] :
|
||||
# 55| mod =
|
||||
# 55| r55_2(int) = Constant[0] :
|
||||
# 55| mod = 0 0 0 (getExpr)
|
||||
# 55| m55_3(int) = Store[j] : &:r55_1, r55_2
|
||||
# 55| mod = 0 0 0 (valueFlowStep)
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 55| Block 4
|
||||
# 55| m55_4(unknown) = Phi : from 3:~m52_4, from 5:~m56_6
|
||||
# 55| mod =
|
||||
# 55| m55_5(int) = Phi : from 3:m55_3, from 5:m55_16
|
||||
# 55| mod = Phi: j 0 0 (getExpr)
|
||||
# 55| r55_6(glval<int>) = VariableAddress[j] :
|
||||
# 55| mod =
|
||||
# 55| r55_7(int) = Load[j] : &:r55_6, m55_5
|
||||
# 55| mod = Phi: j 0 0 (getExpr, use)
|
||||
# 55| r55_8(glval<int>) = VariableAddress[cap] :
|
||||
# 55| mod =
|
||||
# 55| r55_9(int) = Load[cap] : &:r55_8, m50_6
|
||||
# 55| mod = InitializeParameter: cap 0 0 (getExpr, use)
|
||||
# 55| r55_10(bool) = CompareLT : r55_7, r55_9
|
||||
# 55| mod =
|
||||
# 55| v55_11(void) = ConditionalBranch : r55_10
|
||||
# 55| mod =
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 56| Block 5
|
||||
# 56| r56_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 56| mod =
|
||||
# 56| r56_2(glval<int>) = VariableAddress[j] :
|
||||
# 56| mod =
|
||||
# 56| r56_3(int) = Load[j] : &:r56_2, m55_5
|
||||
# 56| mod = Phi: j 0 0 (getExpr, use)
|
||||
# 56| v56_4(void) = Call[mod] : func:r56_1, 0:r56_3
|
||||
# 56| mod =
|
||||
# 56| m56_5(unknown) = ^CallSideEffect : ~m55_4
|
||||
# 56| mod =
|
||||
# 56| m56_6(unknown) = Chi : total:m55_4, partial:m56_5
|
||||
# 56| mod =
|
||||
# 55| r55_12(int) = Constant[1] :
|
||||
# 55| mod = 0 1 0 (getExpr)
|
||||
# 55| r55_13(glval<int>) = VariableAddress[j] :
|
||||
# 55| mod =
|
||||
# 55| r55_14(int) = Load[j] : &:r55_13, m55_5
|
||||
# 55| mod = Phi: j 0 0 (getExpr, use)
|
||||
# 55| r55_15(int) = Add : r55_14, r55_12
|
||||
# 55| mod = Phi: j 1 0 (valueFlowStep)
|
||||
# 55| m55_16(int) = Store[j] : &:r55_13, r55_15
|
||||
# 55| mod = Phi: j 1 0 (valueFlowStep)
|
||||
#-----| Goto (back edge) -> Block 4
|
||||
|
||||
# 58| Block 6
|
||||
# 58| r58_1(glval<int>) = VariableAddress[k] :
|
||||
# 58| mod =
|
||||
# 58| r58_2(int) = Constant[0] :
|
||||
# 58| mod = 0 0 0 (getExpr)
|
||||
# 58| m58_3(int) = Store[k] : &:r58_1, r58_2
|
||||
# 58| mod = 0 0 0 (valueFlowStep)
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 58| Block 7
|
||||
# 58| m58_4(unknown) = Phi : from 6:~m55_4, from 8:~m59_6
|
||||
# 58| mod =
|
||||
# 58| m58_5(int) = Phi : from 6:m58_3, from 8:m58_16
|
||||
# 58| mod = Phi: k 0 0 (getExpr)
|
||||
# 58| r58_6(glval<int>) = VariableAddress[k] :
|
||||
# 58| mod =
|
||||
# 58| r58_7(int) = Load[k] : &:r58_6, m58_5
|
||||
# 58| mod = 0 0 3 (use), Phi: k 0 0 (getExpr, use)
|
||||
# 58| r58_8(glval<int>) = VariableAddress[cap] :
|
||||
# 58| mod =
|
||||
# 58| r58_9(int) = Load[cap] : &:r58_8, m50_6
|
||||
# 58| mod = InitializeParameter: cap 0 0 (getExpr, use)
|
||||
# 58| r58_10(bool) = CompareLT : r58_7, r58_9
|
||||
# 58| mod =
|
||||
# 58| v58_11(void) = ConditionalBranch : r58_10
|
||||
# 58| mod =
|
||||
#-----| False -> Block 9
|
||||
#-----| True -> Block 8
|
||||
|
||||
# 59| Block 8
|
||||
# 59| r59_1(glval<unknown>) = FunctionAddress[mod] :
|
||||
# 59| mod =
|
||||
# 59| r59_2(glval<int>) = VariableAddress[k] :
|
||||
# 59| mod =
|
||||
# 59| r59_3(int) = Load[k] : &:r59_2, m58_5
|
||||
# 59| mod = 0 0 3 (use), Phi: k 0 0 (getExpr, use)
|
||||
# 59| v59_4(void) = Call[mod] : func:r59_1, 0:r59_3
|
||||
# 59| mod =
|
||||
# 59| m59_5(unknown) = ^CallSideEffect : ~m58_4
|
||||
# 59| mod =
|
||||
# 59| m59_6(unknown) = Chi : total:m58_4, partial:m59_5
|
||||
# 59| mod =
|
||||
# 58| r58_12(int) = Constant[3] :
|
||||
# 58| mod = 0 3 0 (getExpr)
|
||||
# 58| r58_13(glval<int>) = VariableAddress[k] :
|
||||
# 58| mod =
|
||||
# 58| r58_14(int) = Load[k] : &:r58_13, m58_5
|
||||
# 58| mod = 0 0 3 (use), Phi: k 0 0 (getExpr, use)
|
||||
# 58| r58_15(int) = Add : r58_14, r58_12
|
||||
# 58| mod = 0 0 3 (valueFlowStep), Phi: k 3 0 (valueFlowStep)
|
||||
# 58| m58_16(int) = Store[k] : &:r58_13, r58_15
|
||||
# 58| mod = 0 0 3 (valueFlowStep), Phi: k 3 0 (valueFlowStep)
|
||||
#-----| Goto (back edge) -> Block 7
|
||||
|
||||
# 60| Block 9
|
||||
# 60| v60_1(void) = NoOp :
|
||||
# 60| mod =
|
||||
# 50| v50_7(void) = ReturnVoid :
|
||||
# 50| mod =
|
||||
# 50| v50_8(void) = AliasedUse : ~m58_4
|
||||
# 50| mod =
|
||||
# 50| v50_9(void) = ExitFunction :
|
||||
# 50| mod =
|
||||
30
cpp/ql/test/library-tests/ir/modulus-analysis/PrintIR.ql
Normal file
30
cpp/ql/test/library-tests/ir/modulus-analysis/PrintIR.ql
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.ir.PrintIR
|
||||
import semmle.code.cpp.ir.IR as IR
|
||||
import experimental.semmle.code.cpp.semantic.analysis.ModulusAnalysis
|
||||
import experimental.semmle.code.cpp.semantic.analysis.ConstantAnalysis
|
||||
import experimental.semmle.code.cpp.semantic.Semantic
|
||||
|
||||
class ModulusProvider extends IR::IRPropertyProvider {
|
||||
override string getInstructionProperty(IR::Instruction instruction, string key) {
|
||||
key = "mod" and
|
||||
result =
|
||||
concat(string modString |
|
||||
exists(SemBound b, int delta, int mod, string branches |
|
||||
branches =
|
||||
strictconcat(string branch |
|
||||
semExprModulus(instruction, b, delta, mod, branch)
|
||||
|
|
||||
branch, ", "
|
||||
) and
|
||||
modString =
|
||||
b.toString() + " " + delta.toString() + " " + mod.toString() + " (" + branches + ")"
|
||||
)
|
||||
|
|
||||
modString, ", "
|
||||
)
|
||||
}
|
||||
}
|
||||
60
cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp
Normal file
60
cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
template<typename T> void mod(T value);
|
||||
|
||||
const int c1 = 42;
|
||||
const int c2 = 43;
|
||||
|
||||
void m(int i, bool cond, int x, int y) {
|
||||
int eq = i + 3;
|
||||
|
||||
int mul = eq * c1 + 3; // congruent 3 mod 42
|
||||
|
||||
int seven = 7;
|
||||
if (mul % c2 == seven) {
|
||||
mod(mul); // congruent 3 mod 42, 7 mod 43
|
||||
}
|
||||
|
||||
int j = cond
|
||||
? i * 4 + 3
|
||||
: i * 8 + 7;
|
||||
mod(j); // $ mod=0,3,4
|
||||
|
||||
if (x % c1 == 3 && y % c1 == 7) {
|
||||
// Need implies_v2
|
||||
mod(x + y); // $ MISSING: 0,10,42
|
||||
}
|
||||
|
||||
if (x % c1 == 3 && y % c1 == 7) {
|
||||
// Need implies_v2
|
||||
mod(x - y); // $ MISSING: mod=0,38,42
|
||||
}
|
||||
|
||||
if (cond) {
|
||||
j = i * 4 + 3;
|
||||
}
|
||||
else {
|
||||
j = i * 8 + 7;
|
||||
}
|
||||
mod(j); // $ mod=0,3,4
|
||||
|
||||
if (cond) {
|
||||
mod(j); // $ mod=0,3,4
|
||||
} else {
|
||||
mod(j); // $ mod=0,3,4
|
||||
}
|
||||
|
||||
if ((x & 15) == 3) {
|
||||
mod(x); // $ mod=0,3,16
|
||||
}
|
||||
}
|
||||
|
||||
void loops(int cap)
|
||||
{
|
||||
for (int i = 0; i < cap; i++)
|
||||
mod(i);
|
||||
|
||||
for (int j = 0; j < cap; j += 1)
|
||||
mod(j);
|
||||
|
||||
for (int k = 0; k < cap; k += 3)
|
||||
mod(k); // $ mod=0,0,3
|
||||
}
|
||||
544
cpp/ql/test/library-tests/ir/sign-analysis/PrintIR.expected
Normal file
544
cpp/ql/test/library-tests/ir/sign-analysis/PrintIR.expected
Normal file
@@ -0,0 +1,544 @@
|
||||
test.cpp:
|
||||
# 3| int f1(int, int)
|
||||
# 3| Block 0
|
||||
# 3| v3_1(void) = EnterFunction :
|
||||
# 3| sign =
|
||||
# 3| m3_2(unknown) = AliasedDefinition :
|
||||
# 3| sign =
|
||||
# 3| m3_3(unknown) = InitializeNonLocal :
|
||||
# 3| sign =
|
||||
# 3| m3_4(unknown) = Chi : total:m3_2, partial:m3_3
|
||||
# 3| sign =
|
||||
# 3| r3_5(glval<int>) = VariableAddress[x] :
|
||||
# 3| sign =
|
||||
# 3| m3_6(int) = InitializeParameter[x] : &:r3_5
|
||||
# 3| sign = +-0
|
||||
# 3| r3_7(glval<int>) = VariableAddress[y] :
|
||||
# 3| sign =
|
||||
# 3| m3_8(int) = InitializeParameter[y] : &:r3_7
|
||||
# 3| sign = +-0
|
||||
# 4| r4_1(glval<int>) = VariableAddress[x] :
|
||||
# 4| sign =
|
||||
# 4| r4_2(int) = Load[x] : &:r4_1, m3_6
|
||||
# 4| sign = +-0
|
||||
# 4| r4_3(int) = Constant[0] :
|
||||
# 4| sign = 0
|
||||
# 4| r4_4(bool) = CompareLT : r4_2, r4_3
|
||||
# 4| sign =
|
||||
# 4| v4_5(void) = ConditionalBranch : r4_4
|
||||
# 4| sign =
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 3| Block 1
|
||||
# 3| m3_9(unknown) = Phi : from 2:~m5_7, from 4:~m8_7, from 5:~m3_4
|
||||
# 3| sign =
|
||||
# 3| m3_10(int) = Phi : from 2:m5_8, from 4:m8_8, from 5:m11_3
|
||||
# 3| sign = +-0
|
||||
# 3| r3_11(glval<int>) = VariableAddress[#return] :
|
||||
# 3| sign =
|
||||
# 3| v3_12(void) = ReturnValue : &:r3_11, m3_10
|
||||
# 3| sign =
|
||||
# 3| v3_13(void) = AliasedUse : ~m3_9
|
||||
# 3| sign =
|
||||
# 3| v3_14(void) = ExitFunction :
|
||||
# 3| sign =
|
||||
|
||||
# 5| Block 2
|
||||
# 5| r5_1(glval<int>) = VariableAddress[#return] :
|
||||
# 5| sign =
|
||||
# 5| r5_2(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 5| sign =
|
||||
# 5| r5_3(glval<int>) = VariableAddress[x] :
|
||||
# 5| sign =
|
||||
# 5| r5_4(int) = Load[x] : &:r5_3, m3_6
|
||||
# 5| sign = -
|
||||
# 5| r5_5(int) = Call[sign] : func:r5_2, 0:r5_4
|
||||
# 5| sign = +-0
|
||||
# 5| m5_6(unknown) = ^CallSideEffect : ~m3_4
|
||||
# 5| sign =
|
||||
# 5| m5_7(unknown) = Chi : total:m3_4, partial:m5_6
|
||||
# 5| sign =
|
||||
# 5| m5_8(int) = Store[#return] : &:r5_1, r5_5
|
||||
# 5| sign = +-0
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 7| Block 3
|
||||
# 7| r7_1(glval<int>) = VariableAddress[x] :
|
||||
# 7| sign =
|
||||
# 7| r7_2(int) = Load[x] : &:r7_1, m3_6
|
||||
# 7| sign = +0
|
||||
# 7| r7_3(glval<int>) = VariableAddress[y] :
|
||||
# 7| sign =
|
||||
# 7| r7_4(int) = Load[y] : &:r7_3, m3_8
|
||||
# 7| sign = +-0
|
||||
# 7| r7_5(bool) = CompareLT : r7_2, r7_4
|
||||
# 7| sign =
|
||||
# 7| v7_6(void) = ConditionalBranch : r7_5
|
||||
# 7| sign =
|
||||
#-----| False -> Block 5
|
||||
#-----| True -> Block 4
|
||||
|
||||
# 8| Block 4
|
||||
# 8| r8_1(glval<int>) = VariableAddress[#return] :
|
||||
# 8| sign =
|
||||
# 8| r8_2(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 8| sign =
|
||||
# 8| r8_3(glval<int>) = VariableAddress[y] :
|
||||
# 8| sign =
|
||||
# 8| r8_4(int) = Load[y] : &:r8_3, m3_8
|
||||
# 8| sign = +
|
||||
# 8| r8_5(int) = Call[sign] : func:r8_2, 0:r8_4
|
||||
# 8| sign = +-0
|
||||
# 8| m8_6(unknown) = ^CallSideEffect : ~m3_4
|
||||
# 8| sign =
|
||||
# 8| m8_7(unknown) = Chi : total:m3_4, partial:m8_6
|
||||
# 8| sign =
|
||||
# 8| m8_8(int) = Store[#return] : &:r8_1, r8_5
|
||||
# 8| sign = +-0
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 11| Block 5
|
||||
# 11| r11_1(glval<int>) = VariableAddress[#return] :
|
||||
# 11| sign =
|
||||
# 11| r11_2(int) = Constant[0] :
|
||||
# 11| sign = 0
|
||||
# 11| m11_3(int) = Store[#return] : &:r11_1, r11_2
|
||||
# 11| sign = 0
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 14| void u(int)
|
||||
# 14| Block 0
|
||||
# 14| v14_1(void) = EnterFunction :
|
||||
# 14| sign =
|
||||
# 14| m14_2(unknown) = AliasedDefinition :
|
||||
# 14| sign =
|
||||
# 14| m14_3(unknown) = InitializeNonLocal :
|
||||
# 14| sign =
|
||||
# 14| m14_4(unknown) = Chi : total:m14_2, partial:m14_3
|
||||
# 14| sign =
|
||||
# 14| r14_5(glval<int>) = VariableAddress[x] :
|
||||
# 14| sign =
|
||||
# 14| m14_6(int) = InitializeParameter[x] : &:r14_5
|
||||
# 14| sign = +-0
|
||||
# 15| r15_1(glval<unsigned int>) = VariableAddress[c] :
|
||||
# 15| sign =
|
||||
# 15| r15_2(glval<int>) = VariableAddress[x] :
|
||||
# 15| sign =
|
||||
# 15| r15_3(int) = Load[x] : &:r15_2, m14_6
|
||||
# 15| sign = +-0
|
||||
# 15| r15_4(unsigned int) = Convert : r15_3
|
||||
# 15| sign = +0
|
||||
# 15| m15_5(unsigned int) = Store[c] : &:r15_1, r15_4
|
||||
# 15| sign = +0
|
||||
# 16| r16_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 16| sign =
|
||||
# 16| r16_2(glval<unsigned int>) = VariableAddress[c] :
|
||||
# 16| sign =
|
||||
# 16| r16_3(unsigned int) = Load[c] : &:r16_2, m15_5
|
||||
# 16| sign = +0
|
||||
# 16| r16_4(unsigned int) = Call[sign] : func:r16_1, 0:r16_3
|
||||
# 16| sign = +0
|
||||
# 16| m16_5(unknown) = ^CallSideEffect : ~m14_4
|
||||
# 16| sign =
|
||||
# 16| m16_6(unknown) = Chi : total:m14_4, partial:m16_5
|
||||
# 16| sign =
|
||||
# 17| v17_1(void) = NoOp :
|
||||
# 17| sign =
|
||||
# 14| v14_7(void) = ReturnVoid :
|
||||
# 14| sign =
|
||||
# 14| v14_8(void) = AliasedUse : ~m16_6
|
||||
# 14| sign =
|
||||
# 14| v14_9(void) = ExitFunction :
|
||||
# 14| sign =
|
||||
|
||||
# 19| void constants()
|
||||
# 19| Block 0
|
||||
# 19| v19_1(void) = EnterFunction :
|
||||
# 19| sign =
|
||||
# 19| m19_2(unknown) = AliasedDefinition :
|
||||
# 19| sign =
|
||||
# 19| m19_3(unknown) = InitializeNonLocal :
|
||||
# 19| sign =
|
||||
# 19| m19_4(unknown) = Chi : total:m19_2, partial:m19_3
|
||||
# 19| sign =
|
||||
# 20| r20_1(glval<int>) = VariableAddress[i_pos] :
|
||||
# 20| sign =
|
||||
# 20| r20_2(int) = Constant[1234] :
|
||||
# 20| sign = +
|
||||
# 20| m20_3(int) = Store[i_pos] : &:r20_1, r20_2
|
||||
# 20| sign = +
|
||||
# 21| r21_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 21| sign =
|
||||
# 21| r21_2(glval<int>) = VariableAddress[i_pos] :
|
||||
# 21| sign =
|
||||
# 21| r21_3(int) = Load[i_pos] : &:r21_2, m20_3
|
||||
# 21| sign = +
|
||||
# 21| r21_4(int) = Call[sign] : func:r21_1, 0:r21_3
|
||||
# 21| sign = +-0
|
||||
# 21| m21_5(unknown) = ^CallSideEffect : ~m19_4
|
||||
# 21| sign =
|
||||
# 21| m21_6(unknown) = Chi : total:m19_4, partial:m21_5
|
||||
# 21| sign =
|
||||
# 22| r22_1(glval<int>) = VariableAddress[i_neg] :
|
||||
# 22| sign =
|
||||
# 22| r22_2(int) = Constant[-1234] :
|
||||
# 22| sign = -
|
||||
# 22| m22_3(int) = Store[i_neg] : &:r22_1, r22_2
|
||||
# 22| sign = -
|
||||
# 23| r23_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 23| sign =
|
||||
# 23| r23_2(glval<int>) = VariableAddress[i_neg] :
|
||||
# 23| sign =
|
||||
# 23| r23_3(int) = Load[i_neg] : &:r23_2, m22_3
|
||||
# 23| sign = -
|
||||
# 23| r23_4(int) = Call[sign] : func:r23_1, 0:r23_3
|
||||
# 23| sign = +-0
|
||||
# 23| m23_5(unknown) = ^CallSideEffect : ~m21_6
|
||||
# 23| sign =
|
||||
# 23| m23_6(unknown) = Chi : total:m21_6, partial:m23_5
|
||||
# 23| sign =
|
||||
# 24| r24_1(glval<int>) = VariableAddress[i_zero] :
|
||||
# 24| sign =
|
||||
# 24| r24_2(int) = Constant[0] :
|
||||
# 24| sign = 0
|
||||
# 24| m24_3(int) = Store[i_zero] : &:r24_1, r24_2
|
||||
# 24| sign = 0
|
||||
# 25| r25_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 25| sign =
|
||||
# 25| r25_2(glval<int>) = VariableAddress[i_zero] :
|
||||
# 25| sign =
|
||||
# 25| r25_3(int) = Load[i_zero] : &:r25_2, m24_3
|
||||
# 25| sign = 0
|
||||
# 25| r25_4(int) = Call[sign] : func:r25_1, 0:r25_3
|
||||
# 25| sign = +-0
|
||||
# 25| m25_5(unknown) = ^CallSideEffect : ~m23_6
|
||||
# 25| sign =
|
||||
# 25| m25_6(unknown) = Chi : total:m23_6, partial:m25_5
|
||||
# 25| sign =
|
||||
# 26| r26_1(glval<long>) = VariableAddress[l_pos] :
|
||||
# 26| sign =
|
||||
# 26| r26_2(long) = Constant[1234] :
|
||||
# 26| sign = +
|
||||
# 26| m26_3(long) = Store[l_pos] : &:r26_1, r26_2
|
||||
# 26| sign = +
|
||||
# 27| r27_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 27| sign =
|
||||
# 27| r27_2(glval<long>) = VariableAddress[l_pos] :
|
||||
# 27| sign =
|
||||
# 27| r27_3(long) = Load[l_pos] : &:r27_2, m26_3
|
||||
# 27| sign = +
|
||||
# 27| r27_4(long) = Call[sign] : func:r27_1, 0:r27_3
|
||||
# 27| sign = +-0
|
||||
# 27| m27_5(unknown) = ^CallSideEffect : ~m25_6
|
||||
# 27| sign =
|
||||
# 27| m27_6(unknown) = Chi : total:m25_6, partial:m27_5
|
||||
# 27| sign =
|
||||
# 28| r28_1(glval<long>) = VariableAddress[l_neg] :
|
||||
# 28| sign =
|
||||
# 28| r28_2(long) = Constant[-1234] :
|
||||
# 28| sign = -
|
||||
# 28| m28_3(long) = Store[l_neg] : &:r28_1, r28_2
|
||||
# 28| sign = -
|
||||
# 29| r29_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 29| sign =
|
||||
# 29| r29_2(glval<long>) = VariableAddress[l_neg] :
|
||||
# 29| sign =
|
||||
# 29| r29_3(long) = Load[l_neg] : &:r29_2, m28_3
|
||||
# 29| sign = -
|
||||
# 29| r29_4(long) = Call[sign] : func:r29_1, 0:r29_3
|
||||
# 29| sign = +-0
|
||||
# 29| m29_5(unknown) = ^CallSideEffect : ~m27_6
|
||||
# 29| sign =
|
||||
# 29| m29_6(unknown) = Chi : total:m27_6, partial:m29_5
|
||||
# 29| sign =
|
||||
# 30| r30_1(glval<long>) = VariableAddress[l_zero] :
|
||||
# 30| sign =
|
||||
# 30| r30_2(long) = Constant[0] :
|
||||
# 30| sign = 0
|
||||
# 30| m30_3(long) = Store[l_zero] : &:r30_1, r30_2
|
||||
# 30| sign = 0
|
||||
# 31| r31_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 31| sign =
|
||||
# 31| r31_2(glval<long>) = VariableAddress[l_zero] :
|
||||
# 31| sign =
|
||||
# 31| r31_3(long) = Load[l_zero] : &:r31_2, m30_3
|
||||
# 31| sign = 0
|
||||
# 31| r31_4(long) = Call[sign] : func:r31_1, 0:r31_3
|
||||
# 31| sign = +-0
|
||||
# 31| m31_5(unknown) = ^CallSideEffect : ~m29_6
|
||||
# 31| sign =
|
||||
# 31| m31_6(unknown) = Chi : total:m29_6, partial:m31_5
|
||||
# 31| sign =
|
||||
# 32| r32_1(glval<long>) = VariableAddress[l_pos_big] :
|
||||
# 32| sign =
|
||||
# 32| r32_2(long) = Constant[7426928653] :
|
||||
# 32| sign = +
|
||||
# 32| m32_3(long) = Store[l_pos_big] : &:r32_1, r32_2
|
||||
# 32| sign = +
|
||||
# 33| r33_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 33| sign =
|
||||
# 33| r33_2(glval<long>) = VariableAddress[l_pos_big] :
|
||||
# 33| sign =
|
||||
# 33| r33_3(long) = Load[l_pos_big] : &:r33_2, m32_3
|
||||
# 33| sign = +
|
||||
# 33| r33_4(long) = Call[sign] : func:r33_1, 0:r33_3
|
||||
# 33| sign = +-0
|
||||
# 33| m33_5(unknown) = ^CallSideEffect : ~m31_6
|
||||
# 33| sign =
|
||||
# 33| m33_6(unknown) = Chi : total:m31_6, partial:m33_5
|
||||
# 33| sign =
|
||||
# 34| r34_1(glval<float>) = VariableAddress[f_pos] :
|
||||
# 34| sign =
|
||||
# 34| r34_2(float) = Constant[1.233999968] :
|
||||
# 34| sign = +
|
||||
# 34| m34_3(float) = Store[f_pos] : &:r34_1, r34_2
|
||||
# 34| sign = +
|
||||
# 35| r35_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 35| sign =
|
||||
# 35| r35_2(glval<float>) = VariableAddress[f_pos] :
|
||||
# 35| sign =
|
||||
# 35| r35_3(float) = Load[f_pos] : &:r35_2, m34_3
|
||||
# 35| sign = +
|
||||
# 35| r35_4(float) = Call[sign] : func:r35_1, 0:r35_3
|
||||
# 35| sign = +-0
|
||||
# 35| m35_5(unknown) = ^CallSideEffect : ~m33_6
|
||||
# 35| sign =
|
||||
# 35| m35_6(unknown) = Chi : total:m33_6, partial:m35_5
|
||||
# 35| sign =
|
||||
# 36| r36_1(glval<float>) = VariableAddress[f_neg] :
|
||||
# 36| sign =
|
||||
# 36| r36_2(float) = Constant[-1.233999968] :
|
||||
# 36| sign = -
|
||||
# 36| m36_3(float) = Store[f_neg] : &:r36_1, r36_2
|
||||
# 36| sign = -
|
||||
# 37| r37_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 37| sign =
|
||||
# 37| r37_2(glval<float>) = VariableAddress[f_neg] :
|
||||
# 37| sign =
|
||||
# 37| r37_3(float) = Load[f_neg] : &:r37_2, m36_3
|
||||
# 37| sign = -
|
||||
# 37| r37_4(float) = Call[sign] : func:r37_1, 0:r37_3
|
||||
# 37| sign = +-0
|
||||
# 37| m37_5(unknown) = ^CallSideEffect : ~m35_6
|
||||
# 37| sign =
|
||||
# 37| m37_6(unknown) = Chi : total:m35_6, partial:m37_5
|
||||
# 37| sign =
|
||||
# 38| r38_1(glval<float>) = VariableAddress[f_zero] :
|
||||
# 38| sign =
|
||||
# 38| r38_2(float) = Constant[0.0] :
|
||||
# 38| sign = 0
|
||||
# 38| m38_3(float) = Store[f_zero] : &:r38_1, r38_2
|
||||
# 38| sign = 0
|
||||
# 39| r39_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 39| sign =
|
||||
# 39| r39_2(glval<float>) = VariableAddress[f_zero] :
|
||||
# 39| sign =
|
||||
# 39| r39_3(float) = Load[f_zero] : &:r39_2, m38_3
|
||||
# 39| sign = 0
|
||||
# 39| r39_4(float) = Call[sign] : func:r39_1, 0:r39_3
|
||||
# 39| sign = +-0
|
||||
# 39| m39_5(unknown) = ^CallSideEffect : ~m37_6
|
||||
# 39| sign =
|
||||
# 39| m39_6(unknown) = Chi : total:m37_6, partial:m39_5
|
||||
# 39| sign =
|
||||
# 40| v40_1(void) = NoOp :
|
||||
# 40| sign =
|
||||
# 19| v19_5(void) = ReturnVoid :
|
||||
# 19| sign =
|
||||
# 19| v19_6(void) = AliasedUse : ~m39_6
|
||||
# 19| sign =
|
||||
# 19| v19_7(void) = ExitFunction :
|
||||
# 19| sign =
|
||||
|
||||
# 42| void arithmetic(int)
|
||||
# 42| Block 0
|
||||
# 42| v42_1(void) = EnterFunction :
|
||||
# 42| sign =
|
||||
# 42| m42_2(unknown) = AliasedDefinition :
|
||||
# 42| sign =
|
||||
# 42| m42_3(unknown) = InitializeNonLocal :
|
||||
# 42| sign =
|
||||
# 42| m42_4(unknown) = Chi : total:m42_2, partial:m42_3
|
||||
# 42| sign =
|
||||
# 42| r42_5(glval<int>) = VariableAddress[y] :
|
||||
# 42| sign =
|
||||
# 42| m42_6(int) = InitializeParameter[y] : &:r42_5
|
||||
# 42| sign = +-0
|
||||
# 43| r43_1(glval<int>) = VariableAddress[x] :
|
||||
# 43| sign =
|
||||
# 43| r43_2(int) = Constant[0] :
|
||||
# 43| sign = 0
|
||||
# 43| m43_3(int) = Store[x] : &:r43_1, r43_2
|
||||
# 43| sign = 0
|
||||
# 44| r44_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 44| sign =
|
||||
# 44| r44_2(glval<int>) = VariableAddress[x] :
|
||||
# 44| sign =
|
||||
# 44| r44_3(int) = Load[x] : &:r44_2, m43_3
|
||||
# 44| sign = 0
|
||||
# 44| r44_4(int) = Constant[1] :
|
||||
# 44| sign = +
|
||||
# 44| r44_5(int) = Add : r44_3, r44_4
|
||||
# 44| sign = +
|
||||
# 44| r44_6(int) = Call[sign] : func:r44_1, 0:r44_5
|
||||
# 44| sign = +-0
|
||||
# 44| m44_7(unknown) = ^CallSideEffect : ~m42_4
|
||||
# 44| sign =
|
||||
# 44| m44_8(unknown) = Chi : total:m42_4, partial:m44_7
|
||||
# 44| sign =
|
||||
# 45| r45_1(int) = Constant[-1] :
|
||||
# 45| sign = -
|
||||
# 45| r45_2(glval<int>) = VariableAddress[x] :
|
||||
# 45| sign =
|
||||
# 45| m45_3(int) = Store[x] : &:r45_2, r45_1
|
||||
# 45| sign = -
|
||||
# 46| r46_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 46| sign =
|
||||
# 46| r46_2(glval<int>) = VariableAddress[x] :
|
||||
# 46| sign =
|
||||
# 46| r46_3(int) = Load[x] : &:r46_2, m45_3
|
||||
# 46| sign = -
|
||||
# 46| r46_4(int) = Call[sign] : func:r46_1, 0:r46_3
|
||||
# 46| sign = +-0
|
||||
# 46| m46_5(unknown) = ^CallSideEffect : ~m44_8
|
||||
# 46| sign =
|
||||
# 46| m46_6(unknown) = Chi : total:m44_8, partial:m46_5
|
||||
# 46| sign =
|
||||
# 47| r47_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 47| sign =
|
||||
# 47| r47_2(glval<int>) = VariableAddress[x] :
|
||||
# 47| sign =
|
||||
# 47| r47_3(int) = Load[x] : &:r47_2, m45_3
|
||||
# 47| sign = -
|
||||
# 47| r47_4(int) = Constant[1] :
|
||||
# 47| sign = +
|
||||
# 47| r47_5(int) = Add : r47_3, r47_4
|
||||
# 47| sign = +-0
|
||||
# 47| r47_6(int) = Call[sign] : func:r47_1, 0:r47_5
|
||||
# 47| sign = +-0
|
||||
# 47| m47_7(unknown) = ^CallSideEffect : ~m46_6
|
||||
# 47| sign =
|
||||
# 47| m47_8(unknown) = Chi : total:m46_6, partial:m47_7
|
||||
# 47| sign =
|
||||
# 48| r48_1(glval<int>) = VariableAddress[y] :
|
||||
# 48| sign =
|
||||
# 48| r48_2(int) = Load[y] : &:r48_1, m42_6
|
||||
# 48| sign = +-0
|
||||
# 48| r48_3(int) = Constant[0] :
|
||||
# 48| sign = 0
|
||||
# 48| r48_4(bool) = CompareLT : r48_2, r48_3
|
||||
# 48| sign =
|
||||
# 48| v48_5(void) = ConditionalBranch : r48_4
|
||||
# 48| sign =
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 49| Block 1
|
||||
# 49| r49_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 49| sign =
|
||||
# 49| r49_2(glval<int>) = VariableAddress[y] :
|
||||
# 49| sign =
|
||||
# 49| r49_3(int) = Load[y] : &:r49_2, m42_6
|
||||
# 49| sign = -
|
||||
# 49| r49_4(int) = Call[sign] : func:r49_1, 0:r49_3
|
||||
# 49| sign = +-0
|
||||
# 49| m49_5(unknown) = ^CallSideEffect : ~m47_8
|
||||
# 49| sign =
|
||||
# 49| m49_6(unknown) = Chi : total:m47_8, partial:m49_5
|
||||
# 49| sign =
|
||||
# 50| r50_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 50| sign =
|
||||
# 50| r50_2(glval<int>) = VariableAddress[y] :
|
||||
# 50| sign =
|
||||
# 50| r50_3(int) = Load[y] : &:r50_2, m42_6
|
||||
# 50| sign = -
|
||||
# 50| r50_4(int) = Constant[1] :
|
||||
# 50| sign = +
|
||||
# 50| r50_5(int) = Add : r50_3, r50_4
|
||||
# 50| sign = +-0
|
||||
# 50| r50_6(int) = Call[sign] : func:r50_1, 0:r50_5
|
||||
# 50| sign = +-0
|
||||
# 50| m50_7(unknown) = ^CallSideEffect : ~m49_6
|
||||
# 50| sign =
|
||||
# 50| m50_8(unknown) = Chi : total:m49_6, partial:m50_7
|
||||
# 50| sign =
|
||||
# 51| r51_1(glval<int>) = VariableAddress[z] :
|
||||
# 51| sign =
|
||||
# 51| r51_2(glval<int>) = VariableAddress[y] :
|
||||
# 51| sign =
|
||||
# 51| r51_3(int) = Load[y] : &:r51_2, m42_6
|
||||
# 51| sign = -
|
||||
# 51| m51_4(int) = Store[z] : &:r51_1, r51_3
|
||||
# 51| sign = -
|
||||
# 52| r52_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 52| sign =
|
||||
# 52| r52_2(glval<int>) = VariableAddress[z] :
|
||||
# 52| sign =
|
||||
# 52| r52_3(int) = Load[z] : &:r52_2, m51_4
|
||||
# 52| sign = -
|
||||
# 52| r52_4(int) = Constant[1] :
|
||||
# 52| sign = +
|
||||
# 52| r52_5(int) = Add : r52_3, r52_4
|
||||
# 52| sign = +-0
|
||||
# 52| m52_6(int) = Store[z] : &:r52_2, r52_5
|
||||
# 52| sign = +-0
|
||||
# 52| r52_7(int) = Call[sign] : func:r52_1, 0:r52_5
|
||||
# 52| sign = +-0
|
||||
# 52| m52_8(unknown) = ^CallSideEffect : ~m50_8
|
||||
# 52| sign =
|
||||
# 52| m52_9(unknown) = Chi : total:m50_8, partial:m52_8
|
||||
# 52| sign =
|
||||
# 53| r53_1(glval<int>) = VariableAddress[y] :
|
||||
# 53| sign =
|
||||
# 53| r53_2(int) = Load[y] : &:r53_1, m42_6
|
||||
# 53| sign = -
|
||||
# 53| r53_3(glval<int>) = VariableAddress[z] :
|
||||
# 53| sign =
|
||||
# 53| m53_4(int) = Store[z] : &:r53_3, r53_2
|
||||
# 53| sign = -
|
||||
# 54| r54_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 54| sign =
|
||||
# 54| r54_2(glval<int>) = VariableAddress[z] :
|
||||
# 54| sign =
|
||||
# 54| r54_3(int) = Load[z] : &:r54_2, m53_4
|
||||
# 54| sign = -
|
||||
# 54| r54_4(int) = Constant[1] :
|
||||
# 54| sign = +
|
||||
# 54| r54_5(int) = Add : r54_3, r54_4
|
||||
# 54| sign = +-0
|
||||
# 54| m54_6(int) = Store[z] : &:r54_2, r54_5
|
||||
# 54| sign = +-0
|
||||
# 54| r54_7(int) = CopyValue : r54_3
|
||||
# 54| sign = -
|
||||
# 54| r54_8(int) = Call[sign] : func:r54_1, 0:r54_7
|
||||
# 54| sign = +-0
|
||||
# 54| m54_9(unknown) = ^CallSideEffect : ~m52_9
|
||||
# 54| sign =
|
||||
# 54| m54_10(unknown) = Chi : total:m52_9, partial:m54_9
|
||||
# 54| sign =
|
||||
# 55| r55_1(glval<unknown>) = FunctionAddress[sign] :
|
||||
# 55| sign =
|
||||
# 55| r55_2(glval<int>) = VariableAddress[z] :
|
||||
# 55| sign =
|
||||
# 55| r55_3(int) = Load[z] : &:r55_2, m54_6
|
||||
# 55| sign = +-0
|
||||
# 55| r55_4(int) = Call[sign] : func:r55_1, 0:r55_3
|
||||
# 55| sign = +-0
|
||||
# 55| m55_5(unknown) = ^CallSideEffect : ~m54_10
|
||||
# 55| sign =
|
||||
# 55| m55_6(unknown) = Chi : total:m54_10, partial:m55_5
|
||||
# 55| sign =
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 57| Block 2
|
||||
# 57| m57_1(unknown) = Phi : from 0:~m47_8, from 1:~m55_6
|
||||
# 57| sign =
|
||||
# 57| v57_2(void) = NoOp :
|
||||
# 57| sign =
|
||||
# 42| v42_7(void) = ReturnVoid :
|
||||
# 42| sign =
|
||||
# 42| v42_8(void) = AliasedUse : ~m57_1
|
||||
# 42| sign =
|
||||
# 42| v42_9(void) = ExitFunction :
|
||||
# 42| sign =
|
||||
15
cpp/ql/test/library-tests/ir/sign-analysis/PrintIR.ql
Normal file
15
cpp/ql/test/library-tests/ir/sign-analysis/PrintIR.ql
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.ir.PrintIR
|
||||
import semmle.code.cpp.ir.IR as IR
|
||||
import experimental.semmle.code.cpp.semantic.analysis.SignAnalysisCommon
|
||||
import experimental.semmle.code.cpp.semantic.Semantic
|
||||
|
||||
class SignProvider extends IR::IRPropertyProvider {
|
||||
override string getInstructionProperty(IR::Instruction instruction, string key) {
|
||||
key = "sign" and
|
||||
result = concat(semExprSign(instruction).toString(), "")
|
||||
}
|
||||
}
|
||||
24
cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql
Normal file
24
cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql
Normal file
@@ -0,0 +1,24 @@
|
||||
import cpp
|
||||
import experimental.semmle.code.cpp.semantic.analysis.SignAnalysisCommon
|
||||
import experimental.semmle.code.cpp.semantic.Semantic
|
||||
import semmle.code.cpp.ir.IR as IR
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class SignAnalysisTest extends InlineExpectationsTest {
|
||||
SignAnalysisTest() { this = "SignAnalysisTest" }
|
||||
|
||||
override string getARelevantTag() { result = "sign" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(SemExpr e, IR::CallInstruction call |
|
||||
call.getArgument(0) = e and
|
||||
call.getStaticCallTarget().hasName("sign") and
|
||||
tag = "sign" and
|
||||
element = e.toString() and
|
||||
location = e.getLocation() and
|
||||
value = getASignString(e)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private string getASignString(SemExpr e) { result = strictconcat(semExprSign(e).toString(), "") }
|
||||
57
cpp/ql/test/library-tests/ir/sign-analysis/test.cpp
Normal file
57
cpp/ql/test/library-tests/ir/sign-analysis/test.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
template<typename T> T sign(T value);
|
||||
|
||||
int f1(int x, int y) {
|
||||
if (x < 0) {
|
||||
return sign(x); // $ sign=-
|
||||
}
|
||||
if (x < y) {
|
||||
return sign(y); // $ sign=+
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void u(int x) {
|
||||
unsigned c = (unsigned)x;
|
||||
sign(c); // $ sign=+0
|
||||
}
|
||||
|
||||
void constants() {
|
||||
int i_pos = 1234;
|
||||
sign(i_pos); // $ sign=+
|
||||
int i_neg = -1234;
|
||||
sign(i_neg); // $ sign=-
|
||||
int i_zero = 0;
|
||||
sign(i_zero); // $ sign=0
|
||||
long l_pos = 1234;
|
||||
sign(l_pos); // $ sign=+
|
||||
long l_neg = -1234;
|
||||
sign(l_neg); // $ sign=-
|
||||
long l_zero = 0;
|
||||
sign(l_zero); // $ sign=0
|
||||
long l_pos_big = 0x00000001baadf00d;
|
||||
sign(l_pos_big); // $ sign=+
|
||||
float f_pos = 1.234f;
|
||||
sign(f_pos); // $ sign=+
|
||||
float f_neg = -1.234f;
|
||||
sign(f_neg); // $ sign=-
|
||||
float f_zero = 0.0f;
|
||||
sign(f_zero); // $ sign=0
|
||||
}
|
||||
|
||||
void arithmetic(int y) {
|
||||
int x = 0;
|
||||
sign(x + 1); // $ sign=+
|
||||
x = -1;
|
||||
sign(x); // $ sign=-
|
||||
sign(x + 1); // $ sign=+-0 // Ideally 0 because it's constant
|
||||
if (y < 0) {
|
||||
sign(y); // $ sign=-
|
||||
sign(y + 1); // $ sign=+-0 // Ideally -0 because it's only adding one.
|
||||
int z = y;
|
||||
sign(++z); // $ sign=+-0 // Ideally -0 because it's only adding one.
|
||||
z = y;
|
||||
sign(z++); // $ sign=-
|
||||
sign(z); // $ sign=+-0 // Ideally -0 because it's only adding one.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user