Skip to content

Commit 499b6f3

Browse files
committed
C++: Also key SSA defs and uses by the base address.
1 parent e2feed7 commit 499b6f3

File tree

1 file changed

+35
-37
lines changed

1 file changed

+35
-37
lines changed

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

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
9494

9595
cached
9696
private newtype TDefOrUseImpl =
97-
TDefImpl(Operand address, int indirectionIndex) {
98-
exists(Instruction base | isDef(_, _, address, base, _, indirectionIndex) |
97+
TDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) {
98+
isDef(_, _, address, base, _, indirectionIndex) and
99+
(
99100
// We only include the definition if the SSA pruning stage
100101
// concluded that the definition is live after the write.
101102
any(SsaInternals0::Def def).getAddressOperand() = address
@@ -105,8 +106,8 @@ private newtype TDefOrUseImpl =
105106
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
106107
)
107108
} or
108-
TUseImpl(Operand operand, int indirectionIndex) {
109-
isUse(_, operand, _, _, indirectionIndex) and
109+
TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) {
110+
isUse(_, operand, base, _, indirectionIndex) and
110111
not isDef(_, _, operand, _, _, _)
111112
} or
112113
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
@@ -265,15 +266,17 @@ abstract class DefImpl extends DefOrUseImpl {
265266
}
266267

267268
private class DirectDef extends DefImpl, TDefImpl {
268-
DirectDef() { this = TDefImpl(address, ind) }
269+
BaseSourceVariableInstruction base;
270+
271+
DirectDef() { this = TDefImpl(base, address, ind) }
269272

270-
override BaseSourceVariableInstruction getBase() { isDef(_, _, address, result, _, _) }
273+
override BaseSourceVariableInstruction getBase() { result = base }
271274

272-
override int getIndirection() { isDef(_, _, address, _, result, ind) }
275+
override int getIndirection() { isDef(_, _, address, base, result, ind) }
273276

274-
override Node0Impl getValue() { isDef(_, result, address, _, _, _) }
277+
override Node0Impl getValue() { isDef(_, result, address, base, _, _) }
275278

276-
override predicate isCertain() { isDef(true, _, address, _, _, ind) }
279+
override predicate isCertain() { isDef(true, _, address, base, _, ind) }
277280
}
278281

279282
private class IteratorDef extends DefImpl, TIteratorDef {
@@ -316,57 +319,52 @@ abstract class UseImpl extends DefOrUseImpl {
316319

317320
abstract private class OperandBasedUse extends UseImpl {
318321
Operand operand;
322+
BaseSourceVariableInstruction base;
319323

320324
bindingset[ind]
321325
OperandBasedUse() { any() }
322326

323327
final override predicate hasIndexInBlock(IRBlock block, int index) {
324328
// See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
325329
// predicate's implementation.
326-
exists(BaseSourceVariableInstruction base | base = this.getBase() |
327-
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
328-
then
329-
exists(Operand op, int indirectionIndex, int indirection |
330-
indirectionIndex = this.getIndirectionIndex() and
331-
indirection = this.getIndirection() and
332-
op =
333-
min(Operand cand, int i |
334-
isUse(_, cand, base, indirection, indirectionIndex) and
335-
block.getInstruction(i) = cand.getUse()
336-
|
337-
cand order by i
338-
) and
339-
block.getInstruction(index) = op.getUse()
340-
)
341-
else operand.getUse() = block.getInstruction(index)
342-
)
330+
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
331+
then
332+
exists(Operand op, int indirectionIndex, int indirection |
333+
indirectionIndex = this.getIndirectionIndex() and
334+
indirection = this.getIndirection() and
335+
op =
336+
min(Operand cand, int i |
337+
isUse(_, cand, base, indirection, indirectionIndex) and
338+
block.getInstruction(i) = cand.getUse()
339+
|
340+
cand order by i
341+
) and
342+
block.getInstruction(index) = op.getUse()
343+
)
344+
else operand.getUse() = block.getInstruction(index)
343345
}
344346

347+
final override BaseSourceVariableInstruction getBase() { result = base }
348+
345349
final Operand getOperand() { result = operand }
346350

347351
final override Cpp::Location getLocation() { result = operand.getLocation() }
348352
}
349353

350354
private class DirectUse extends OperandBasedUse, TUseImpl {
351-
DirectUse() { this = TUseImpl(operand, ind) }
352-
353-
override int getIndirection() { isUse(_, operand, _, result, ind) }
355+
DirectUse() { this = TUseImpl(base, operand, ind) }
354356

355-
override BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, ind) }
357+
override int getIndirection() { isUse(_, operand, base, result, ind) }
356358

357-
override predicate isCertain() { isUse(true, operand, _, _, ind) }
359+
override predicate isCertain() { isUse(true, operand, base, _, ind) }
358360

359361
override Node getNode() { nodeHasOperand(result, operand, ind) }
360362
}
361363

362364
private class IteratorUse extends OperandBasedUse, TIteratorUse {
363-
BaseSourceVariableInstruction container;
364-
365-
IteratorUse() { this = TIteratorUse(operand, container, ind) }
365+
IteratorUse() { this = TIteratorUse(operand, base, ind) }
366366

367-
override int getIndirection() { isIteratorUse(container, operand, result, ind) }
368-
369-
override BaseSourceVariableInstruction getBase() { result = container }
367+
override int getIndirection() { isIteratorUse(base, operand, result, ind) }
370368

371369
override predicate isCertain() { none() }
372370

0 commit comments

Comments
 (0)