mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Move logic for determining CallSideEffect opcode out of TranslatedCall.
This is the first step to fixing the order of side effects on call instructions. The goal is to move all side effects (argument side effects, allocation side effects, and conservative call side effects) to be treated as elements in a single sequence of side effects, which will then be handled in a single place similar to how we already handle argument side effects.
This commit is contained in:
@@ -111,6 +111,32 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `SideEffectFunction` called by the specified expression.class, if known.
|
||||
*
|
||||
* Thie will return a result only for `Call`, in which case it returns the target of the call, or
|
||||
* for `NewExpr` and `NewArrayExpr`, in which case it returns the allocator function called by the
|
||||
* expression.
|
||||
*/
|
||||
private SideEffectFunction getCallOrAllocationSideEffectFunction(Expr expr) {
|
||||
result = expr.(Call).getTarget()
|
||||
or
|
||||
result = expr.(NewOrNewArrayExpr).getAllocator()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the side effect opcode, if any, that represents any side effects not specifically modeled
|
||||
* by an argument side effect.
|
||||
*/
|
||||
Opcode getCallSideEffectOpcode(Expr expr) {
|
||||
if not getCallOrAllocationSideEffectFunction(expr).hasOnlySpecificWriteSideEffects()
|
||||
then result instanceof Opcode::CallSideEffect
|
||||
else (
|
||||
not getCallOrAllocationSideEffectFunction(expr).hasOnlySpecificReadSideEffects() and
|
||||
result instanceof Opcode::CallReadSideEffect
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a side effect opcode for parameter index `i` of the specified call.
|
||||
*
|
||||
|
||||
@@ -50,17 +50,14 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
opcode instanceof Opcode::Call and
|
||||
resultType = getTypeForPRValue(getCallResultType())
|
||||
or
|
||||
hasSideEffect() and
|
||||
tag = CallSideEffectTag() and
|
||||
opcode = getCallSideEffectOpcode(expr) and
|
||||
(
|
||||
if hasWriteSideEffect()
|
||||
then (
|
||||
opcode instanceof Opcode::CallSideEffect and
|
||||
resultType = getUnknownType()
|
||||
) else (
|
||||
opcode instanceof Opcode::CallReadSideEffect and
|
||||
resultType = getVoidType()
|
||||
)
|
||||
opcode instanceof Opcode::CallSideEffect and
|
||||
resultType = getUnknownType()
|
||||
or
|
||||
opcode instanceof Opcode::CallReadSideEffect and
|
||||
resultType = getVoidType()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -200,11 +197,7 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
*/
|
||||
abstract predicate hasArguments();
|
||||
|
||||
predicate hasReadSideEffect() { any() }
|
||||
|
||||
predicate hasWriteSideEffect() { any() }
|
||||
|
||||
private predicate hasSideEffect() { hasReadSideEffect() or hasWriteSideEffect() }
|
||||
final private predicate hasSideEffect() { exists(getCallSideEffectOpcode(expr)) }
|
||||
|
||||
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
|
||||
hasSideEffect() and
|
||||
@@ -325,14 +318,6 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
|
||||
tag = CallTargetTag() and result = expr.getTarget()
|
||||
}
|
||||
|
||||
override predicate hasReadSideEffect() {
|
||||
not expr.getTarget().(SideEffectFunction).hasOnlySpecificReadSideEffects()
|
||||
}
|
||||
|
||||
override predicate hasWriteSideEffect() {
|
||||
not expr.getTarget().(SideEffectFunction).hasOnlySpecificWriteSideEffects()
|
||||
}
|
||||
|
||||
override Instruction getQualifierResult() {
|
||||
hasQualifier() and
|
||||
result = getQualifier().getResult()
|
||||
|
||||
Reference in New Issue
Block a user