mirror of
https://github.com/github/codeql.git
synced 2025-12-23 12:16:33 +01:00
C++: Fix places that assumed that 'Expr' was always 'Instruction'.
This commit is contained in:
@@ -105,7 +105,7 @@ module SemanticExprConfig {
|
|||||||
SemBasicBlock getExprBasicBlock(Expr e) { result = getSemanticBasicBlock(e.getBlock()) }
|
SemBasicBlock getExprBasicBlock(Expr e) { result = getSemanticBasicBlock(e.getBlock()) }
|
||||||
|
|
||||||
private predicate anyConstantExpr(Expr expr, SemType type, string value) {
|
private predicate anyConstantExpr(Expr expr, SemType type, string value) {
|
||||||
exists(IR::ConstantInstruction instr | instr = expr |
|
exists(IR::ConstantInstruction instr | getSemanticExpr(instr) = expr |
|
||||||
type = getSemanticType(instr.getResultIRType()) and
|
type = getSemanticType(instr.getResultIRType()) and
|
||||||
value = instr.getValue()
|
value = instr.getValue()
|
||||||
)
|
)
|
||||||
@@ -146,41 +146,46 @@ module SemanticExprConfig {
|
|||||||
predicate nullLiteral(Expr expr, SemAddressType type) { anyConstantExpr(expr, type, _) }
|
predicate nullLiteral(Expr expr, SemAddressType type) { anyConstantExpr(expr, type, _) }
|
||||||
|
|
||||||
predicate stringLiteral(Expr expr, SemType type, string value) {
|
predicate stringLiteral(Expr expr, SemType type, string value) {
|
||||||
anyConstantExpr(expr, type, value) and expr instanceof IR::StringConstantInstruction
|
anyConstantExpr(expr, type, value) and
|
||||||
|
expr.getUnconverted() instanceof IR::StringConstantInstruction
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate binaryExpr(Expr expr, Opcode opcode, SemType type, Expr leftOperand, Expr rightOperand) {
|
predicate binaryExpr(Expr expr, Opcode opcode, SemType type, Expr leftOperand, Expr rightOperand) {
|
||||||
exists(IR::BinaryInstruction instr | instr = expr |
|
exists(IR::BinaryInstruction instr |
|
||||||
|
instr = expr.getUnconverted() and
|
||||||
type = getSemanticType(instr.getResultIRType()) and
|
type = getSemanticType(instr.getResultIRType()) and
|
||||||
leftOperand = instr.getLeft() and
|
leftOperand = getSemanticExpr(instr.getLeft()) and
|
||||||
rightOperand = instr.getRight() and
|
rightOperand = getSemanticExpr(instr.getRight()) and
|
||||||
// REVIEW: Merge the two `Opcode` types.
|
// REVIEW: Merge the two `Opcode` types.
|
||||||
opcode.toString() = instr.getOpcode().toString()
|
opcode.toString() = instr.getOpcode().toString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate unaryExpr(Expr expr, Opcode opcode, SemType type, Expr operand) {
|
predicate unaryExpr(Expr expr, Opcode opcode, SemType type, Expr operand) {
|
||||||
type = getSemanticType(expr.getResultIRType()) and
|
exists(IR::UnaryInstruction instr | instr = expr.getUnconverted() |
|
||||||
(
|
type = getSemanticType(instr.getResultIRType()) and
|
||||||
exists(IR::UnaryInstruction instr | instr = expr |
|
operand = getSemanticExpr(instr.getUnary()) and
|
||||||
operand = instr.getUnary() and
|
|
||||||
// REVIEW: Merge the two operand types.
|
// REVIEW: Merge the two operand types.
|
||||||
opcode.toString() = instr.getOpcode().toString()
|
opcode.toString() = instr.getOpcode().toString()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(IR::StoreInstruction instr | instr = expr |
|
exists(IR::StoreInstruction instr | instr = expr.getUnconverted() |
|
||||||
operand = instr.getSourceValue() and
|
type = getSemanticType(instr.getResultIRType()) and
|
||||||
|
operand = getSemanticExpr(instr.getSourceValue()) and
|
||||||
opcode instanceof Opcode::Store
|
opcode instanceof Opcode::Store
|
||||||
)
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate nullaryExpr(Expr expr, Opcode opcode, SemType type) {
|
predicate nullaryExpr(Expr expr, Opcode opcode, SemType type) {
|
||||||
type = getSemanticType(expr.getResultIRType()) and
|
exists(IR::LoadInstruction load |
|
||||||
(
|
load = expr.getUnconverted() and
|
||||||
expr instanceof IR::LoadInstruction and opcode instanceof Opcode::Load
|
type = getSemanticType(load.getResultIRType()) and
|
||||||
|
opcode instanceof Opcode::Load
|
||||||
|
)
|
||||||
or
|
or
|
||||||
expr instanceof IR::InitializeParameterInstruction and
|
exists(IR::InitializeParameterInstruction init |
|
||||||
|
init = expr.getUnconverted() and
|
||||||
|
type = getSemanticType(init.getResultIRType()) and
|
||||||
opcode instanceof Opcode::InitializeParameter
|
opcode instanceof Opcode::InitializeParameter
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -267,7 +272,9 @@ module SemanticExprConfig {
|
|||||||
final override IR::Operand asOperand() { result = op }
|
final override IR::Operand asOperand() { result = op }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v.asInstruction() = sourceExpr }
|
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) {
|
||||||
|
getSemanticExpr(v.asInstruction()) = sourceExpr
|
||||||
|
}
|
||||||
|
|
||||||
predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction }
|
predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction }
|
||||||
|
|
||||||
@@ -280,9 +287,9 @@ module SemanticExprConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Expr getAUse(SsaVariable v) {
|
Expr getAUse(SsaVariable v) {
|
||||||
result.(IR::LoadInstruction).getSourceValue() = v.asInstruction()
|
result.getUnconverted().(IR::LoadInstruction).getSourceValue() = v.asInstruction()
|
||||||
or
|
or
|
||||||
result = valueNumber(v.asPointerArithGuard()).getAnInstruction()
|
result.getUnconverted() = valueNumber(v.asPointerArithGuard()).getAnInstruction()
|
||||||
}
|
}
|
||||||
|
|
||||||
SemType getSsaVariableType(SsaVariable v) {
|
SemType getSsaVariableType(SsaVariable v) {
|
||||||
@@ -391,17 +398,21 @@ module SemanticExprConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Expr getBoundExpr(Bound bound, int delta) {
|
Expr getBoundExpr(Bound bound, int delta) {
|
||||||
result = bound.(IRBound::Bound).getInstruction(delta)
|
result = getSemanticExpr(bound.(IRBound::Bound).getInstruction(delta))
|
||||||
}
|
}
|
||||||
|
|
||||||
class Guard = IRGuards::IRGuardCondition;
|
class Guard = IRGuards::IRGuardCondition;
|
||||||
|
|
||||||
predicate guard(Guard guard, BasicBlock block) { block = guard.getBlock() }
|
predicate guard(Guard guard, BasicBlock block) { block = guard.getBlock() }
|
||||||
|
|
||||||
Expr getGuardAsExpr(Guard guard) { result = guard }
|
Expr getGuardAsExpr(Guard guard) { result = getSemanticExpr(guard) }
|
||||||
|
|
||||||
predicate equalityGuard(Guard guard, Expr e1, Expr e2, boolean polarity) {
|
predicate equalityGuard(Guard guard, Expr e1, Expr e2, boolean polarity) {
|
||||||
guard.comparesEq(e1.getAUse(), e2.getAUse(), 0, true, polarity)
|
exists(IR::Instruction left, IR::Instruction right |
|
||||||
|
getSemanticExpr(left) = e1 and
|
||||||
|
getSemanticExpr(right) = e2 and
|
||||||
|
guard.comparesEq(left.getAUse(), right.getAUse(), 0, true, polarity)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock controlled, boolean branch) {
|
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock controlled, boolean branch) {
|
||||||
@@ -412,16 +423,17 @@ module SemanticExprConfig {
|
|||||||
guard.controlsEdge(bb1, bb2, branch)
|
guard.controlsEdge(bb1, bb2, branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
Guard comparisonGuard(Expr e) { result = e }
|
Guard comparisonGuard(Expr e) { getSemanticExpr(result) = e }
|
||||||
|
|
||||||
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) {
|
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) {
|
||||||
none() // TODO
|
none() // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the expression associated with `instr`. */
|
||||||
|
SemExpr getSemanticExpr(IR::Instruction instr) { result = Equiv::getEquivalenceClass(instr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
SemExpr getSemanticExpr(IR::Instruction instr) { result = instr }
|
predicate getSemanticExpr = SemanticExprConfig::getSemanticExpr/1;
|
||||||
|
|
||||||
IR::Instruction getCppInstruction(SemExpr e) { e = result }
|
|
||||||
|
|
||||||
SemBasicBlock getSemanticBasicBlock(IR::IRBlock block) { result = block }
|
SemBasicBlock getSemanticBasicBlock(IR::IRBlock block) { result = block }
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class RangeAnalysisTest extends InlineExpectationsTest {
|
|||||||
|
|
||||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
exists(SemExpr e, IR::CallInstruction call |
|
exists(SemExpr e, IR::CallInstruction call |
|
||||||
call.getArgument(0) = e and
|
getSemanticExpr(call.getArgument(0)) = e and
|
||||||
call.getStaticCallTarget().hasName("range") and
|
call.getStaticCallTarget().hasName("range") and
|
||||||
tag = "range" and
|
tag = "range" and
|
||||||
element = e.toString() and
|
element = e.toString() and
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import experimental.semmle.code.cpp.semantic.Semantic
|
|||||||
import experimental.semmle.code.cpp.semantic.analysis.RangeUtils
|
import experimental.semmle.code.cpp.semantic.analysis.RangeUtils
|
||||||
import experimental.semmle.code.cpp.semantic.analysis.FloatDelta
|
import experimental.semmle.code.cpp.semantic.analysis.FloatDelta
|
||||||
import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific
|
import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific
|
||||||
|
import experimental.semmle.code.cpp.semantic.SemanticExprSpecific
|
||||||
import semmle.code.cpp.ir.IR as IR
|
import semmle.code.cpp.ir.IR as IR
|
||||||
import TestUtilities.InlineExpectationsTest
|
import TestUtilities.InlineExpectationsTest
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ class SignAnalysisTest extends InlineExpectationsTest {
|
|||||||
|
|
||||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
exists(SemExpr e, IR::CallInstruction call |
|
exists(SemExpr e, IR::CallInstruction call |
|
||||||
call.getArgument(0) = e and
|
getSemanticExpr(call.getArgument(0)) = e and
|
||||||
call.getStaticCallTarget().hasName("sign") and
|
call.getStaticCallTarget().hasName("sign") and
|
||||||
tag = "sign" and
|
tag = "sign" and
|
||||||
element = e.toString() and
|
element = e.toString() and
|
||||||
|
|||||||
Reference in New Issue
Block a user