From e0cfbb53dc74a1d283bd39fef13f8731c9dac326 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 1 Aug 2022 09:52:46 -0400 Subject: [PATCH] C++: add missing SideEffectElimination.qll --- .../internal/SideEffectElimination.qll | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SideEffectElimination.qll diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SideEffectElimination.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SideEffectElimination.qll new file mode 100644 index 00000000000..b5aa5134b47 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SideEffectElimination.qll @@ -0,0 +1,42 @@ +import cpp as CPP +import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as Unaliased +import AliasAnalysis as Alias +import AliasConfiguration as Conf +import semmle.code.cpp.models.interfaces.SideEffect as SideEffect + +private predicate noLocalSideEffectWrite(CPP::Function func) { + forall(Unaliased::AddressOperand addr | addr.getUse().getEnclosingFunction() = func | + not ( + Alias::getAddressOperandAllocation(addr) instanceof Conf::VariableAllocation and + Alias::getAddressOperandAllocation(addr).(Conf::VariableAllocation).alwaysEscapes() + ) + ) +} + +language[monotonicAggregates] +private predicate noTransitiveSideEffectWrite(CPP::Function func) { + exists(Unaliased::IRFunction irFunc | irFunc.getFunction() = func) and + noLocalSideEffectWrite(func) and + forall(Unaliased::CallInstruction call | call.getEnclosingFunction() = func | + exists(call.getStaticCallTarget()) + ) and + forall(Unaliased::CallInstruction call, CPP::Function callee | + call.getStaticCallTarget() = callee and + call.getEnclosingFunction() = func + | + noTransitiveSideEffectWrite(callee) + or + callee.(SideEffect::SideEffectFunction).hasOnlySpecificWriteSideEffects() + ) +} + +predicate removeableSideEffect(Unaliased::SideEffectInstruction instr) { + ( + instr instanceof Unaliased::CallSideEffectInstruction or + instr instanceof Unaliased::CallReadSideEffectInstruction + ) and + noTransitiveSideEffectWrite(instr + .getPrimaryInstruction() + .(Unaliased::CallInstruction) + .getStaticCallTarget()) +}