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

Skip to content

Commit b5b0c2b

Browse files
committed
Data flow: Sync files
1 parent 6be2bf8 commit b5b0c2b

21 files changed

Lines changed: 2427 additions & 2169 deletions

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll

Lines changed: 119 additions & 101 deletions
Large diffs are not rendered by default.

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll

Lines changed: 119 additions & 101 deletions
Large diffs are not rendered by default.

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll

Lines changed: 119 additions & 101 deletions
Large diffs are not rendered by default.

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll

Lines changed: 119 additions & 101 deletions
Large diffs are not rendered by default.

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 95 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ private module Cached {
2121
predicate viableParamArg(DataFlowCall call, ParameterNode p, ArgumentNode arg) {
2222
exists(int i |
2323
viableParam(call, i, p) and
24-
arg.argumentOf(call, i)
24+
arg.argumentOf(call, i) and
25+
compatibleTypes(getErasedNodeTypeBound(arg), getErasedNodeTypeBound(p))
2526
)
2627
}
2728

2829
/** Provides predicates for calculating flow-through summaries. */
30+
cached
2931
private module FlowThrough {
3032
/**
3133
* The first flow-through approximation:
@@ -216,14 +218,12 @@ private module Cached {
216218
private predicate localFlowStepPlus(Node node1, Node node2) {
217219
localFlowEntry(node1) and
218220
simpleLocalFlowStep(node1, node2) and
219-
node1 != node2 and
220-
Cand::cand(_, node2)
221+
node1 != node2
221222
or
222223
exists(Node mid |
223224
localFlowStepPlus(node1, mid) and
224225
simpleLocalFlowStep(mid, node2) and
225-
not mid instanceof CastNode and
226-
Cand::cand(_, node2)
226+
not mid instanceof CastNode
227227
)
228228
}
229229

@@ -238,9 +238,11 @@ private module Cached {
238238
* The final flow-through calculation:
239239
*
240240
* - Input/output access paths are abstracted with a `ContentOption` parameter
241-
* that represents the head of the access path.
241+
* that represents the head of the access path. `TContentNone()` means that
242+
* the access path is unrestricted.
242243
* - Types are checked using the `compatibleTypes()` relation.
243244
*/
245+
cached
244246
module Final {
245247
/**
246248
* Holds if `p` can flow to `node` in the same callable using only
@@ -250,11 +252,10 @@ private module Cached {
250252
* (if any), and `contentOut` describes the content of `node` that
251253
* it flows to (if any).
252254
*/
253-
predicate parameterValueFlow(
255+
private predicate parameterValueFlow(
254256
ParameterNode p, Node node, ContentOption contentIn, ContentOption contentOut
255257
) {
256258
parameterValueFlow0(p, node, contentIn, contentOut) and
257-
Cand::cand(p, node) and
258259
if node instanceof CastingNode
259260
then
260261
// normal flow through
@@ -269,19 +270,9 @@ private module Cached {
269270
compatibleTypes(fIn.getType(), getErasedNodeTypeBound(node))
270271
)
271272
or
272-
// setter
273+
// (getter+)setter
273274
exists(Content fOut |
274-
contentIn = TContentNone() and
275275
contentOut.getContent() = fOut and
276-
compatibleTypes(getErasedNodeTypeBound(p), fOut.getType()) and
277-
compatibleTypes(fOut.getContainerType(), getErasedNodeTypeBound(node))
278-
)
279-
or
280-
// getter+setter
281-
exists(Content fIn, Content fOut |
282-
contentIn.getContent() = fIn and
283-
contentOut.getContent() = fOut and
284-
compatibleTypes(fIn.getType(), fOut.getType()) and
285276
compatibleTypes(fOut.getContainerType(), getErasedNodeTypeBound(node))
286277
)
287278
else any()
@@ -312,7 +303,8 @@ private module Cached {
312303
contentOutMid = TContentNone() and
313304
contentIn.getContent() = f and
314305
contentOut = TContentNone() and
315-
Cand::parameterValueFlowReturnCand(p, _, true, _)
306+
Cand::parameterValueFlowReturnCand(p, _, true, _) and
307+
compatibleTypes(getErasedNodeTypeBound(p), f.getContainerType())
316308
or
317309
// value (possibly read and then) stored prior to read (same content)
318310
contentIn = contentInMid and
@@ -325,25 +317,30 @@ private module Cached {
325317
parameterValueFlow(p, mid, contentIn, TContentNone()) and
326318
storeStep(mid, f, node) and
327319
contentOut.getContent() = f
320+
|
321+
contentIn = TContentNone() and
322+
compatibleTypes(getErasedNodeTypeBound(p), f.getType())
323+
or
324+
compatibleTypes(contentIn.getContent().getType(), f.getType())
328325
)
329326
or
330327
// flow through: no prior read or store
331328
exists(ArgumentNode arg |
332329
parameterValueFlowArg(p, arg, TContentNone(), TContentNone()) and
333-
argumentValueFlowsThrough(arg, node, contentIn, contentOut)
330+
argumentValueFlowsThrough(_, arg, contentIn, contentOut, node)
334331
)
335332
or
336333
// flow through: no read or store inside method
337334
exists(ArgumentNode arg |
338335
parameterValueFlowArg(p, arg, contentIn, contentOut) and
339-
argumentValueFlowsThrough(arg, node, TContentNone(), TContentNone())
336+
argumentValueFlowsThrough(_, arg, TContentNone(), TContentNone(), node)
340337
)
341338
or
342339
// flow through: possible prior read and prior store with compatible
343340
// flow-through method
344341
exists(ArgumentNode arg, ContentOption contentMid |
345342
parameterValueFlowArg(p, arg, contentIn, contentMid) and
346-
argumentValueFlowsThrough(arg, node, contentMid, contentOut)
343+
argumentValueFlowsThrough(_, arg, contentMid, contentOut, node)
347344
)
348345
}
349346

@@ -356,15 +353,7 @@ private module Cached {
356353
}
357354

358355
pragma[nomagic]
359-
predicate parameterValueFlowsToPostUpdate(
360-
ParameterNode p, PostUpdateNode n, ContentOption contentIn, ContentOption contentOut
361-
) {
362-
parameterValueFlow(p, n, contentIn, contentOut) and
363-
contentOut.hasContent()
364-
}
365-
366-
pragma[nomagic]
367-
predicate argumentValueFlowsThrough0(
356+
private predicate argumentValueFlowsThrough0(
368357
DataFlowCall call, ArgumentNode arg, ReturnKindExt kind, ContentOption contentIn,
369358
ContentOption contentOut
370359
) {
@@ -374,104 +363,91 @@ private module Cached {
374363
}
375364

376365
/**
377-
* Holds if `arg` flows to `out` through a call using only value-preserving steps,
366+
* Holds if `arg` flows to `out` through `call` using only value-preserving steps,
378367
* not taking call contexts into account.
379368
*
380369
* `contentIn` describes the content of `arg` that can flow to `out` (if any), and
381370
* `contentOut` describes the content of `out` that it flows to (if any).
382371
*/
383-
private predicate argumentValueFlowsThrough(
384-
ArgumentNode arg, Node out, ContentOption contentIn, ContentOption contentOut
372+
cached
373+
predicate argumentValueFlowsThrough(
374+
DataFlowCall call, ArgumentNode arg, ContentOption contentIn, ContentOption contentOut,
375+
Node out
385376
) {
386-
exists(DataFlowCall call, ReturnKindExt kind |
377+
exists(ReturnKindExt kind |
387378
argumentValueFlowsThrough0(call, arg, kind, contentIn, contentOut) and
388379
out = kind.getAnOutNode(call)
380+
|
381+
// normal flow through
382+
contentIn = TContentNone() and
383+
contentOut = TContentNone() and
384+
compatibleTypes(getErasedNodeTypeBound(arg), getErasedNodeTypeBound(out))
385+
or
386+
// getter(+setter)
387+
exists(Content fIn |
388+
contentIn.getContent() = fIn and
389+
compatibleTypes(getErasedNodeTypeBound(arg), fIn.getContainerType())
390+
)
391+
or
392+
// setter
393+
exists(Content fOut |
394+
contentIn = TContentNone() and
395+
contentOut.getContent() = fOut and
396+
compatibleTypes(getErasedNodeTypeBound(arg), fOut.getType())
397+
)
389398
)
390399
}
391-
}
392400

393-
import Final
394-
}
401+
/**
402+
* Holds if `p` can flow to the pre-update node associated with post-update
403+
* node `n`, in the same callable, using only value-preserving steps.
404+
*/
405+
cached
406+
predicate parameterValueFlowsToPreUpdate(ParameterNode p, PostUpdateNode n) {
407+
parameterValueFlow(p, n.getPreUpdateNode(), TContentNone(), TContentNone())
408+
}
395409

396-
/**
397-
* Holds if `p` can flow to the pre-update node associated with post-update
398-
* node `n`, in the same callable, using only value-preserving steps.
399-
*/
400-
cached
401-
predicate parameterValueFlowsToPreUpdate(ParameterNode p, PostUpdateNode n) {
402-
FlowThrough::parameterValueFlow(p, n.getPreUpdateNode(), TContentNone(), TContentNone())
403-
}
410+
pragma[nomagic]
411+
private predicate parameterValueFlowsToPostUpdate(
412+
ParameterNode p, PostUpdateNode n, ContentOption contentIn, ContentOption contentOut
413+
) {
414+
parameterValueFlow(p, n, contentIn, contentOut) and
415+
contentOut.hasContent()
416+
}
404417

405-
/**
406-
* Holds if `p` can flow to a return node of kind `kind` in the same
407-
* callable using only value-preserving steps.
408-
*
409-
* `contentIn` describes the content of `p` that can flow to the return
410-
* node (if any), and `contentOut` describes the content of the return
411-
* node that it flows to (if any).
412-
*/
413-
cached
414-
predicate parameterValueFlowReturn(
415-
ParameterNode p, Node ret, ReturnKindExt kind, ContentOption contentIn, ContentOption contentOut
416-
) {
417-
ret =
418-
any(ReturnNode n |
419-
FlowThrough::parameterValueFlow(p, n, contentIn, contentOut) and
420-
kind = TValueReturn(n.getKind())
421-
)
422-
or
423-
ret =
424-
any(PostUpdateNode n |
425-
exists(ParameterNode p2, int pos2 |
426-
FlowThrough::parameterValueFlowsToPostUpdate(p, n, contentIn, contentOut) and
427-
parameterValueFlowsToPreUpdate(p2, n) and
428-
p2.isParameterOf(_, pos2) and
429-
kind = TParamUpdate(pos2) and
430-
p != p2
431-
)
432-
)
433-
}
418+
/**
419+
* Holds if `p` can flow to a return node of kind `kind` in the same
420+
* callable using only value-preserving steps.
421+
*
422+
* `contentIn` describes the content of `p` that can flow to the return
423+
* node (if any), and `contentOut` describes the content of the return
424+
* node that it flows to (if any).
425+
*/
426+
cached
427+
predicate parameterValueFlowReturn(
428+
ParameterNode p, Node ret, ReturnKindExt kind, ContentOption contentIn,
429+
ContentOption contentOut
430+
) {
431+
ret =
432+
any(ReturnNode n |
433+
parameterValueFlow(p, n, contentIn, contentOut) and
434+
kind = TValueReturn(n.getKind())
435+
)
436+
or
437+
ret =
438+
any(PostUpdateNode n |
439+
exists(ParameterNode p2, int pos2 |
440+
parameterValueFlowsToPostUpdate(p, n, contentIn, contentOut) and
441+
parameterValueFlowsToPreUpdate(p2, n) and
442+
p2.isParameterOf(_, pos2) and
443+
kind = TParamUpdate(pos2) and
444+
p != p2
445+
)
446+
)
447+
}
448+
}
434449

435-
/**
436-
* Holds if `arg` flows to `out` through `call` using only value-preserving steps.
437-
*
438-
* `contentIn` describes the content of `arg` that can flow to `out` (if any), and
439-
* `contentOut` describes the content of `out` that it flows to (if any).
440-
*/
441-
cached
442-
predicate argumentValueFlowsThrough(
443-
DataFlowCall call, ArgumentNode arg, ContentOption contentIn, ContentOption contentOut, Node out
444-
) {
445-
exists(ReturnKindExt kind |
446-
FlowThrough::argumentValueFlowsThrough0(call, arg, kind, contentIn, contentOut) and
447-
out = kind.getAnOutNode(call)
448-
|
449-
// normal flow through
450-
contentIn = TContentNone() and
451-
contentOut = TContentNone() and
452-
compatibleTypes(getErasedNodeTypeBound(arg), getErasedNodeTypeBound(out))
453-
or
454-
// getter
455-
exists(Content fIn |
456-
contentIn.getContent() = fIn and
457-
contentOut = TContentNone() and
458-
compatibleTypes(getErasedNodeTypeBound(arg), fIn.getContainerType())
459-
)
460-
or
461-
// setter
462-
exists(Content fOut |
463-
contentIn = TContentNone() and
464-
contentOut.getContent() = fOut and
465-
compatibleTypes(getErasedNodeTypeBound(arg), fOut.getType())
466-
)
467-
or
468-
// getter+setter
469-
exists(Content fIn, Content fOut |
470-
contentIn.getContent() = fIn and
471-
contentOut.getContent() = fOut and
472-
compatibleTypes(getErasedNodeTypeBound(arg), fIn.getContainerType())
473-
)
474-
)
450+
import Final
475451
}
476452

477453
/**
@@ -495,6 +471,8 @@ private module Cached {
495471
)
496472
}
497473

474+
import FlowThrough
475+
498476
/**
499477
* Holds if the call context `call` either improves virtual dispatch in
500478
* `callable` or if it allows us to prune unreachable nodes in `callable`.
@@ -558,7 +536,7 @@ class ContentOption extends TContentOption {
558536
result = this.getContent().toString()
559537
or
560538
not this.hasContent() and
561-
result = ""
539+
result = "<none>"
562540
}
563541
}
564542

0 commit comments

Comments
 (0)