Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions shared/ssa/codeql/ssa/Ssa.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,12 @@ module Make<LocationSig Location, InputSig<Location> Input> {
* definition.
*/
default predicate includeWriteDefsInFlowStep() { any() }

/**
* Holds if barrier guards should be supported on input edges to phi
* nodes. Disable this only if barrier guards are not going to be used.
*/
default predicate supportBarrierGuardsOnPhiEdges() { any() }
}

/**
Expand Down Expand Up @@ -1533,6 +1539,29 @@ module Make<LocationSig Location, InputSig<Location> Input> {
)
}

/**
* Holds if the input to `phi` from the block `input` might be relevant for
* barrier guards as a separately synthesized `TSsaInputNode`.
*/
private predicate relevantPhiInputNode(SsaPhiExt phi, BasicBlock input) {
DfInput::supportBarrierGuardsOnPhiEdges() and
// If the input isn't explicitly read then a guard cannot check it.
exists(DfInput::getARead(getAPhiInputDef(phi, input))) and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this means that for

if (b) {
    x = foo;
    read(x);
}
else {
    x = bar;
}
read(x);

we will not generate an input edge from the else block?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

(
exists(DfInput::Guard g | g.controlsBranchEdge(input, phi.getBasicBlock(), _))
or
exists(BasicBlock prev |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could deserve a comment with an example

AdjacentSsaRefs::adjacentRefPhi(prev, _, input, phi.getBasicBlock(),
phi.getSourceVariable()) and
prev != input and
exists(DfInput::Guard g, boolean branch |
DfInput::guardControlsBlock(g, input, branch) and
not DfInput::guardControlsBlock(g, prev, branch)
)
)
)
}

private newtype TNode =
TParamNode(DfInput::Parameter p) {
exists(WriteDefinition def | DfInput::ssaDefInitializesParam(def, p))
Expand All @@ -1546,7 +1575,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
)
} or
TSsaDefinitionNode(DefinitionExt def) or
TSsaInputNode(SsaPhiExt phi, BasicBlock input) { exists(getAPhiInputDef(phi, input)) }
TSsaInputNode(SsaPhiExt phi, BasicBlock input) { relevantPhiInputNode(phi, input) }

/**
* A data flow node that we need to reference in the value step relation.
Expand Down Expand Up @@ -1822,8 +1851,12 @@ module Make<LocationSig Location, InputSig<Location> Input> {
// Flow from definition/read to phi input
exists(BasicBlock input, BasicBlock bbPhi, DefinitionExt phi |
AdjacentSsaRefs::adjacentRefPhi(bb1, i1, input, bbPhi, v) and
nodeTo = TSsaInputNode(phi, input) and
phi.definesAt(v, bbPhi, -1, _)
|
nodeTo = TSsaInputNode(phi, input)
or
not relevantPhiInputNode(phi, input) and
nodeTo.(SsaDefinitionExtNodeImpl).getDefExt() = phi
)
}

Expand Down