C++: Simple constant analysis

This change moves the simple constant analysis that was used by the const_func test into a pyrameterized module for use on any stage of the IR. This will be used to detect unreachable code.
This commit is contained in:
Dave Bartolomeo
2018-12-07 10:40:16 -08:00
parent 6a11ef5c18
commit 59fc77f066
11 changed files with 143 additions and 22 deletions

View File

@@ -0,0 +1,32 @@
private import internal.ConstantAnalysisInternal
import semmle.code.cpp.ir.internal.IntegerConstant
private import IR
language[monotonicAggregates]
IntValue getConstantValue(Instruction instr) {
result = instr.(IntegerConstantInstruction).getValue().toInt() or
exists(BinaryInstruction binInstr, IntValue left, IntValue right |
binInstr = instr and
left = getConstantValue(binInstr.getLeftOperand()) and
right = getConstantValue(binInstr.getRightOperand()) and
(
binInstr instanceof AddInstruction and result = add(left, right) or
binInstr instanceof SubInstruction and result = sub(left, right) or
binInstr instanceof MulInstruction and result = mul(left, right) or
binInstr instanceof DivInstruction and result = div(left, right)
)
) or
exists(UnaryInstruction unaryInstr, IntValue src |
unaryInstr = instr and
src = getConstantValue(unaryInstr.getOperand()) and
(
unaryInstr instanceof NegateInstruction and result = neg(src)
)
) or
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
result = max(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
result = min(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
)
}

View File

@@ -0,0 +1,11 @@
private import internal.ConstantAnalysisInternal
private import semmle.code.cpp.ir.internal.IntegerConstant
private import ConstantAnalysis
import IR
private class ConstantAnalysisPropertyProvider extends IRPropertyProvider {
override string getInstructionProperty(Instruction instr, string key) {
key = "ConstantValue" and
result = getValue(getConstantValue(instr)).toString()
}
}

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IR as IR

View File

@@ -0,0 +1,32 @@
private import internal.ConstantAnalysisInternal
import semmle.code.cpp.ir.internal.IntegerConstant
private import IR
language[monotonicAggregates]
IntValue getConstantValue(Instruction instr) {
result = instr.(IntegerConstantInstruction).getValue().toInt() or
exists(BinaryInstruction binInstr, IntValue left, IntValue right |
binInstr = instr and
left = getConstantValue(binInstr.getLeftOperand()) and
right = getConstantValue(binInstr.getRightOperand()) and
(
binInstr instanceof AddInstruction and result = add(left, right) or
binInstr instanceof SubInstruction and result = sub(left, right) or
binInstr instanceof MulInstruction and result = mul(left, right) or
binInstr instanceof DivInstruction and result = div(left, right)
)
) or
exists(UnaryInstruction unaryInstr, IntValue src |
unaryInstr = instr and
src = getConstantValue(unaryInstr.getOperand()) and
(
unaryInstr instanceof NegateInstruction and result = neg(src)
)
) or
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
result = max(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
result = min(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
)
}

View File

@@ -0,0 +1,11 @@
private import internal.ConstantAnalysisInternal
private import semmle.code.cpp.ir.internal.IntegerConstant
private import ConstantAnalysis
import IR
private class ConstantAnalysisPropertyProvider extends IRPropertyProvider {
override string getInstructionProperty(Instruction instr, string key) {
key = "ConstantValue" and
result = getValue(getConstantValue(instr)).toString()
}
}

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.implementation.raw.IR as IR

View File

@@ -0,0 +1,32 @@
private import internal.ConstantAnalysisInternal
import semmle.code.cpp.ir.internal.IntegerConstant
private import IR
language[monotonicAggregates]
IntValue getConstantValue(Instruction instr) {
result = instr.(IntegerConstantInstruction).getValue().toInt() or
exists(BinaryInstruction binInstr, IntValue left, IntValue right |
binInstr = instr and
left = getConstantValue(binInstr.getLeftOperand()) and
right = getConstantValue(binInstr.getRightOperand()) and
(
binInstr instanceof AddInstruction and result = add(left, right) or
binInstr instanceof SubInstruction and result = sub(left, right) or
binInstr instanceof MulInstruction and result = mul(left, right) or
binInstr instanceof DivInstruction and result = div(left, right)
)
) or
exists(UnaryInstruction unaryInstr, IntValue src |
unaryInstr = instr and
src = getConstantValue(unaryInstr.getOperand()) and
(
unaryInstr instanceof NegateInstruction and result = neg(src)
)
) or
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
result = max(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
result = min(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
)
}

View File

@@ -0,0 +1,11 @@
private import internal.ConstantAnalysisInternal
private import semmle.code.cpp.ir.internal.IntegerConstant
private import ConstantAnalysis
import IR
private class ConstantAnalysisPropertyProvider extends IRPropertyProvider {
override string getInstructionProperty(Instruction instr, string key) {
key = "ConstantValue" and
result = getValue(getConstantValue(instr)).toString()
}
}

View File

@@ -0,0 +1 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as IR

View File

@@ -1,29 +1,8 @@
import default
import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.implementation.aliased_ssa.constant.ConstantAnalysis
import semmle.code.cpp.ir.internal.IntegerConstant
language[monotonicAggregates]
IntValue getConstantValue(Instruction instr) {
result = instr.(IntegerConstantInstruction).getValue().toInt() or
exists(BinaryInstruction binInstr, IntValue left, IntValue right |
binInstr = instr and
left = getConstantValue(binInstr.getLeftOperand()) and
right = getConstantValue(binInstr.getRightOperand()) and
(
binInstr instanceof AddInstruction and result = add(left, right) or
binInstr instanceof SubInstruction and result = sub(left, right) or
binInstr instanceof MulInstruction and result = mul(left, right) or
binInstr instanceof DivInstruction and result = div(left, right)
)
) or
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
result = max(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
result = min(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
)
}
from FunctionIR funcIR, int value
where
value = getValue(getConstantValue(funcIR.getReturnInstruction().(ReturnValueInstruction).getReturnValue()))