Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 589f7bd

Browse files
committed
C++: Introduce BaseSourceVariableInstruction.
1 parent e71fbb1 commit 589f7bd

3 files changed

Lines changed: 83 additions & 150 deletions

File tree

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

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ private module SourceVariables {
1919
)
2020
}
2121

22-
class BaseSourceVariable = SsaInternals0::BaseSourceVariable;
23-
24-
class BaseIRVariable = SsaInternals0::BaseIRVariable;
25-
26-
class BaseCallVariable = SsaInternals0::BaseCallVariable;
27-
2822
cached
2923
private newtype TSourceVariable =
3024
TSourceIRVariable(BaseIRVariable baseVar, int ind) {
@@ -159,15 +153,10 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl {
159153
* Gets the instruction that computes the base of this definition or use.
160154
* This is always a `VariableAddressInstruction` or an `AllocationInstruction`.
161155
*/
162-
abstract Instruction getBase();
156+
abstract BaseSourceVariableInstruction getBase();
163157

164158
final BaseSourceVariable getBaseSourceVariable() {
165-
exists(IRVariable var |
166-
result.(BaseIRVariable).getIRVariable() = var and
167-
instructionHasIRVariable(this.getBase(), var)
168-
)
169-
or
170-
result.(BaseCallVariable).getCallInstruction() = this.getBase()
159+
this.getBase().getBaseSourceVariable() = result
171160
}
172161

173162
/** Gets the variable that is defined or used. */
@@ -179,11 +168,6 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl {
179168
}
180169
}
181170

182-
pragma[noinline]
183-
private predicate instructionHasIRVariable(VariableAddressInstruction vai, IRVariable var) {
184-
vai.getIRVariable() = var
185-
}
186-
187171
private predicate defOrUseHasSourceVariable(DefOrUseImpl defOrUse, BaseSourceVariable bv, int ind) {
188172
defHasSourceVariable(defOrUse, bv, ind)
189173
or
@@ -214,7 +198,7 @@ class DefImpl extends DefOrUseImpl, TDefImpl {
214198

215199
DefImpl() { this = TDefImpl(address, ind) }
216200

217-
override Instruction getBase() { isDef(_, _, address, result, _, _) }
201+
override BaseSourceVariableInstruction getBase() { isDef(_, _, address, result, _, _) }
218202

219203
Operand getAddressOperand() { result = address }
220204

@@ -259,7 +243,7 @@ class UseImpl extends DefOrUseImpl, TUseImpl {
259243

260244
override int getIndirectionIndex() { result = ind }
261245

262-
override Instruction getBase() { isUse(_, operand, result, _, ind) }
246+
override BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, ind) }
263247

264248
predicate isCertain() { isUse(true, operand, _, _, ind) }
265249
}
@@ -415,22 +399,14 @@ predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
415399
)
416400
}
417401

418-
private SsaInternals0::SourceVariable getOldSourceVariable(SourceVariable v) {
419-
v.getBaseVariable().(BaseIRVariable).getIRVariable() =
420-
result.getBaseVariable().(SsaInternals0::BaseIRVariable).getIRVariable()
421-
or
422-
v.getBaseVariable().(BaseCallVariable).getCallInstruction() =
423-
result.getBaseVariable().(SsaInternals0::BaseCallVariable).getCallInstruction()
424-
}
425-
426402
/**
427403
* Holds if there is a write at index `i` in basic block `bb` to variable `v` that's
428404
* subsequently read (as determined by the SSA pruning stage).
429405
*/
430406
private predicate variableWriteCand(IRBlock bb, int i, SourceVariable v) {
431407
exists(SsaInternals0::Def def, SsaInternals0::SourceVariable v0 |
432408
def.asDefOrUse().hasIndexInBlock(bb, i, v0) and
433-
v0 = getOldSourceVariable(v)
409+
v0 = v.getBaseVariable()
434410
)
435411
}
436412

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

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,50 @@ predicate isWrite(Node0Impl value, Operand address, boolean certain) {
152152
)
153153
}
154154

