Skip to content

Commit ddaa28f

Browse files
committed
C++: Split 'ssaFlow' into multiple smaller predicates for readability.
1 parent dbf6925 commit ddaa28f

File tree

1 file changed

+57
-46
lines changed
  • cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal

1 file changed

+57
-46
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Ssa.qll

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -304,65 +304,59 @@ predicate explicitWrite(boolean certain, Instruction instr, Instruction address)
304304

305305
cached
306306
private module Cached {
307-
/**
308-
* Holds if `nodeFrom` is a read or write, and `nTo` is the next subsequent read of the variable
309-
* written (or read) by `storeOrRead`.
310-
*/
311-
cached
312-
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
313-
// Def-use/use-use flow from an `InstructionNode` to an `OperandNode`.
314-
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, DefOrUse defOrUse, Use use, SourceVariable v |
307+
private predicate defUseFlow(Node nodeFrom, Node nodeTo) {
308+
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, DefOrUse defOrUse, Use use |
315309
defOrUse.hasRankInBlock(bb1, i1) and
316310
use.hasRankInBlock(bb2, i2) and
317-
use.getVariable() = v and
318311
adjacentDefRead(_, bb1, i1, bb2, i2) and
319312
nodeFrom.asInstruction() = toInstruction(defOrUse) and
320313
flowOutOfAddressStep(use.getOperand(), nodeTo)
321314
)
322-
or
323-
// Use-use flow from a `ReadNode` to an `OperandNode`.
324-
exists(ReadNode read, IRBlock bb1, int i1, IRBlock bb2, int i2, Use use1, Use use2 |
325-
read = nodeFrom and
315+
}
316+
317+
private predicate fromReadNode(ReadNode nodeFrom, Node nodeTo) {
318+
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, Use use1, Use use2 |
326319
use1.hasRankInBlock(bb1, i1) and
327320
use2.hasRankInBlock(bb2, i2) and
328-
use1.getOperand().getDef() = read.getInstruction() and
321+
use1.getOperand().getDef() = nodeFrom.getInstruction() and
329322
adjacentDefRead(_, bb1, i1, bb2, i2) and
330323
flowOutOfAddressStep(use2.getOperand(), nodeTo)
331324
)
332-
or
333-
// Flow from phi nodes
325+
}
326+
327+
private predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
334328
exists(PhiNode phi, Use use, IRBlock block, int rnk |
335-
phi = nodeFrom.(SsaPhiNode).getPhiNode() and
329+
phi = nodeFrom.getPhiNode() and
330+
adjacentDefRead(_, phi.getBasicBlock(), -1, block, rnk) and
336331
use.hasRankInBlock(block, rnk) and
337332
phi.getSourceVariable() = use.getVariable() and
338-
flowOutOfAddressStep(use.getOperand(), nodeTo) and
339-
adjacentDefRead(_, phi.getBasicBlock(), -1, block, rnk)
333+
flowOutOfAddressStep(use.getOperand(), nodeTo)
340334
)
341-
or
335+
}
336+
337+
private predicate toPhiNode(Node nodeFrom, SsaPhiNode nodeTo) {
342338
// Flow to phi nodes
343-
exists(Def def, StoreNode store, IRBlock block, int rnk |
344-
store = nodeFrom and
345-
store.isTerminal() and
346-
def.getInstruction() = store.getStoreInstruction() and
347-
def.hasRankInBlock(block, rnk) and
348-
nodeTo.(SsaPhiNode).hasInputAtRankInBlock(block, rnk)
349-
)
350-
or
351339
exists(Def def, IRBlock block, int rnk |
352-
def.getInstruction() = nodeFrom.asInstruction() and
353340
def.hasRankInBlock(block, rnk) and
354-
nodeTo.(SsaPhiNode).hasInputAtRankInBlock(block, rnk)
355-
)
356-
or
357-
// Def-use flow from a `StoreNode` to an `OperandNode`.
358-
exists(
359-
StoreNode store, IRBlock bb1, int i1, IRBlock bb2, int i2, Def def, Use use, Definition ssaDef
341+
nodeTo.hasInputAtRankInBlock(block, rnk)
360342
|
361-
store = nodeFrom and
362-
store.isTerminal() and
363-
def.getInstruction() = store.getStoreInstruction() and
343+
exists(StoreNode store |
344+
store = nodeFrom and
345+
store.isTerminal() and
346+
def.getInstruction() = store.getStoreInstruction()
347+
)
348+
or
349+
def.getInstruction() = nodeFrom.asInstruction()
350+
)
351+
}
352+
353+
private predicate fromStoreNode(StoreNode nodeFrom, Node nodeTo) {
354+
// Def-use flow from a `StoreNode`.
355+
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, Def def, Use use |
356+
nodeFrom.isTerminal() and
357+
def.getInstruction() = nodeFrom.getStoreInstruction() and
364358
def.hasRankInBlock(bb1, i1) and
365-
adjacentDefRead(ssaDef, bb1, i1, bb2, i2) and
359+
adjacentDefRead(_, bb1, i1, bb2, i2) and
366360
use.hasRankInBlock(bb2, i2) and
367361
flowOutOfAddressStep(use.getOperand(), nodeTo)
368362
)
@@ -372,17 +366,14 @@ private module Cached {
372366
// library to hook that up to the assignment to `a`. So instead we flow to the _first_ use of the
373367
// value computed by `operator new` that occurs after `nodeFrom` (to avoid a loop in the
374368
// dataflow graph).
375-
exists(
376-
StoreNode store, WriteSideEffectInstruction write, IRBlock bb, int i1, int i2, Operand op
377-
|
378-
store = nodeFrom and
379-
store.getInstruction().(CallInstruction).getStaticCallTarget() instanceof
369+
exists(WriteSideEffectInstruction write, IRBlock bb, int i1, int i2, Operand op |
370+
nodeFrom.getInstruction().(CallInstruction).getStaticCallTarget() instanceof
380371
Alloc::OperatorNewAllocationFunction and
381-
write = store.getStoreInstruction() and
372+
write = nodeFrom.getStoreInstruction() and
382373
bb.getInstruction(i1) = write and
383374
bb.getInstruction(i2) = op.getUse() and
384375
// Flow to an instruction that occurs later in the block.
385-
valueFlow*(store.getInstruction(), op.getDef()) and
376+
valueFlow*(nodeFrom.getInstruction(), op.getDef()) and
386377
nodeTo.asOperand() = op and
387378
i2 > i1 and
388379
// There is no previous instruction that also occurs after `nodeFrom`.
@@ -395,6 +386,26 @@ private module Cached {
395386
)
396387
}
397388

389+
/**
390+
* Holds if `nodeFrom` is a read or write, and `nTo` is the next subsequent read of the variable
391+
* written (or read) by `storeOrRead`.
392+
*/
393+
cached
394+
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
395+
// Def-use/use-use flow from an `InstructionNode`.
396+
defUseFlow(nodeFrom, nodeTo)
397+
or
398+
// Use-use flow from a `ReadNode`.
399+
fromReadNode(nodeFrom, nodeTo)
400+
or
401+
// Def-use flow from a `StoreNode`.
402+
fromStoreNode(nodeFrom, nodeTo)
403+
or
404+
fromPhiNode(nodeFrom, nodeTo)
405+
or
406+
toPhiNode(nodeFrom, nodeTo)
407+
}
408+
398409
private predicate valueFlow(Instruction iFrom, Instruction iTo) {
399410
iTo.(CopyValueInstruction).getSourceValue() = iFrom
400411
or

0 commit comments

Comments
 (0)