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

Skip to content

Commit 9de570b

Browse files
committed
C++: Use the newly added predicates in field flow. This commit also adds a Class column to the FieldContent branch so FieldContent has a pretty toString implementation again.
1 parent 1e13a39 commit 9de570b

2 files changed

Lines changed: 50 additions & 32 deletions

File tree

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ private import cpp
22
private import DataFlowUtil
33
private import semmle.code.cpp.ir.IR
44
private import DataFlowDispatch
5-
private import semmle.code.cpp.ir.implementation.aliased_ssa.internal.AliasedSSA
6-
private import semmle.code.cpp.ir.internal.IntegerConstant
75

86
/**
97
* A data flow node that occurs as the argument of a call and is passed as-is
@@ -146,11 +144,23 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
146144
*/
147145
predicate jumpStep(Node n1, Node n2) { none() }
148146

147+
/**
148+
* Gets the field corresponding to the bit range `[startBit..endBit)` of class `c`.
149+
*/
150+
private Field getField(Class c, int startBit, int endBit) {
151+
result.getDeclaringType() = c and
152+
startBit = 8 * result.getByteOffset() and
153+
endBit = 8 * result.getType().getSize() + startBit
154+
or
155+
exists(Field f, Class cInner |
156+
f = c.getAField() and
157+
cInner = f.getUnderlyingType() and
158+
result = getField(cInner, startBit - 8 * f.getByteOffset(), endBit - 8 * f.getByteOffset())
159+
)
160+
}
161+
149162
private newtype TContent =
150-
TFieldContent(IntValue startBitOffset, IntValue endBitOffset) {
151-
getDefInterval(_, startBitOffset, endBitOffset) or
152-
getUseInterval(_, startBitOffset, endBitOffset)
153-
} or
163+
TFieldContent(Class c, int startBit, int endBit) { exists(getField(c, startBit, endBit)) } or
154164
TCollectionContent() or
155165
TArrayContent()
156166

@@ -167,20 +177,18 @@ class Content extends TContent {
167177
}
168178
}
169179

170-
private class FieldContent extends Content, TFieldContent {
171-
IntValue startBitOffset;
172-
IntValue endBitOffset;
180+
class FieldContent extends Content, TFieldContent {
181+
Class c;
182+
int startBit;
183+
int endBit;
173184

174-
FieldContent() { this = TFieldContent(startBitOffset, endBitOffset) }
185+
FieldContent() { this = TFieldContent(c, startBit, endBit) }
175186

176-
override string toString() {
177-
result = "[" + startBitOffset.toString() + ".." + endBitOffset.toString() + ")"
178-
}
187+
override string toString() { result = getField().toString() }
179188

180-
predicate hasOffset(IntValue start, IntValue end) {
181-
start = startBitOffset and
182-
end = endBitOffset
183-
}
189+
predicate hasOffset(Class cl, int start, int end) { cl = c and start = startBit and end = endBit }
190+
191+
Field getField() { result = getField(c, startBit, endBit) }
184192
}
185193

186194
private class CollectionContent extends Content, TCollectionContent {
@@ -192,21 +200,26 @@ private class ArrayContent extends Content, TArrayContent {
192200
}
193201

194202
private predicate storeStepNoChi(Node node1, Content f, PostUpdateNode node2) {
195-
exists(StoreInstruction store, IntValue startBitDef, IntValue endBitDef |
203+
exists(StoreInstruction store |
196204
store = node2.asInstruction() and
197-
getDefInterval(store, startBitDef, endBitDef) and
198205
store.getSourceValue() = node1.asInstruction() and
199-
f.(FieldContent).hasOffset(startBitDef, endBitDef)
206+
f.(FieldContent).getField() = store.getDestinationAddress().(FieldInstruction).getField()
200207
)
201208
}
202209

203210
private predicate storeStepChi(Node node1, Content f, PostUpdateNode node2) {
204-
exists(StoreInstruction store, ChiInstruction chi, IntValue startBitDef, IntValue endBitDef |
211+
exists(StoreInstruction store, ChiInstruction chi |
205212
node1.asInstruction() = store and
206-
getDefInterval(store, startBitDef, endBitDef) and
207213
node2.asInstruction() = chi and
208214
chi.getPartial() = store and
209-
f.(FieldContent).hasOffset(startBitDef, endBitDef)
215+
(
216+
exists(int startBit, int endBit |
217+
chi.getUpdatedInterval(startBit, endBit) and
218+
f.(FieldContent).hasOffset(chi.getResultType(), startBit, endBit)
219+
)
220+
or
221+
f.(FieldContent).getField() = store.getDestinationAddress().(FieldInstruction).getField()
222+
)
210223
)
211224
}
212225

@@ -226,11 +239,18 @@ predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
226239
* `node2`.
227240
*/
228241
predicate readStep(Node node1, Content f, Node node2) {
229-
exists(LoadInstruction load, IntValue startBitUse, IntValue endBitUse |
242+
exists(LoadInstruction load |
230243
node2.asInstruction() = load and
231244
node1.asInstruction() = load.getSourceValueOperand().getAnyDef() and
232-
getUseInterval(load, startBitUse, endBitUse) and
233-
f.(FieldContent).hasOffset(startBitUse, endBitUse)
245+
(
246+
exists(Class c, int startBit, int endBit |
247+
c = load.getSourceValueOperand().getAnyDef().getResultType() and
248+
load.getSourceValueOperand().getUsedInterval(startBit, endBit) and
249+
f.(FieldContent).hasOffset(c, startBit, endBit)
250+
)
251+
or
252+
f.(FieldContent).getField() = load.getSourceAddress().(FieldInstruction).getField()
253+
)
234254
)
235255
}
236256

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -325,14 +325,15 @@ abstract private class PartialDefinitionNode extends PostUpdateNode {
325325

326326
private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
327327
override ChiInstruction instr;
328-
IntValue startBitDef;
329-
IntValue endBitDef;
330328
StoreInstruction store;
331329

332330
ExplicitFieldStoreQualifierNode() {
333331
not instr.isResultConflated() and
334332
instr.getPartial() = store and
335-
getDefInterval(store, startBitDef, endBitDef)
333+
(
334+
instr.getUpdatedInterval(_, _) or
335+
store.getDestinationAddress() instanceof FieldAddressInstruction
336+
)
336337
}
337338

338339
// By using an operand as the result of this predicate we avoid the dataflow inconsistency errors
@@ -359,11 +360,8 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
359360
*/
360361
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
361362
override StoreInstruction instr;
362-
IntValue startBitDef;
363-
IntValue endBitDef;
364363

365364
ExplicitSingleFieldStoreQualifierNode() {
366-
getDefInterval(instr, startBitDef, endBitDef) and
367365
not exists(ChiInstruction chi | chi.getPartial() = instr) and
368366
// Without this condition any store would create a `PostUpdateNode`.
369367
instr.getDestinationAddress() instanceof FieldAddressInstruction

0 commit comments

Comments
 (0)