155+
predicate isAdditionalConversionFlow(Operand opFrom, Instruction instrTo) {
156+
any(Indirection ind).isAdditionalConversionFlow(opFrom, instrTo)
157+
}
158+
159+
predicate ignoreSourceVariableBase(BaseSourceVariableInstruction base, Node0Impl value) {
160+
any(Indirection ind).ignoreSourceVariableBase(base, value)
161+
}
162+
163+
newtype TBaseSourceVariable =
164+
// Each IR variable gets its own source variable
165+
TBaseIRVariable(IRVariable var) or
166+
// Each allocation gets its own source variable
167+
TBaseCallVariable(AllocationInstruction call)
168+
169+
abstract class BaseSourceVariable extends TBaseSourceVariable {
170+
abstract string toString();
171+
172+
abstract DataFlowType getType();
173+
}
174+
175+
class BaseIRVariable extends BaseSourceVariable, TBaseIRVariable {
176+
IRVariable var;
177+
178+
IRVariable getIRVariable() { result = var }
179+
180+
BaseIRVariable() { this = TBaseIRVariable(var) }
181+
182+
override string toString() { result = var.toString() }
183+
184+
override DataFlowType getType() { result = var.getType() }
185+
}
186+
187+
class BaseCallVariable extends BaseSourceVariable, TBaseCallVariable {
188+
AllocationInstruction call;
189+
190+
BaseCallVariable() { this = TBaseCallVariable(call) }
191+
192+
AllocationInstruction getCallInstruction() { result = call }
193+
194+
override string toString() { result = call.toString() }
195+
196+
override DataFlowType getType() { result = call.getResultType() }
197+
}
198+
155199
/**
156200
* Holds if the value pointed to by `operand` can potentially be
157201
* modified be the caller.
@@ -199,6 +243,19 @@ predicate isModifiableByCall(ArgumentOperand operand) {
199243
)
200244
}
201245

246+
abstract class BaseSourceVariableInstruction extends Instruction {
247+
abstract BaseSourceVariable getBaseSourceVariable();
248+
}
249+
250+
private class BaseIRVariableInstruction extends BaseSourceVariableInstruction,
251+
VariableAddressInstruction {
252+
override BaseIRVariable getBaseSourceVariable() { result.getIRVariable() = this.getIRVariable() }
253+
}
254+
255+
private class BaseAllocationInstruction extends BaseSourceVariableInstruction, AllocationInstruction {
256+
override BaseCallVariable getBaseSourceVariable() { result.getCallInstruction() = this }
257+
}
258+
202259
cached
203260
private module Cached {
204261
/**
@@ -209,7 +266,9 @@ private module Cached {
209266
* `indirectionIndex` specifies the number of loads required to read the variable.
210267
*/
211268
cached
212-
predicate isUse(boolean certain, Operand op, Instruction base, int ind, int indirectionIndex) {
269+
predicate isUse(
270+
boolean certain, Operand op, BaseSourceVariableInstruction base, int ind, int indirectionIndex
271+
) {
213272
not ignoreOperand(op) and
214273
certain = true and
215274
exists(LanguageType type, int upper, int ind0 |
@@ -257,11 +316,10 @@ private module Cached {
257316
* Holds if `operand` is a use of an SSA variable rooted at `base`, and the
258317
* path from `base` to `operand` passes through `ind` load-like instructions.
259318
*/
260-
private predicate isUseImpl(Operand operand, Instruction base, int ind) {
319+
private predicate isUseImpl(Operand operand, BaseSourceVariableInstruction base, int ind) {
261320
DataFlowImplCommon::forceCachingInSameStage() and
262321
ind = 0 and
263-
operand.getDef() = base and
264-
isSourceVariableBase(base)
322+
operand = base.getAUse()
265323
or
266324
exists(Operand mid, Instruction instr |
267325
isUseImpl(mid, base, ind) and
@@ -278,17 +336,6 @@ private module Cached {
278336
)
279337
}
280338

281-
/**
282-
* Holds if `i` is a base instruction that starts a sequence of uses
283-
* of some variable that SSA can handle.
284-
*
285-
* This is either when `i` is a `VariableAddressInstruction` or when
286-
* `i` is a fresh allocation produced by an `AllocationInstruction`.
287-
*/
288-
private predicate isSourceVariableBase(Instruction i) {
289-
i instanceof VariableAddressInstruction or i instanceof AllocationInstruction
290-
}
291-
292339
/**
293340
* Holds if `address` is an address of an SSA variable rooted at `base`,
294341
* and `instr` is a definition of the SSA variable with `ind` number of indirections.
@@ -299,7 +346,7 @@ private module Cached {
299346
*/
300347
cached
301348
predicate isDef(
302-
boolean certain, Node0Impl value, Operand address, Instruction base, int ind,
349+
boolean certain, Node0Impl value, Operand address, BaseSourceVariableInstruction base, int ind,
303350
int indirectionIndex
304351
) {
305352
exists(int ind0, CppType type, int lower, int upper |
@@ -320,11 +367,10 @@ private module Cached {
320367
* Note: Unlike `isUseImpl`, this predicate recurses through pointer-arithmetic
321368
* instructions.
322369
*/
323-
private predicate isDefImpl(Operand address, Instruction base, int ind) {
370+
private predicate isDefImpl(Operand address, BaseSourceVariableInstruction base, int ind) {
324371
DataFlowImplCommon::forceCachingInSameStage() and
325372
ind = 0 and
326-
address.getDef() = base and
327-
isSourceVariableBase(base)
373+
address = base.getAUse()
328374
or
329375
exists(Operand mid, Instruction instr |
330376
isDefImpl(mid, base, ind) and

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

Lines changed: 13 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -15,75 +15,15 @@ private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
1515
private import semmle.code.cpp.ir.dataflow.internal.SsaInternalsCommon
1616

1717
private module SourceVariables {
18-
newtype TBaseSourceVariable =
19-
// Each IR variable gets its own source variable
20-
TBaseIRVariable(IRVariable var) or
21-
// Each allocation gets its own source variable
22-
TBaseCallVariable(AllocationInstruction call)
18+
class SourceVariable instanceof BaseSourceVariable {
19+
string toString() { result = BaseSourceVariable.super.toString() }
2320

24-
abstract class BaseSourceVariable extends TBaseSourceVariable {
25-
abstract string toString();
26-
27-
abstract DataFlowType getType();
28-
}
29-
30-
class BaseIRVariable extends BaseSourceVariable, TBaseIRVariable {
31-
IRVariable var;
32-
33-
IRVariable getIRVariable() { result = var }
34-
35-
BaseIRVariable() { this = TBaseIRVariable(var) }
36-
37-
override string toString() { result = var.toString() }
38-
39-
override DataFlowType getType() { result = var.getType() }
40-
}
41-
42-
class BaseCallVariable extends BaseSourceVariable, TBaseCallVariable {
43-
AllocationInstruction call;
44-
45-
BaseCallVariable() { this = TBaseCallVariable(call) }
46-
47-
AllocationInstruction getCallInstruction() { result = call }
48-
49-
override string toString() { result = call.toString() }
50-
51-
override DataFlowType getType() { result = call.getResultType() }
52-
}
53-
54-
private newtype TSourceVariable =
55-
TSourceIRVariable(BaseIRVariable baseVar) or
56-
TCallVariable(AllocationInstruction call)
57-
58-
abstract class SourceVariable extends TSourceVariable {
59-
abstract string toString();
60-
61-
abstract BaseSourceVariable getBaseVariable();
62-
}
63-
64-
class SourceIRVariable extends SourceVariable, TSourceIRVariable {
65-
BaseIRVariable var;
66-
67-
SourceIRVariable() { this = TSourceIRVariable(var) }
68-
69-
IRVariable getIRVariable() { result = var.getIRVariable() }
70-
71-
override BaseIRVariable getBaseVariable() { result.getIRVariable() = this.getIRVariable() }
72-
73-
override string toString() { result = this.getIRVariable().toString() }
21+
BaseSourceVariable getBaseVariable() { result = this }
7422
}
7523

76-
class CallVariable extends SourceVariable, TCallVariable {
77-
AllocationInstruction call;
78-
79-
CallVariable() { this = TCallVariable(call) }
80-
81-
AllocationInstruction getCall() { result = call }
24+
class SourceIRVariable = BaseIRVariable;
8225

83-
override BaseCallVariable getBaseVariable() { result.getCallInstruction() = call }
84-
85-
override string toString() { result = "Call" }
86-
}
26+
class CallVariable = BaseCallVariable;
8727
}
8828

8929
import SourceVariables
@@ -113,58 +53,27 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl {
11353
/** Gets the location of this element. */
11454
abstract Cpp::Location getLocation();
11555

116-
abstract Instruction getBase();
56+
abstract BaseSourceVariableInstruction getBase();
11757

11858
final BaseSourceVariable getBaseSourceVariable() {
119-
exists(IRVariable var |
120-
result.(BaseIRVariable).getIRVariable() = var and
121-
instructionHasIRVariable(this.getBase(), var)
122-
)
123-
or
124-
result.(BaseCallVariable).getCallInstruction() = this.getBase()
59+
result = this.getBase().getBaseSourceVariable()
12560
}
12661

12762
/** Gets the variable that is defined or used. */
12863
final SourceVariable getSourceVariable() {
12964
exists(BaseSourceVariable v |
130-
sourceVariableHasBaseAndIndex(result, v) and
131-
defOrUseHasSourceVariable(this, v)
65+
result.getBaseVariable() = v and
66+
this.getBaseSourceVariable() = v
13267
)
13368
}
13469
}
13570

136-
pragma[noinline]
137-
private predicate instructionHasIRVariable(VariableAddressInstruction vai, IRVariable var) {
138-
vai.getIRVariable() = var
139-
}
140-
141-
private predicate defOrUseHasSourceVariable(DefOrUseImpl defOrUse, BaseSourceVariable bv) {
142-
defHasSourceVariable(defOrUse, bv)
143-
or
144-
useHasSourceVariable(defOrUse, bv)
145-
}
146-
147-
pragma[noinline]
148-
private predicate defHasSourceVariable(DefImpl def, BaseSourceVariable bv) {
149-
bv = def.getBaseSourceVariable()
150-
}
151-
152-
pragma[noinline]
153-
private predicate useHasSourceVariable(UseImpl use, BaseSourceVariable bv) {
154-
bv = use.getBaseSourceVariable()
155-
}
156-
157-
pragma[noinline]
158-
private predicate sourceVariableHasBaseAndIndex(SourceVariable v, BaseSourceVariable bv) {
159-
v.getBaseVariable() = bv
160-
}
161-
16271
class DefImpl extends DefOrUseImpl, TDefImpl {
16372
Operand address;
16473

16574
DefImpl() { this = TDefImpl(address) }
16675

167-
override Instruction getBase() { isDef(_, _, address, result, _, _) }
76+
override BaseSourceVariableInstruction getBase() { isDef(_, _, address, result, _, _) }
16877

16978
Operand getAddressOperand() { result = address }
17079

@@ -200,7 +109,7 @@ class UseImpl extends DefOrUseImpl, TUseImpl {
200109

201110
final override Cpp::Location getLocation() { result = operand.getLocation() }
202111

203-
override Instruction getBase() { isUse(_, operand, result, _, _) }
112+
override BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, _) }
204113

205114
predicate isCertain() { isUse(true, operand, _, _, _) }
206115
}
@@ -305,6 +214,8 @@ class Def extends DefOrUse {
305214
Node0Impl getValue() { result = defOrUse.getValue() }
306215

307216
override string toString() { result = this.asDefOrUse().toString() }
217+
218+
BaseSourceVariableInstruction getBase() { result = defOrUse.getBase() }
308219
}
309220

310221
private module SsaImpl = SsaImplCommon::Make<SsaInput>;

0 commit comments

Comments
 (0)