Skip to content

Commit 853a3aa

Browse files
authored
Merge pull request #1799 from aschackmull/java/fieldflow-perf
Java/C++/C#: Improve performance of data flow with fields.
2 parents fbeed91 + 2bea0a4 commit 853a3aa

File tree

18 files changed

+774
-936
lines changed

18 files changed

+774
-936
lines changed

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

Lines changed: 43 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -241,66 +241,62 @@ private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKind kind) {
241241
* Holds if `node` is reachable from a source in the given configuration
242242
* ignoring call contexts.
243243
*/
244-
private predicate nodeCandFwd1(Node node, boolean stored, Configuration config) {
244+
private predicate nodeCandFwd1(Node node, Configuration config) {
245245
not fullBarrier(node, config) and
246246
(
247-
config.isSource(node) and stored = false
247+
config.isSource(node)
248248
or
249249
exists(Node mid |
250-
nodeCandFwd1(mid, stored, config) and
250+
nodeCandFwd1(mid, config) and
251251
localFlowStep(mid, node, config)
252252
)
253253
or
254254
exists(Node mid |
255-
nodeCandFwd1(mid, stored, config) and
256-
additionalLocalFlowStep(mid, node, config) and
257-
stored = false
255+
nodeCandFwd1(mid, config) and
256+
additionalLocalFlowStep(mid, node, config)
258257
)
259258
or
260259
exists(Node mid |
261-
nodeCandFwd1(mid, stored, config) and
260+
nodeCandFwd1(mid, config) and
262261
jumpStep(mid, node, config)
263262
)
264263
or
265264
exists(Node mid |
266-
nodeCandFwd1(mid, stored, config) and
267-
additionalJumpStep(mid, node, config) and
268-
stored = false
265+
nodeCandFwd1(mid, config) and
266+
additionalJumpStep(mid, node, config)
269267
)
270268
or
271269
// store
272270
exists(Node mid |
273271
useFieldFlow(config) and
274-
nodeCandFwd1(mid, _, config) and
272+
nodeCandFwd1(mid, config) and
275273
store(mid, _, node) and
276-
stored = true and
277274
not outBarrier(mid, config)
278275
)
279276
or
280277
// read
281278
exists(Content f |
282279
nodeCandFwd1Read(f, node, config) and
283280
storeCandFwd1(f, config) and
284-
(stored = false or stored = true) and
285281
not inBarrier(node, config)
286282
)
287283
or
288284
// flow into a callable
289285
exists(Node arg |
290-
nodeCandFwd1(arg, stored, config) and
286+
nodeCandFwd1(arg, config) and
291287
viableParamArg(_, node, arg)
292288
)
293289
or
294290
// flow out of an argument
295291
exists(PostUpdateNode mid, ParameterNode p |
296-
nodeCandFwd1(mid, stored, config) and
292+
nodeCandFwd1(mid, config) and
297293
parameterValueFlowsToUpdate(p, mid) and
298294
viableParamArg(_, p, node.(PostUpdateNode).getPreUpdateNode())
299295
)
300296
or
301297
// flow out of a callable
302298
exists(DataFlowCall call, ReturnNode ret, ReturnKind kind |
303-
nodeCandFwd1(ret, stored, config) and
299+
nodeCandFwd1(ret, config) and
304300
getReturnPosition(ret) = viableReturnPos(call, kind) and
305301
node = getAnOutNode(call, kind)
306302
)
@@ -310,7 +306,7 @@ private predicate nodeCandFwd1(Node node, boolean stored, Configuration config)
310306
pragma[nomagic]
311307
private predicate nodeCandFwd1Read(Content f, Node node, Configuration config) {
312308
exists(Node mid |
313-
nodeCandFwd1(mid, true, config) and
309+
nodeCandFwd1(mid, config) and
314310
read(mid, f, node)
315311
)
316312
}
@@ -323,7 +319,7 @@ private predicate storeCandFwd1(Content f, Configuration config) {
323319
exists(Node mid, Node node |
324320
not fullBarrier(node, config) and
325321
useFieldFlow(config) and
326-
nodeCandFwd1(mid, _, config) and
322+
nodeCandFwd1(mid, config) and
327323
store(mid, f, node)
328324
)
329325
}
@@ -336,66 +332,61 @@ private boolean unbindBool(boolean b) { result != b.booleanNot() }
336332
* configuration ignoring call contexts.
337333
*/
338334
pragma[nomagic]
339-
private predicate nodeCand1(Node node, boolean stored, Configuration config) {
340-
nodeCandFwd1(node, false, config) and
341-
config.isSink(node) and
342-
stored = false
335+
private predicate nodeCand1(Node node, Configuration config) {
336+
nodeCandFwd1(node, config) and
337+
config.isSink(node)
343338
or
344-
nodeCandFwd1(node, unbindBool(stored), unbind(config)) and
339+
nodeCandFwd1(node, unbind(config)) and
345340
(
346341
exists(Node mid |
347342
localFlowStep(node, mid, config) and
348-
nodeCand1(mid, stored, config)
343+
nodeCand1(mid, config)
349344
)
350345
or
351346
exists(Node mid |
352347
additionalLocalFlowStep(node, mid, config) and
353-
nodeCand1(mid, stored, config) and
354-
stored = false
348+
nodeCand1(mid, config)
355349
)
356350
or
357351
exists(Node mid |
358352
jumpStep(node, mid, config) and
359-
nodeCand1(mid, stored, config)
353+
nodeCand1(mid, config)
360354
)
361355
or
362356
exists(Node mid |
363357
additionalJumpStep(node, mid, config) and
364-
nodeCand1(mid, stored, config) and
365-
stored = false
358+
nodeCand1(mid, config)
366359
)
367360
or
368361
// store
369362
exists(Content f |
370363
nodeCand1Store(f, node, config) and
371-
readCand1(f, config) and
372-
(stored = false or stored = true)
364+
readCand1(f, config)
373365
)
374366
or
375367
// read
376368
exists(Node mid, Content f |
377369
read(node, f, mid) and
378370
storeCandFwd1(f, unbind(config)) and
379-
nodeCand1(mid, _, config) and
380-
stored = true
371+
nodeCand1(mid, config)
381372
)
382373
or
383374
// flow into a callable
384375
exists(Node param |
385376
viableParamArg(_, param, node) and
386-
nodeCand1(param, stored, config)
377+
nodeCand1(param, config)
387378
)
388379
or
389380
// flow out of an argument
390381
exists(PostUpdateNode mid, ParameterNode p |
391382
parameterValueFlowsToUpdate(p, node) and
392383
viableParamArg(_, p, mid.getPreUpdateNode()) and
393-
nodeCand1(mid, stored, config)
384+
nodeCand1(mid, config)
394385
)
395386
or
396387
// flow out of a callable
397388
exists(DataFlowCall call, ReturnKind kind, OutNode out |
398-
nodeCand1(out, stored, config) and
389+
nodeCand1(out, config) and
399390
getReturnPosition(node) = viableReturnPos(call, kind) and
400391
out = getAnOutNode(call, kind)
401392
)
@@ -409,24 +400,24 @@ pragma[noinline]
409400
private predicate readCand1(Content f, Configuration config) {
410401
exists(Node mid, Node node |
411402
useFieldFlow(config) and
412-
nodeCandFwd1(node, true, unbind(config)) and
403+
nodeCandFwd1(node, unbind(config)) and
413404
read(node, f, mid) and
414405
storeCandFwd1(f, unbind(config)) and
415-
nodeCand1(mid, _, config)
406+
nodeCand1(mid, config)
416407
)
417408
}
418409

419410
pragma[nomagic]
420411
private predicate nodeCand1Store(Content f, Node node, Configuration config) {
421412
exists(Node mid |
422-
nodeCand1(mid, true, config) and
413+
nodeCand1(mid, config) and
423414
storeCandFwd1(f, unbind(config)) and
424415
store(node, f, mid)
425416
)
426417
}
427418

428419
private predicate throughFlowNodeCand(Node node, Configuration config) {
429-
nodeCand1(node, false, config) and
420+
nodeCand1(node, config) and
430421
not fullBarrier(node, config) and
431422
not inBarrier(node, config) and
432423
not outBarrier(node, config)
@@ -493,7 +484,7 @@ pragma[noinline]
493484
private predicate simpleArgumentFlowsThrough0(
494485
DataFlowCall call, ArgumentNode arg, ReturnKind kind, DataFlowType t, Configuration config
495486
) {
496-
nodeCand1(arg, false, unbind(config)) and
487+
nodeCand1(arg, unbind(config)) and
497488
not outBarrier(arg, config) and
498489
exists(ParameterNode p, ReturnNode ret |
499490
simpleParameterFlow(p, ret, t, config) and
@@ -513,7 +504,7 @@ private predicate simpleArgumentFlowsThrough(
513504
ArgumentNode arg, Node out, DataFlowType t, Configuration config
514505
) {
515506
exists(DataFlowCall call, ReturnKind kind |
516-
nodeCand1(out, false, unbind(config)) and
507+
nodeCand1(out, unbind(config)) and
517508
not inBarrier(out, config) and
518509
simpleArgumentFlowsThrough0(call, arg, kind, t, config) and
519510
out = getAnOutNode(call, kind)
@@ -526,10 +517,10 @@ private predicate simpleArgumentFlowsThrough(
526517
*/
527518
pragma[noinline]
528519
private predicate localFlowStepOrFlowThroughCallable(Node node1, Node node2, Configuration config) {
529-
nodeCand1(node1, _, config) and
520+
nodeCand1(node1, config) and
530521
localFlowStep(node1, node2, config)
531522
or
532-
nodeCand1(node1, _, config) and
523+
nodeCand1(node1, config) and
533524
argumentValueFlowsThrough(node1, node2, _)
534525
}
535526

@@ -542,7 +533,7 @@ pragma[noinline]
542533
private predicate additionalLocalFlowStepOrFlowThroughCallable(
543534
Node node1, Node node2, Configuration config
544535
) {
545-
nodeCand1(node1, _, config) and
536+
nodeCand1(node1, config) and
546537
additionalLocalFlowStep(node1, node2, config)
547538
or
548539
simpleArgumentFlowsThrough(node1, node2, _, config)
@@ -554,8 +545,8 @@ private predicate additionalLocalFlowStepOrFlowThroughCallable(
554545
* that this step is part of a path from a source to a sink.
555546
*/
556547
private predicate flowOutOfCallable(Node node1, Node node2, Configuration config) {
557-
nodeCand1(node1, _, unbind(config)) and
558-
nodeCand1(node2, _, config) and
548+
nodeCand1(node1, unbind(config)) and
549+
nodeCand1(node2, config) and
559550
not outBarrier(node1, config) and
560551
not inBarrier(node2, config) and
561552
(
@@ -579,8 +570,8 @@ private predicate flowOutOfCallable(Node node1, Node node2, Configuration config
579570
*/
580571
private predicate flowIntoCallable(Node node1, Node node2, Configuration config) {
581572
viableParamArg(_, node2, node1) and
582-
nodeCand1(node1, _, unbind(config)) and
583-
nodeCand1(node2, _, config) and
573+
nodeCand1(node1, unbind(config)) and
574+
nodeCand1(node2, config) and
584575
not outBarrier(node1, config) and
585576
not inBarrier(node2, config)
586577
}
@@ -646,12 +637,12 @@ private predicate flowIntoCallable(
646637
* configuration taking simple call contexts into consideration.
647638
*/
648639
private predicate nodeCandFwd2(Node node, boolean fromArg, boolean stored, Configuration config) {
649-
nodeCand1(node, false, config) and
640+
nodeCand1(node, config) and
650641
config.isSource(node) and
651642
fromArg = false and
652643
stored = false
653644
or
654-
nodeCand1(node, unbindBool(stored), unbind(config)) and
645+
nodeCand1(node, unbind(config)) and
655646
(
656647
exists(Node mid |
657648
nodeCandFwd2(mid, fromArg, stored, config) and
@@ -715,7 +706,7 @@ pragma[noinline]
715706
private predicate storeCandFwd2(Content f, Configuration config) {
716707
exists(Node mid, Node node |
717708
useFieldFlow(config) and
718-
nodeCand1(node, true, unbind(config)) and
709+
nodeCand1(node, unbind(config)) and
719710
nodeCandFwd2(mid, _, _, config) and
720711
store(mid, f, node) and
721712
readCand1(f, unbind(config))

0 commit comments

Comments
 (0)