mirror of
https://github.com/github/codeql.git
synced 2026-05-24 08:07:07 +02:00
Compare commits
373 Commits
codeql-cli
...
max-schaef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
362a1fe609 | ||
|
|
799c380e5f | ||
|
|
77a7e007e3 | ||
|
|
bea7b94537 | ||
|
|
19d0d7bbc0 | ||
|
|
c5bdd5bbd7 | ||
|
|
bcde7151e8 | ||
|
|
2c76b13451 | ||
|
|
874d9d14bc | ||
|
|
bcedf687ff | ||
|
|
57796d6d02 | ||
|
|
c45fd4080d | ||
|
|
9d83c91deb | ||
|
|
3c22bf4a25 | ||
|
|
3c0bb6f4e5 | ||
|
|
1648b427c2 | ||
|
|
e443c65c75 | ||
|
|
220abc4d36 | ||
|
|
7d4ce0a79a | ||
|
|
ac9b77a3ac | ||
|
|
abfbb47390 | ||
|
|
e7e7e4197e | ||
|
|
e9a9f56ea5 | ||
|
|
03d7f5ec73 | ||
|
|
ba99d49b61 | ||
|
|
ea2cf27432 | ||
|
|
bd1731b420 | ||
|
|
31bea7e0ca | ||
|
|
e01e8a0842 | ||
|
|
6c057ddc81 | ||
|
|
3c401d3a4f | ||
|
|
cf1cddc8ca | ||
|
|
2e50d61446 | ||
|
|
6e50357224 | ||
|
|
b9940f260f | ||
|
|
58b0bed7f3 | ||
|
|
02af978e8d | ||
|
|
9609dc4030 | ||
|
|
4aee6d506d | ||
|
|
ac34b922ec | ||
|
|
18acad516b | ||
|
|
cedc84df8f | ||
|
|
2b9c96d7cc | ||
|
|
339c40c2b7 | ||
|
|
a108fcd2b4 | ||
|
|
bcda4a1377 | ||
|
|
45b1a5e29b | ||
|
|
58832a546a | ||
|
|
9f8c9615fc | ||
|
|
b43aae18e0 | ||
|
|
06f52c2854 | ||
|
|
98a3f2da7d | ||
|
|
111ad8b525 | ||
|
|
decd576a6b | ||
|
|
622f69e1a1 | ||
|
|
3c885f3969 | ||
|
|
3c83262d58 | ||
|
|
77d0df4fb6 | ||
|
|
c11adc8c28 | ||
|
|
43df0cd5f4 | ||
|
|
a1267d732e | ||
|
|
da33c220a6 | ||
|
|
212a0f27ff | ||
|
|
2f56ec7fe0 | ||
|
|
80c3993ddc | ||
|
|
3ad2d90014 | ||
|
|
611f98bca4 | ||
|
|
544660322f | ||
|
|
f08a598821 | ||
|
|
4d3d07a964 | ||
|
|
dc4cc74cbb | ||
|
|
eab96988bf | ||
|
|
2dcb5fbd16 | ||
|
|
3eb4e39251 | ||
|
|
6f782f3f62 | ||
|
|
55b9724f59 | ||
|
|
0a7af90454 | ||
|
|
902f0f91b0 | ||
|
|
5e7026c6c6 | ||
|
|
da3fa22cbd | ||
|
|
592ca06159 | ||
|
|
96ba3ec88e | ||
|
|
eb2790ae63 | ||
|
|
d22e2bae8e | ||
|
|
b2974ba1c6 | ||
|
|
b201fd0bdd | ||
|
|
bc0e580683 | ||
|
|
f78ea26c3b | ||
|
|
93a9c62e29 | ||
|
|
7434a58afc | ||
|
|
ed80e4e284 | ||
|
|
c4eeda1560 | ||
|
|
7faf3a8b8e | ||
|
|
dd97e70ffc | ||
|
|
1847a6deb0 | ||
|
|
fdddec74d3 | ||
|
|
bf8307f78d | ||
|
|
3335d48154 | ||
|
|
c0db40d11a | ||
|
|
be64daf265 | ||
|
|
ee5cb6f3d8 | ||
|
|
844b29b637 | ||
|
|
5c50ed036c | ||
|
|
62299dc95a | ||
|
|
48e367cb11 | ||
|
|
8f82db07d3 | ||
|
|
ba9267df5b | ||
|
|
4cb0695646 | ||
|
|
c3cf425079 | ||
|
|
dd656d34be | ||
|
|
c647f30576 | ||
|
|
7155af50be | ||
|
|
6ba27dc863 | ||
|
|
622e176a16 | ||
|
|
4a4f9b3942 | ||
|
|
e7bfd7df62 | ||
|
|
543032a3de | ||
|
|
f69737b407 | ||
|
|
c720fb2c34 | ||
|
|
4886bb1116 | ||
|
|
8888ee9fa8 | ||
|
|
69d8fa6e4a | ||
|
|
ae0e25e5b1 | ||
|
|
2627a3dcb7 | ||
|
|
e1884c193b | ||
|
|
6cb5db2387 | ||
|
|
439afd97ba | ||
|
|
132bb9f1d6 | ||
|
|
58635bdbd6 | ||
|
|
e99c78e027 | ||
|
|
75b1e14098 | ||
|
|
6bf05eb29a | ||
|
|
fb9fc14f3d | ||
|
|
8630630c45 | ||
|
|
54957d6ea4 | ||
|
|
f57e0cb71e | ||
|
|
ec862ebc72 | ||
|
|
9671e05148 | ||
|
|
3567c30020 | ||
|
|
ff55ed84f4 | ||
|
|
13a71a4f6d | ||
|
|
3105697c7f | ||
|
|
8747438613 | ||
|
|
82057e2e46 | ||
|
|
25cb52aa52 | ||
|
|
8ec414d454 | ||
|
|
b22b4c5b85 | ||
|
|
e45f6e9b24 | ||
|
|
8915241166 | ||
|
|
336a18a1d9 | ||
|
|
ddfed6ea65 | ||
|
|
72ffcf5f9c | ||
|
|
f7e5fe7040 | ||
|
|
1c66e26e92 | ||
|
|
6e130d24cd | ||
|
|
5125468307 | ||
|
|
f3a5ce5efc | ||
|
|
6f08790065 | ||
|
|
2cbc59b7a1 | ||
|
|
9302b167d8 | ||
|
|
e13b3ed5e7 | ||
|
|
e29ce5f5d5 | ||
|
|
1df1f0dbc2 | ||
|
|
0235e9962e | ||
|
|
3949ae4123 | ||
|
|
330229c463 | ||
|
|
52be6579b7 | ||
|
|
1c8298ae08 | ||
|
|
d88a813038 | ||
|
|
254c6c3344 | ||
|
|
e7dc120456 | ||
|
|
ceb5b4c56e | ||
|
|
9d8b93ed45 | ||
|
|
fdb77457b3 | ||
|
|
04de315e0e | ||
|
|
dc34cb0aae | ||
|
|
bdd6fba06a | ||
|
|
15eabb42ef | ||
|
|
f799962146 | ||
|
|
cb3a59446c | ||
|
|
e70a49a771 | ||
|
|
db48461ebc | ||
|
|
ac2769c142 | ||
|
|
829557fdda | ||
|
|
c12c2a534c | ||
|
|
5323af33d2 | ||
|
|
96ef6809a7 | ||
|
|
312b96aa8b | ||
|
|
8cc4f86e7d | ||
|
|
32595b92a2 | ||
|
|
13100b19bc | ||
|
|
66f88d9c71 | ||
|
|
477322d21d | ||
|
|
846eac8be9 | ||
|
|
8842b974f0 | ||
|
|
65b69fe353 | ||
|
|
2a914770ea | ||
|
|
d030f0b5d2 | ||
|
|
33364a8ab6 | ||
|
|
d8bd18f369 | ||
|
|
3e1359b92e | ||
|
|
4c4d2415e9 | ||
|
|
34a0c02f70 | ||
|
|
5c4e02a1da | ||
|
|
21bc8c4324 | ||
|
|
19b14e166d | ||
|
|
3d96206783 | ||
|
|
959300f963 | ||
|
|
41ce4ffe4b | ||
|
|
eca112c3bc | ||
|
|
250cb30c05 | ||
|
|
dd96095a30 | ||
|
|
d5160927f5 | ||
|
|
925ee825ff | ||
|
|
36db493723 | ||
|
|
cbab24ba45 | ||
|
|
e0f866f19d | ||
|
|
138975e4a8 | ||
|
|
783ce48538 | ||
|
|
8a92a4250f | ||
|
|
1264e6e292 | ||
|
|
e9cd2dc9e1 | ||
|
|
16e2ac898f | ||
|
|
4d5f158652 | ||
|
|
f5355cfa98 | ||
|
|
1985dd629d | ||
|
|
82101434fd | ||
|
|
8cb80d6014 | ||
|
|
81b96a8041 | ||
|
|
29a61458e0 | ||
|
|
56ebe6c727 | ||
|
|
f2ea88aa4c | ||
|
|
9313564e64 | ||
|
|
ef7767b6cd | ||
|
|
3022c59654 | ||
|
|
ab3c03d2d6 | ||
|
|
f4e05cc621 | ||
|
|
946f0b4dc4 | ||
|
|
348c95ebe1 | ||
|
|
c55e03c588 | ||
|
|
acef9b7111 | ||
|
|
13734d4e62 | ||
|
|
70bb29581d | ||
|
|
448a9015c0 | ||
|
|
21592563cb | ||
|
|
ac7a25734b | ||
|
|
334c0d0449 | ||
|
|
fc26e148fd | ||
|
|
e3ce7c608b | ||
|
|
087d689997 | ||
|
|
af2a7eadc3 | ||
|
|
fb15a4ea11 | ||
|
|
c0c1ab7006 | ||
|
|
31a246b554 | ||
|
|
06d369ba11 | ||
|
|
b2b2c2016c | ||
|
|
ec515f967d | ||
|
|
9917c3c5ba | ||
|
|
fae002fbb7 | ||
|
|
4831ee65b6 | ||
|
|
bdc3d10cdb | ||
|
|
49ef677b1d | ||
|
|
144c19db74 | ||
|
|
a8742ea111 | ||
|
|
db60360293 | ||
|
|
9c4567bd6d | ||
|
|
f2ef4ad6ac | ||
|
|
57beb73bf7 | ||
|
|
f1ead2554f | ||
|
|
33164c8a43 | ||
|
|
fa26b55452 | ||
|
|
16f9ad06ef | ||
|
|
891f05c5ae | ||
|
|
5618001c3f | ||
|
|
03d0d984e3 | ||
|
|
a55f07ac68 | ||
|
|
103932fec8 | ||
|
|
507ada1951 | ||
|
|
8fbbc2b6d8 | ||
|
|
ce52cbb428 | ||
|
|
76780d74d9 | ||
|
|
95db7aa776 | ||
|
|
58737b1d7e | ||
|
|
0a33a6e79b | ||
|
|
cf35fd4dee | ||
|
|
cdafb26423 | ||
|
|
88ea9197d9 | ||
|
|
46b8e3be66 | ||
|
|
dec5fc0f48 | ||
|
|
40270e1f70 | ||
|
|
b598b4ac45 | ||
|
|
73e95d67b9 | ||
|
|
393bd7277c | ||
|
|
af4320df50 | ||
|
|
14deb06e80 | ||
|
|
638bfff09d | ||
|
|
19cc620f18 | ||
|
|
f208594067 | ||
|
|
8d3fc735ea | ||
|
|
f52b6e0449 | ||
|
|
6019a38266 | ||
|
|
23da0c16c7 | ||
|
|
7c4927c2e3 | ||
|
|
fcda0c9819 | ||
|
|
c17a36ec07 | ||
|
|
92d57ab504 | ||
|
|
9aad43f649 | ||
|
|
cbacd51337 | ||
|
|
22d5e9bbfb | ||
|
|
900c8b71d8 | ||
|
|
a27949cffa | ||
|
|
026a13b4db | ||
|
|
4bc272da73 | ||
|
|
e8d0f1fa3e | ||
|
|
23fd3f62ac | ||
|
|
26ef1bc249 | ||
|
|
18d9573b6a | ||
|
|
8c0f02ac4b | ||
|
|
3657269d3e | ||
|
|
d1fc700735 | ||
|
|
7675f153ce | ||
|
|
d1a2048134 | ||
|
|
340a17dd74 | ||
|
|
dbf0b98791 | ||
|
|
f649939d78 | ||
|
|
2e5f7dc8fc | ||
|
|
8faad92cfd | ||
|
|
0df10bda0c | ||
|
|
1da611cc02 | ||
|
|
bc42e2bc35 | ||
|
|
5787dcc82d | ||
|
|
356214c11b | ||
|
|
5683092d6a | ||
|
|
1ace9ee50f | ||
|
|
e1a5a84253 | ||
|
|
6e13b877bb | ||
|
|
e187a4a7d6 | ||
|
|
0c3aa7b7f2 | ||
|
|
8bdb67cc15 | ||
|
|
4eae191430 | ||
|
|
4728cf5a12 | ||
|
|
cd41a1ca8c | ||
|
|
3719e10ce8 | ||
|
|
52a1d905f1 | ||
|
|
a354ab84e9 | ||
|
|
e98485df7f | ||
|
|
f6b412e1c9 | ||
|
|
d1e040e27c | ||
|
|
a9b2876b71 | ||
|
|
66d8943c08 | ||
|
|
25200b47ea | ||
|
|
a5527903e9 | ||
|
|
7514037464 | ||
|
|
649af822fd | ||
|
|
5caa49aeab | ||
|
|
2bea0adb92 | ||
|
|
cfc1a3db22 | ||
|
|
e0d70e3008 | ||
|
|
a727255a82 | ||
|
|
c10f41b168 | ||
|
|
4c1f433073 | ||
|
|
963e0a730d | ||
|
|
42571069bf | ||
|
|
017369c6f2 | ||
|
|
cc2b61186e | ||
|
|
dd27ef7d3c | ||
|
|
833165f86c | ||
|
|
c85262cfd0 | ||
|
|
a8863e44db | ||
|
|
3aacc5ffde | ||
|
|
fbf9545338 | ||
|
|
303882350b | ||
|
|
9611e4ce19 |
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -67,11 +67,6 @@ go/extractor/opencsv/CSVReader.java -text
|
||||
# for those testing dbscheme files.
|
||||
*/ql/lib/upgrades/initial/*.dbscheme -text
|
||||
|
||||
# Generated test files - these are synced from the standard JavaScript libraries using
|
||||
# `javascript/ql/experimental/adaptivethreatmodeling/test/update_endpoint_test_files.py`.
|
||||
javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/**/*.js linguist-generated=true -merge
|
||||
javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/autogenerated/**/*.ts linguist-generated=true -merge
|
||||
|
||||
# Auto-generated modeling for Python
|
||||
python/ql/lib/semmle/python/frameworks/data/internal/subclass-capture/*.yml linguist-generated=true
|
||||
|
||||
|
||||
5
.github/labeler.yml
vendored
5
.github/labeler.yml
vendored
@@ -15,7 +15,7 @@ Java:
|
||||
- change-notes/**/*java.*
|
||||
|
||||
JS:
|
||||
- any: [ 'javascript/**/*', '!javascript/ql/experimental/adaptivethreatmodeling/**/*' ]
|
||||
- any: [ 'javascript/**/*' ]
|
||||
- change-notes/**/*javascript*
|
||||
|
||||
Kotlin:
|
||||
@@ -46,6 +46,3 @@ documentation:
|
||||
# Since these are all shared files that need to be synced, just pick _one_ copy of each.
|
||||
"DataFlow Library":
|
||||
- "shared/dataflow/**/*"
|
||||
|
||||
"ATM":
|
||||
- javascript/ql/experimental/adaptivethreatmodeling/**/*
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
/java/ql/test-kotlin1/ @github/codeql-kotlin
|
||||
/java/ql/test-kotlin2/ @github/codeql-kotlin
|
||||
|
||||
# ML-powered queries
|
||||
/javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers
|
||||
|
||||
# CodeQL tools and associated docs
|
||||
/docs/codeql/codeql-cli/ @github/codeql-cli-reviewers
|
||||
/docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
|
||||
@@ -37,9 +34,7 @@ MODULE.bazel @github/codeql-ci-reviewers
|
||||
|
||||
# Workflows
|
||||
/.github/workflows/ @github/codeql-ci-reviewers
|
||||
/.github/workflows/atm-* @github/codeql-ml-powered-queries-reviewers
|
||||
/.github/workflows/go-* @github/codeql-go
|
||||
/.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers
|
||||
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
|
||||
/.github/workflows/ruby-* @github/codeql-ruby
|
||||
/.github/workflows/swift.yml @github/codeql-swift
|
||||
|
||||
@@ -14,7 +14,7 @@ local_path_override(
|
||||
# see https://registry.bazel.build/ for a list of available packages
|
||||
|
||||
bazel_dep(name = "platforms", version = "0.0.8")
|
||||
bazel_dep(name = "rules_pkg", version = "0.9.1")
|
||||
bazel_dep(name = "rules_pkg", version = "0.10.1")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.0.3")
|
||||
bazel_dep(name = "rules_python", version = "0.31.0")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.5.0")
|
||||
|
||||
@@ -11,16 +11,6 @@ provide:
|
||||
- "cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml"
|
||||
- "go/ql/config/legacy-support/qlpack.yml"
|
||||
- "go/build/codeql-extractor-go/codeql-extractor.yml"
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml"
|
||||
# This pack is explicitly excluded from the workspace since most users
|
||||
# will want to use a version of this pack from the package cache. Internal
|
||||
# users can uncomment the following line and place a custom ML model
|
||||
# in the corresponding pack to test a custom ML model within their local
|
||||
# checkout.
|
||||
# - "javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml"
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml"
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml"
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/test/qlpack.yml"
|
||||
- "csharp/ql/campaigns/Solorigate/lib/qlpack.yml"
|
||||
- "csharp/ql/campaigns/Solorigate/src/qlpack.yml"
|
||||
- "csharp/ql/campaigns/Solorigate/test/qlpack.yml"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_filegroup")
|
||||
load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
|
||||
load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix")
|
||||
|
||||
pkg_files(
|
||||
name = "downgrades",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files")
|
||||
load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
|
||||
|
||||
package(default_visibility = ["//cpp:__pkg__"])
|
||||
|
||||
|
||||
4
cpp/ql/lib/change-notes/2024-04-05-sound-ir.md
Normal file
4
cpp/ql/lib/change-notes/2024-04-05-sound-ir.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The alias analysis used internally by various libraries has been improved to answer alias questions more conservatively. As a result, some queries may report fewer false positives.
|
||||
4
cpp/ql/lib/change-notes/2024-04-18-param-nodes.md
Normal file
4
cpp/ql/lib/change-notes/2024-04-18-param-nodes.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Parameters of functions without definitions now have `ParameterNode`s.
|
||||
4
cpp/ql/lib/change-notes/2024-10-04-getc.md
Normal file
4
cpp/ql/lib/change-notes/2024-10-04-getc.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Source models have been added for the standard library function `getc` (and variations).
|
||||
4
cpp/ql/lib/change-notes/2024-10-04-models-as-data.md
Normal file
4
cpp/ql/lib/change-notes/2024-10-04-models-as-data.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Models-as-Data support has been added for C/C++. This feature allows flow sources, sinks and summaries to be expressed in compact strings as an alternative to modelling each source / sink / summary with explicit QL. See `dataflow/ExternalFlow.qll` for documentation and specification of the model format, and `models/implementations/ZMQ.qll` for a simple example of models. Importing models from `.yml` is not yet supported.
|
||||
4
cpp/ql/lib/change-notes/2024-10-04-zmq.md
Normal file
4
cpp/ql/lib/change-notes/2024-10-04-zmq.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Source, sink and flow models for the ZeroMQ (ZMQ) networking library have been added.
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.12.11
|
||||
version: 0.12.12-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
@@ -7,6 +7,7 @@ library: true
|
||||
upgrades: upgrades
|
||||
dependencies:
|
||||
codeql/dataflow: ${workspace}
|
||||
codeql/mad: ${workspace}
|
||||
codeql/rangeanalysis: ${workspace}
|
||||
codeql/ssa: ${workspace}
|
||||
codeql/typeflow: ${workspace}
|
||||
|
||||
556
cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
Normal file
556
cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
Normal file
@@ -0,0 +1,556 @@
|
||||
/**
|
||||
* INTERNAL use only. This is an experimental API subject to change without notice.
|
||||
*
|
||||
* Provides classes and predicates for dealing with flow models specified in CSV format.
|
||||
*
|
||||
* The CSV specification has the following columns:
|
||||
* - Sources:
|
||||
* `namespace; type; subtypes; name; signature; ext; output; kind`
|
||||
* - Sinks:
|
||||
* `namespace; type; subtypes; name; signature; ext; input; kind`
|
||||
* - Summaries:
|
||||
* `namespace; type; subtypes; name; signature; ext; input; output; kind`
|
||||
*
|
||||
* The interpretation of a row is similar to API-graphs with a left-to-right
|
||||
* reading.
|
||||
* 1. The `namespace` column selects a namespace.
|
||||
* 2. The `type` column selects a type within that namespace.
|
||||
* 3. The `subtypes` is a boolean that indicates whether to jump to an
|
||||
* arbitrary subtype of that type. Set this to `false` if leaving the `type`
|
||||
* blank (for example, a free function).
|
||||
* 4. The `name` column optionally selects a specific named member of the type.
|
||||
* 5. The `signature` column optionally restricts the named member. If
|
||||
* `signature` is blank then no such filtering is done. The format of the
|
||||
* signature is a comma-separated list of types enclosed in parentheses. The
|
||||
* types can be short names or fully qualified names (mixing these two options
|
||||
* is not allowed within a single signature).
|
||||
* 6. The `ext` column specifies additional API-graph-like edges. Currently
|
||||
* there is only one valid value: "".
|
||||
* 7. The `input` column specifies how data enters the element selected by the
|
||||
* first 6 columns, and the `output` column specifies how data leaves the
|
||||
* element selected by the first 6 columns. An `input` can be either:
|
||||
* - "": Selects a write to the selected element in case this is a field.
|
||||
* - "Argument[n]": Selects an argument in a call to the selected element.
|
||||
* The arguments are zero-indexed, and `-1` specifies the qualifier object,
|
||||
* that is, `*this`.
|
||||
* - one or more "*" can be added in front of the argument index to indicate
|
||||
* indirection, for example, `Argument[*0]` indicates the first indirection
|
||||
* of the 0th argument.
|
||||
* - `n1..n2` syntax can be used to indicate a range of arguments, inclusive
|
||||
* at both ends. One or more "*"s can be added in front of the whole range
|
||||
* to indicate that every argument in the range is indirect, for example
|
||||
* `*0..1` is the first indirection of both arguments 0 and 1.
|
||||
* - "ReturnValue": Selects a value being returned by the selected element.
|
||||
* One or more "*" can be added as an argument to indicate indirection, for
|
||||
* example, "ReturnValue[*]" indicates the first indirection of the return
|
||||
* value.
|
||||
*
|
||||
* An `output` can be either:
|
||||
* - "": Selects a read of a selected field.
|
||||
* - "Argument[n]": Selects the post-update value of an argument in a call to
|
||||
* the selected element. That is, the value of the argument after the call
|
||||
* returns. The arguments are zero-indexed, and `-1` specifies the qualifier
|
||||
* object, that is, `*this`.
|
||||
* - one or more "*" can be added in front of the argument index to indicate
|
||||
* indirection, for example, `Argument[*0]` indicates the first indirection
|
||||
* of the 0th argument.
|
||||
* - `n1..n2` syntax can be used to indicate a range of arguments, inclusive
|
||||
* at both ends. One or more "*"s can be added in front of the whole range
|
||||
* to indicate that every argument in the range is indirect, for example
|
||||
* `*0..1` is the first indirection of both arguments 0 and 1.
|
||||
* - "Parameter[n]": Selects the value of a parameter of the selected element.
|
||||
* The syntax is the same as for "Argument", for example "Parameter[0]",
|
||||
* "Parameter[*0]", "Parameter[0..2]" etc.
|
||||
* - "ReturnValue": Selects a value being returned by the selected element.
|
||||
* One or more "*" can be added as an argument to indicate indirection, for
|
||||
* example, "ReturnValue[*]" indicates the first indirection of the return
|
||||
* value.
|
||||
* 8. The `kind` column is a tag that can be referenced from QL to determine to
|
||||
* which classes the interpreted elements should be added. For example, for
|
||||
* sources "remote" indicates a default remote flow source, and for summaries
|
||||
* "taint" indicates a default additional taint step and "value" indicates a
|
||||
* globally applicable value-preserving step.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
private import new.DataFlow
|
||||
private import internal.FlowSummaryImpl
|
||||
private import internal.FlowSummaryImpl::Public
|
||||
private import internal.FlowSummaryImpl::Private
|
||||
private import internal.FlowSummaryImpl::Private::External
|
||||
private import codeql.mad.ModelValidation as SharedModelVal
|
||||
private import codeql.util.Unit
|
||||
|
||||
/**
|
||||
* A unit class for adding additional source model rows.
|
||||
*
|
||||
* Extend this class to add additional source definitions.
|
||||
*/
|
||||
class SourceModelCsv extends Unit {
|
||||
/** Holds if `row` specifies a source definition. */
|
||||
abstract predicate row(string row);
|
||||
}
|
||||
|
||||
/**
|
||||
* A unit class for adding additional sink model rows.
|
||||
*
|
||||
* Extend this class to add additional sink definitions.
|
||||
*/
|
||||
class SinkModelCsv extends Unit {
|
||||
/** Holds if `row` specifies a sink definition. */
|
||||
abstract predicate row(string row);
|
||||
}
|
||||
|
||||
/**
|
||||
* A unit class for adding additional summary model rows.
|
||||
*
|
||||
* Extend this class to add additional flow summary definitions.
|
||||
*/
|
||||
class SummaryModelCsv extends Unit {
|
||||
/** Holds if `row` specifies a summary definition. */
|
||||
abstract predicate row(string row);
|
||||
}
|
||||
|
||||
/** Holds if `row` is a source model. */
|
||||
predicate sourceModel(string row) { any(SourceModelCsv s).row(row) }
|
||||
|
||||
/** Holds if `row` is a sink model. */
|
||||
predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
|
||||
|
||||
/** Holds if `row` is a summary model. */
|
||||
predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
|
||||
|
||||
/** Holds if a source model exists for the given parameters. */
|
||||
predicate sourceModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string output, string kind, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
sourceModel(row) and
|
||||
row.splitAt(";", 0) = namespace and
|
||||
row.splitAt(";", 1) = type and
|
||||
row.splitAt(";", 2) = subtypes.toString() and
|
||||
subtypes = [true, false] and
|
||||
row.splitAt(";", 3) = name and
|
||||
row.splitAt(";", 4) = signature and
|
||||
row.splitAt(";", 5) = ext and
|
||||
row.splitAt(";", 6) = output and
|
||||
row.splitAt(";", 7) = kind
|
||||
) and
|
||||
provenance = "manual"
|
||||
}
|
||||
|
||||
/** Holds if a sink model exists for the given parameters. */
|
||||
predicate sinkModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string kind, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
sinkModel(row) and
|
||||
row.splitAt(";", 0) = namespace and
|
||||
row.splitAt(";", 1) = type and
|
||||
row.splitAt(";", 2) = subtypes.toString() and
|
||||
subtypes = [true, false] and
|
||||
row.splitAt(";", 3) = name and
|
||||
row.splitAt(";", 4) = signature and
|
||||
row.splitAt(";", 5) = ext and
|
||||
row.splitAt(";", 6) = input and
|
||||
row.splitAt(";", 7) = kind
|
||||
) and
|
||||
provenance = "manual"
|
||||
}
|
||||
|
||||
/** Holds if a summary model exists for the given parameters. */
|
||||
predicate summaryModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string output, string kind, string provenance
|
||||
) {
|
||||
exists(string row |
|
||||
summaryModel(row) and
|
||||
row.splitAt(";", 0) = namespace and
|
||||
row.splitAt(";", 1) = type and
|
||||
row.splitAt(";", 2) = subtypes.toString() and
|
||||
subtypes = [true, false] and
|
||||
row.splitAt(";", 3) = name and
|
||||
row.splitAt(";", 4) = signature and
|
||||
row.splitAt(";", 5) = ext and
|
||||
row.splitAt(";", 6) = input and
|
||||
row.splitAt(";", 7) = output and
|
||||
row.splitAt(";", 8) = kind
|
||||
) and
|
||||
provenance = "manual"
|
||||
}
|
||||
|
||||
private predicate relevantNamespace(string namespace) {
|
||||
sourceModel(namespace, _, _, _, _, _, _, _, _) or
|
||||
sinkModel(namespace, _, _, _, _, _, _, _, _) or
|
||||
summaryModel(namespace, _, _, _, _, _, _, _, _, _)
|
||||
}
|
||||
|
||||
private predicate namespaceLink(string shortns, string longns) {
|
||||
relevantNamespace(shortns) and
|
||||
relevantNamespace(longns) and
|
||||
longns.prefix(longns.indexOf("::")) = shortns
|
||||
}
|
||||
|
||||
private predicate canonicalNamespace(string namespace) {
|
||||
relevantNamespace(namespace) and not namespaceLink(_, namespace)
|
||||
}
|
||||
|
||||
private predicate canonicalNamespaceLink(string namespace, string subns) {
|
||||
canonicalNamespace(namespace) and
|
||||
(subns = namespace or namespaceLink(namespace, subns))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if CSV framework coverage of `namespace` is `n` api endpoints of the
|
||||
* kind `(kind, part)`.
|
||||
*/
|
||||
predicate modelCoverage(string namespace, int namespaces, string kind, string part, int n) {
|
||||
namespaces = strictcount(string subns | canonicalNamespaceLink(namespace, subns)) and
|
||||
(
|
||||
part = "source" and
|
||||
n =
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string output, string provenance |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance)
|
||||
)
|
||||
or
|
||||
part = "sink" and
|
||||
n =
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string input, string provenance |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance)
|
||||
)
|
||||
or
|
||||
part = "summary" and
|
||||
n =
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string input, string output, string provenance |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Provides a query predicate to check the CSV data for validation errors. */
|
||||
module CsvValidation {
|
||||
private string getInvalidModelInput() {
|
||||
exists(string pred, AccessPath input, string part |
|
||||
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
|
||||
or
|
||||
summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary"
|
||||
|
|
||||
(
|
||||
invalidSpecComponent(input, part) and
|
||||
not part = "" and
|
||||
not (part = "Argument" and pred = "sink") and
|
||||
not parseArg(part, _)
|
||||
or
|
||||
part = input.getToken(_) and
|
||||
parseParam(part, _)
|
||||
) and
|
||||
result = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
|
||||
)
|
||||
}
|
||||
|
||||
private string getInvalidModelOutput() {
|
||||
exists(string pred, string output, string part |
|
||||
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
|
||||
or
|
||||
summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary"
|
||||
|
|
||||
invalidSpecComponent(output, part) and
|
||||
not part = "" and
|
||||
not (part = ["Argument", "Parameter"] and pred = "source") and
|
||||
result = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
|
||||
)
|
||||
}
|
||||
|
||||
private module KindValConfig implements SharedModelVal::KindValidationConfigSig {
|
||||
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) }
|
||||
|
||||
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) }
|
||||
|
||||
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) }
|
||||
}
|
||||
|
||||
private module KindVal = SharedModelVal::KindValidation<KindValConfig>;
|
||||
|
||||
private string getInvalidModelSubtype() {
|
||||
exists(string pred, string row |
|
||||
sourceModel(row) and pred = "source"
|
||||
or
|
||||
sinkModel(row) and pred = "sink"
|
||||
or
|
||||
summaryModel(row) and pred = "summary"
|
||||
|
|
||||
exists(string b |
|
||||
b = row.splitAt(";", 2) and
|
||||
not b = ["true", "false"] and
|
||||
result = "Invalid boolean \"" + b + "\" in " + pred + " model."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private string getInvalidModelColumnCount() {
|
||||
exists(string pred, string row, int expect |
|
||||
sourceModel(row) and expect = 8 and pred = "source"
|
||||
or
|
||||
sinkModel(row) and expect = 8 and pred = "sink"
|
||||
or
|
||||
summaryModel(row) and expect = 9 and pred = "summary"
|
||||
|
|
||||
exists(int cols |
|
||||
cols = 1 + max(int n | exists(row.splitAt(";", n))) and
|
||||
cols != expect and
|
||||
result =
|
||||
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
|
||||
"."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private string getInvalidModelSignature() {
|
||||
exists(string pred, string namespace, string type, string name, string signature, string ext |
|
||||
sourceModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "source"
|
||||
or
|
||||
sinkModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "sink"
|
||||
or
|
||||
summaryModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "summary"
|
||||
|
|
||||
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
|
||||
result = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
|
||||
or
|
||||
not type.regexpMatch("[a-zA-Z0-9_<>,\\+]+") and
|
||||
result = "Dubious type \"" + type + "\" in " + pred + " model."
|
||||
or
|
||||
not name.regexpMatch("[a-zA-Z0-9_<>,]*") and
|
||||
result = "Dubious member name \"" + name + "\" in " + pred + " model."
|
||||
or
|
||||
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+\\*,\\[\\]]*\\)") and
|
||||
result = "Dubious signature \"" + signature + "\" in " + pred + " model."
|
||||
or
|
||||
not ext.regexpMatch("|Attribute") and
|
||||
result = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if some row in a CSV-based flow model appears to contain typos. */
|
||||
query predicate invalidModelRow(string msg) {
|
||||
msg =
|
||||
[
|
||||
getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(),
|
||||
getInvalidModelSubtype(), getInvalidModelColumnCount(), KindVal::getInvalidModelKind()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private predicate elementSpec(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
) {
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
|
||||
}
|
||||
|
||||
private string paramsStringPart(Function c, int i) {
|
||||
i = -1 and result = "(" and exists(c)
|
||||
or
|
||||
exists(int n, string p | c.getParameter(n).getType().toString() = p |
|
||||
i = 2 * n and result = p
|
||||
or
|
||||
i = 2 * n - 1 and result = "," and n != 0
|
||||
)
|
||||
or
|
||||
i = 2 * c.getNumberOfParameters() and result = ")"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a parenthesized string containing all parameter types of this callable, separated by a comma.
|
||||
*
|
||||
* Returns the empty string if the callable has no parameters.
|
||||
* Parameter types are represented by their type erasure.
|
||||
*/
|
||||
cached
|
||||
private string paramsString(Function c) {
|
||||
result = concat(int i | | paramsStringPart(c, i) order by i)
|
||||
}
|
||||
|
||||
bindingset[func]
|
||||
private predicate matchesSignature(Function func, string signature) {
|
||||
signature = "" or
|
||||
paramsString(func) = signature
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the element in module `namespace` that satisfies the following properties:
|
||||
* 1. If the element is a member of a class-like type, then the class-like type has name `type`
|
||||
* 2. If `subtypes = true` and the element is a member of a class-like type, then overrides of the element
|
||||
* are also returned.
|
||||
* 3. The element has name `name`
|
||||
* 4. If `signature` is non-empty, then the element has a list of parameter types described by `signature`.
|
||||
*
|
||||
* NOTE: `namespace` is currently not used (since we don't properly extract modules yet).
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private Element interpretElement0(
|
||||
string namespace, string type, boolean subtypes, string name, string signature
|
||||
) {
|
||||
elementSpec(namespace, type, subtypes, name, signature, _) and
|
||||
(
|
||||
// Non-member functions
|
||||
exists(Function func |
|
||||
func.hasQualifiedName(namespace, name) and
|
||||
type = "" and
|
||||
matchesSignature(func, signature) and
|
||||
subtypes = false and
|
||||
not exists(func.getDeclaringType()) and
|
||||
result = func
|
||||
)
|
||||
or
|
||||
// Member functions
|
||||
exists(Class namedClass, Class classWithMethod, Function method |
|
||||
classWithMethod = method.getClassAndName(name) and
|
||||
namedClass.hasQualifiedName(namespace, type) and
|
||||
matchesSignature(method, signature) and
|
||||
result = method
|
||||
|
|
||||
// member declared in the named type or a subtype of it
|
||||
subtypes = true and
|
||||
classWithMethod = namedClass.getADerivedClass*()
|
||||
or
|
||||
// member declared directly in the named type
|
||||
subtypes = false and
|
||||
classWithMethod = namedClass
|
||||
)
|
||||
or
|
||||
// Member variables
|
||||
signature = "" and
|
||||
exists(Class namedClass, Class classWithMember, MemberVariable member |
|
||||
member.getName() = name and
|
||||
member = classWithMember.getAMember() and
|
||||
namedClass.hasQualifiedName(namespace, type) and
|
||||
result = member
|
||||
|
|
||||
// field declared in the named type or a subtype of it (or an extension of any)
|
||||
subtypes = true and
|
||||
classWithMember = namedClass.getADerivedClass*()
|
||||
or
|
||||
// field declared directly in the named type (or an extension of it)
|
||||
subtypes = false and
|
||||
classWithMember = namedClass
|
||||
)
|
||||
or
|
||||
// Global or namespace variables
|
||||
signature = "" and
|
||||
type = "" and
|
||||
subtypes = false and
|
||||
result = any(GlobalOrNamespaceVariable v | v.hasQualifiedName(namespace, name))
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the source/sink/summary element corresponding to the supplied parameters. */
|
||||
Element interpretElement(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
) {
|
||||
elementSpec(namespace, type, subtypes, name, signature, ext) and
|
||||
exists(Element e | e = interpretElement0(namespace, type, subtypes, name, signature) |
|
||||
ext = "" and result = e
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
* Holds if `node` is specified as a source with the given kind in a CSV flow
|
||||
* model.
|
||||
*/
|
||||
cached
|
||||
predicate sourceNode(DataFlow::Node node, string kind) {
|
||||
exists(SourceSinkInterpretationInput::InterpretNode n |
|
||||
isSourceNode(n, kind, _) and n.asNode() = node // TODO
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is specified as a sink with the given kind in a CSV flow
|
||||
* model.
|
||||
*/
|
||||
cached
|
||||
predicate sinkNode(DataFlow::Node node, string kind) {
|
||||
exists(SourceSinkInterpretationInput::InterpretNode n |
|
||||
isSinkNode(n, kind, _) and n.asNode() = node // TODO
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
private predicate interpretSummary(
|
||||
Function f, string input, string output, string kind, string provenance
|
||||
) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) and
|
||||
f = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
// adapter class for converting Mad summaries to `SummarizedCallable`s
|
||||
private class SummarizedCallableAdapter extends SummarizedCallable {
|
||||
SummarizedCallableAdapter() { interpretSummary(this, _, _, _, _) }
|
||||
|
||||
private predicate relevantSummaryElementManual(string input, string output, string kind) {
|
||||
exists(Provenance provenance |
|
||||
interpretSummary(this, input, output, kind, provenance) and
|
||||
provenance.isManual()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElementGenerated(string input, string output, string kind) {
|
||||
exists(Provenance provenance |
|
||||
interpretSummary(this, input, output, kind, provenance) and
|
||||
provenance.isGenerated()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate propagatesFlow(
|
||||
string input, string output, boolean preservesValue, string model
|
||||
) {
|
||||
exists(string kind |
|
||||
this.relevantSummaryElementManual(input, output, kind)
|
||||
or
|
||||
not this.relevantSummaryElementManual(_, _, _) and
|
||||
this.relevantSummaryElementGenerated(input, output, kind)
|
||||
|
|
||||
if kind = "value" then preservesValue = true else preservesValue = false
|
||||
) and
|
||||
model = "" // TODO
|
||||
}
|
||||
|
||||
override predicate hasProvenance(Provenance provenance) {
|
||||
interpretSummary(this, _, _, _, provenance)
|
||||
}
|
||||
}
|
||||
|
||||
// adapter class for converting Mad neutrals to `NeutralCallable`s
|
||||
private class NeutralCallableAdapter extends NeutralCallable {
|
||||
string kind;
|
||||
string provenance_;
|
||||
|
||||
NeutralCallableAdapter() {
|
||||
// Neutral models have not been implemented for CPP.
|
||||
none() and
|
||||
exists(this) and
|
||||
exists(kind) and
|
||||
exists(provenance_)
|
||||
}
|
||||
|
||||
override string getKind() { result = kind }
|
||||
|
||||
override predicate hasProvenance(Provenance provenance) { provenance = provenance_ }
|
||||
}
|
||||
271
cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
Normal file
271
cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
* Provides classes and predicates for defining flow summaries.
|
||||
*/
|
||||
|
||||
private import cpp as Cpp
|
||||
private import codeql.dataflow.internal.FlowSummaryImpl
|
||||
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific as DataFlowImplSpecific
|
||||
private import semmle.code.cpp.dataflow.ExternalFlow
|
||||
private import semmle.code.cpp.ir.IR
|
||||
|
||||
module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
|
||||
class SummarizedCallableBase = Function;
|
||||
|
||||
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
|
||||
|
||||
ReturnKind getStandardReturnValueKind() { result.(NormalReturnKind).getIndirectionIndex() = 0 }
|
||||
|
||||
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
|
||||
|
||||
string encodeArgumentPosition(ArgumentPosition pos) { result = pos.toString() }
|
||||
|
||||
string encodeReturn(ReturnKind rk, string arg) {
|
||||
rk != getStandardReturnValueKind() and
|
||||
result = "ReturnValue" and
|
||||
arg = repeatStars(rk.(NormalReturnKind).getIndirectionIndex())
|
||||
}
|
||||
|
||||
string encodeContent(ContentSet cs, string arg) {
|
||||
exists(FieldContent c |
|
||||
cs.isSingleton(c) and
|
||||
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
|
||||
result = "Field" and
|
||||
arg = repeatStars(c.getIndirectionIndex() - 1) + c.getField().getName()
|
||||
)
|
||||
}
|
||||
|
||||
string encodeWithoutContent(ContentSet c, string arg) {
|
||||
// used for type tracking, not currently used in C/C++.
|
||||
result = "WithoutContent" + c and arg = ""
|
||||
}
|
||||
|
||||
string encodeWithContent(ContentSet c, string arg) {
|
||||
// used for type tracking, not currently used in C/C++.
|
||||
result = "WithContent" + c and arg = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes an argument / parameter position string, for example the `0` in `Argument[0]`.
|
||||
* Supports ranges (`Argument[x..y]`), qualifiers (`Argument[-1]`), indirections
|
||||
* (`Argument[*x]`) and combinations (such as `Argument[**0..1]`).
|
||||
*/
|
||||
bindingset[argString]
|
||||
private TPosition decodePosition(string argString) {
|
||||
exists(int indirection, string posString, int pos |
|
||||
argString = repeatStars(indirection) + posString and
|
||||
pos = AccessPath::parseInt(posString) and
|
||||
(
|
||||
pos >= 0 and indirection = 0 and result = TDirectPosition(pos)
|
||||
or
|
||||
pos >= 0 and indirection > 0 and result = TIndirectionPosition(pos, indirection)
|
||||
or
|
||||
// `Argument[-1]` / `Parameter[-1]` is the qualifier object `*this`, not the `this` pointer itself.
|
||||
pos = -1 and result = TIndirectionPosition(pos, indirection + 1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[token]
|
||||
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
|
||||
token.getName() = "Argument" and
|
||||
result = decodePosition(token.getAnArgument())
|
||||
}
|
||||
|
||||
bindingset[token]
|
||||
ArgumentPosition decodeUnknownArgumentPosition(AccessPath::AccessPathTokenBase token) {
|
||||
token.getName() = "Parameter" and
|
||||
result = decodePosition(token.getAnArgument())
|
||||
}
|
||||
|
||||
bindingset[token]
|
||||
ContentSet decodeUnknownContent(AccessPath::AccessPathTokenBase token) {
|
||||
// field content (no indirection support)
|
||||
exists(FieldContent c |
|
||||
result.isSingleton(c) and
|
||||
token.getName() = c.getField().getName() and
|
||||
not exists(token.getArgumentList()) and
|
||||
c.getIndirectionIndex() = 1
|
||||
)
|
||||
or
|
||||
// field content (with indirection support)
|
||||
exists(FieldContent c |
|
||||
result.isSingleton(c) and
|
||||
token.getName() = c.getField().getName() and
|
||||
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
|
||||
token.getAnArgument() = repeatStars(c.getIndirectionIndex() - 1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private import Make<Location, DataFlowImplSpecific::CppDataFlow, Input> as Impl
|
||||
|
||||
private module StepsInput implements Impl::Private::StepsInputSig {
|
||||
DataFlowCall getACall(Public::SummarizedCallable sc) {
|
||||
result.getStaticCallTarget().getUnderlyingCallable() = sc
|
||||
}
|
||||
}
|
||||
|
||||
module SourceSinkInterpretationInput implements
|
||||
Impl::Private::External::SourceSinkInterpretationInputSig
|
||||
{
|
||||
class Element = Cpp::Element;
|
||||
|
||||
class SourceOrSinkElement = Element;
|
||||
|
||||
/**
|
||||
* Holds if an external source specification exists for `e` with output specification
|
||||
* `output`, kind `kind`, and provenance `provenance`.
|
||||
*/
|
||||
predicate sourceElement(
|
||||
SourceOrSinkElement e, string output, string kind, Public::Provenance provenance, string model
|
||||
) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext) and
|
||||
model = "" // TODO
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an external sink specification exists for `e` with input specification
|
||||
* `input`, kind `kind` and provenance `provenance`.
|
||||
*/
|
||||
predicate sinkElement(
|
||||
SourceOrSinkElement e, string input, string kind, Public::Provenance provenance, string model
|
||||
) {
|
||||
exists(
|
||||
string package, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) and
|
||||
e = interpretElement(package, type, subtypes, name, signature, ext) and
|
||||
model = "" // TODO
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TInterpretNode =
|
||||
TElement_(Element n) or
|
||||
TNode_(Node n)
|
||||
|
||||
/** An entity used to interpret a source/sink specification. */
|
||||
class InterpretNode extends TInterpretNode {
|
||||
/** Gets the element that this node corresponds to, if any. */
|
||||
SourceOrSinkElement asElement() { this = TElement_(result) }
|
||||
|
||||
/** Gets the data-flow node that this node corresponds to, if any. */
|
||||
Node asNode() { this = TNode_(result) }
|
||||
|
||||
/** Gets the call that this node corresponds to, if any. */
|
||||
DataFlowCall asCall() {
|
||||
this.asElement() = result.asCallInstruction().getUnconvertedResultExpression()
|
||||
}
|
||||
|
||||
/** Gets the callable that this node corresponds to, if any. */
|
||||
DataFlowCallable asCallable() { result.getUnderlyingCallable() = this.asElement() }
|
||||
|
||||
/** Gets the target of this call, if any. */
|
||||
Element getCallTarget() { result = this.asCall().getStaticCallTarget().getUnderlyingCallable() }
|
||||
|
||||
/** Gets a textual representation of this node. */
|
||||
string toString() {
|
||||
result = this.asElement().toString()
|
||||
or
|
||||
result = this.asNode().toString()
|
||||
or
|
||||
result = this.asCall().toString()
|
||||
}
|
||||
|
||||
/** Gets the location of this node. */
|
||||
Location getLocation() {
|
||||
result = this.asElement().getLocation()
|
||||
or
|
||||
result = this.asNode().getLocation()
|
||||
or
|
||||
result = this.asCall().getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides additional sink specification logic. */
|
||||
bindingset[c]
|
||||
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) {
|
||||
// Allow variables to be picked as output nodes.
|
||||
exists(Node n, Element ast |
|
||||
n = node.asNode() and
|
||||
ast = mid.asElement()
|
||||
|
|
||||
c = "" and
|
||||
n.asExpr().(VariableAccess).getTarget() = ast
|
||||
)
|
||||
}
|
||||
|
||||
/** Provides additional source specification logic. */
|
||||
bindingset[c]
|
||||
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) {
|
||||
exists(Node n, Element ast, VariableAccess e |
|
||||
n = node.asNode() and
|
||||
ast = mid.asElement() and
|
||||
e.getTarget() = ast
|
||||
|
|
||||
// Allow variables to be picked as input nodes.
|
||||
// We could simply do this as `e = n.asExpr()`, but that would not allow
|
||||
// us to pick `x` as a sink in an example such as `x = source()` (but
|
||||
// only subsequent uses of `x`) since the variable access on `x` doesn't
|
||||
// actually load the value of `x`. So instead, we pick the instruction
|
||||
// node corresponding to the generated `StoreInstruction` and use the
|
||||
// expression associated with the destination instruction. This means
|
||||
// that the `x` in `x = source()` can be marked as an input.
|
||||
c = "" and
|
||||
exists(StoreInstruction store |
|
||||
store.getDestinationAddress().getUnconvertedResultExpression() = e and
|
||||
n.asInstruction() = store
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module Private {
|
||||
import Impl::Private
|
||||
|
||||
module Steps = Impl::Private::Steps<StepsInput>;
|
||||
|
||||
module External {
|
||||
import Impl::Private::External
|
||||
import Impl::Private::External::SourceSinkInterpretation<SourceSinkInterpretationInput>
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides predicates for constructing summary components.
|
||||
*/
|
||||
module SummaryComponent {
|
||||
private import Impl::Private::SummaryComponent as SC
|
||||
|
||||
predicate parameter = SC::parameter/1;
|
||||
|
||||
predicate argument = SC::argument/1;
|
||||
|
||||
predicate content = SC::content/1;
|
||||
|
||||
predicate withoutContent = SC::withoutContent/1;
|
||||
|
||||
predicate withContent = SC::withContent/1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides predicates for constructing stacks of summary components.
|
||||
*/
|
||||
module SummaryComponentStack {
|
||||
private import Impl::Private::SummaryComponentStack as SCS
|
||||
|
||||
predicate singleton = SCS::singleton/1;
|
||||
|
||||
predicate push = SCS::push/2;
|
||||
|
||||
predicate argument = SCS::argument/1;
|
||||
}
|
||||
}
|
||||
|
||||
module Public = Impl::Public;
|
||||
@@ -1371,17 +1371,7 @@ class ReuseExpr extends Expr, @reuseexpr {
|
||||
/**
|
||||
* Gets the expression that is being re-used.
|
||||
*/
|
||||
Expr getReusedExpr() {
|
||||
// In the case of a prvalue, the extractor outputs the expression
|
||||
// before conversion, but the converted expression is intended.
|
||||
if this.isPRValueCategory()
|
||||
then result = this.getBaseReusedExpr().getFullyConverted()
|
||||
else result = this.getBaseReusedExpr()
|
||||
}
|
||||
|
||||
private Expr getBaseReusedExpr() {
|
||||
expr_reuse(underlyingElement(this), unresolveElement(result), _)
|
||||
}
|
||||
Expr getReusedExpr() { expr_reuse(underlyingElement(this), unresolveElement(result), _) }
|
||||
|
||||
override Type getType() { result = this.getReusedExpr().getType() }
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import cpp
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import internal.DataFlowDispatch
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
|
||||
/**
|
||||
* Resolve potential target function(s) for `call`.
|
||||
@@ -16,8 +17,9 @@ private import semmle.code.cpp.ir.IR
|
||||
* to identify the possible target(s).
|
||||
*/
|
||||
Function resolveCall(Call call) {
|
||||
exists(CallInstruction callInstruction |
|
||||
exists(DataFlowCall dataFlowCall, CallInstruction callInstruction |
|
||||
callInstruction.getAst() = call and
|
||||
result = viableCallable(callInstruction)
|
||||
callInstruction = dataFlowCall.asCallInstruction() and
|
||||
result = viableCallable(dataFlowCall).getUnderlyingCallable()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,13 +23,13 @@ DataFlowCallable defaultViableCallable(DataFlowCall call) {
|
||||
// function with the right signature is present in the database, we return
|
||||
// that as a potential callee.
|
||||
exists(string qualifiedName, int nparams |
|
||||
callSignatureWithoutBody(qualifiedName, nparams, call) and
|
||||
functionSignatureWithBody(qualifiedName, nparams, result) and
|
||||
callSignatureWithoutBody(qualifiedName, nparams, call.asCallInstruction()) and
|
||||
functionSignatureWithBody(qualifiedName, nparams, result.getUnderlyingCallable()) and
|
||||
strictcount(Function other | functionSignatureWithBody(qualifiedName, nparams, other)) = 1
|
||||
)
|
||||
or
|
||||
// Virtual dispatch
|
||||
result = call.(VirtualDispatch::DataSensitiveCall).resolve()
|
||||
result.asSourceCallable() = call.(VirtualDispatch::DataSensitiveCall).resolve()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +40,9 @@ DataFlowCallable viableCallable(DataFlowCall call) {
|
||||
result = defaultViableCallable(call)
|
||||
or
|
||||
// Additional call targets
|
||||
result = any(AdditionalCallTarget additional).viableTarget(call.getUnconvertedResultExpression())
|
||||
result.getUnderlyingCallable() =
|
||||
any(AdditionalCallTarget additional)
|
||||
.viableTarget(call.asCallInstruction().getUnconvertedResultExpression())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,7 +152,7 @@ private module VirtualDispatch {
|
||||
ReturnNode node, ReturnKind kind, DataFlowCallable callable
|
||||
) {
|
||||
node.getKind() = kind and
|
||||
node.getEnclosingCallable() = callable
|
||||
node.getEnclosingCallable() = callable.getUnderlyingCallable()
|
||||
}
|
||||
|
||||
/** Call through a function pointer. */
|
||||
@@ -176,10 +178,15 @@ private module VirtualDispatch {
|
||||
/** Call to a virtual function. */
|
||||
private class DataSensitiveOverriddenFunctionCall extends DataSensitiveCall {
|
||||
DataSensitiveOverriddenFunctionCall() {
|
||||
exists(this.getStaticCallTarget().(VirtualFunction).getAnOverridingFunction())
|
||||
exists(
|
||||
this.getStaticCallTarget()
|
||||
.getUnderlyingCallable()
|
||||
.(VirtualFunction)
|
||||
.getAnOverridingFunction()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getThisArgument() }
|
||||
override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
|
||||
|
||||
override MemberFunction resolve() {
|
||||
exists(Class overridingClass |
|
||||
@@ -194,7 +201,8 @@ private module VirtualDispatch {
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate overrideMayAffectCall(Class overridingClass, MemberFunction overridingFunction) {
|
||||
overridingFunction.getAnOverriddenFunction+() = this.getStaticCallTarget().(VirtualFunction) and
|
||||
overridingFunction.getAnOverriddenFunction+() =
|
||||
this.getStaticCallTarget().getUnderlyingCallable().(VirtualFunction) and
|
||||
overridingFunction.getDeclaringType() = overridingClass
|
||||
}
|
||||
|
||||
@@ -256,12 +264,12 @@ predicate mayBenefitFromCallContext(DataFlowCall call) { mayBenefitFromCallConte
|
||||
* value is given as the `arg`'th argument to `f`.
|
||||
*/
|
||||
private predicate mayBenefitFromCallContext(
|
||||
VirtualDispatch::DataSensitiveCall call, Function f, int arg
|
||||
VirtualDispatch::DataSensitiveCall call, DataFlowCallable f, int arg
|
||||
) {
|
||||
f = pragma[only_bind_out](call).getEnclosingCallable() and
|
||||
exists(InitializeParameterInstruction init |
|
||||
not exists(call.getStaticCallTarget()) and
|
||||
init.getEnclosingFunction() = f and
|
||||
init.getEnclosingFunction() = f.getUnderlyingCallable() and
|
||||
call.flowsFrom(DataFlow::instructionNode(init), _) and
|
||||
init.getParameter().getIndex() = arg
|
||||
)
|
||||
@@ -273,10 +281,11 @@ private predicate mayBenefitFromCallContext(
|
||||
*/
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
|
||||
result = viableCallable(call) and
|
||||
exists(int i, Function f |
|
||||
exists(int i, DataFlowCallable f |
|
||||
mayBenefitFromCallContext(pragma[only_bind_into](call), f, i) and
|
||||
f = ctx.getStaticCallTarget() and
|
||||
result = ctx.getArgument(i).getUnconvertedResultExpression().(FunctionAccess).getTarget()
|
||||
result.asSourceCallable() =
|
||||
ctx.getArgument(i).getUnconvertedResultExpression().(FunctionAccess).getTarget()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,4 +27,6 @@ module CppDataFlow implements InputSig<Location> {
|
||||
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;
|
||||
|
||||
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
|
||||
|
||||
predicate neverSkipInPathGraph = Private::neverSkipInPathGraph/1;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ private import DataFlowUtil
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowDispatch
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import SsaInternals as Ssa
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import codeql.util.Unit
|
||||
@@ -77,15 +78,8 @@ module NodeStars {
|
||||
result = n.(PostUpdateNodeImpl).getIndirectionIndex()
|
||||
or
|
||||
result = n.(FinalParameterNode).getIndirectionIndex()
|
||||
}
|
||||
|
||||
private int maxNumberOfIndirections() { result = max(getNumberOfIndirections(_)) }
|
||||
|
||||
private string repeatStars(int n) {
|
||||
n = 0 and result = ""
|
||||
or
|
||||
n = [1 .. maxNumberOfIndirections()] and
|
||||
result = "*" + repeatStars(n - 1)
|
||||
result = n.(BodyLessParameterNodeImpl).getIndirectionIndex()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,6 +91,11 @@ module NodeStars {
|
||||
|
||||
import NodeStars
|
||||
|
||||
/**
|
||||
* A cut-down `DataFlow::Node` class that does not depend on the output of SSA.
|
||||
* This can thus be safely used in the SSA computations themselves, as well as
|
||||
* in construction of other node classes (`TIRDataFlowNode`).
|
||||
*/
|
||||
class Node0Impl extends TIRDataFlowNode0 {
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
@@ -333,7 +332,9 @@ private module IndirectInstructions {
|
||||
import IndirectInstructions
|
||||
|
||||
/** Gets the callable in which this node occurs. */
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node n) {
|
||||
result.getUnderlyingCallable() = n.getEnclosingCallable()
|
||||
}
|
||||
|
||||
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
|
||||
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
|
||||
@@ -379,12 +380,30 @@ private class SideEffectArgumentNode extends ArgumentNode, SideEffectOperandNode
|
||||
override predicate argumentOf(DataFlowCall dfCall, ArgumentPosition pos) {
|
||||
exists(int indirectionIndex |
|
||||
pos = TIndirectionPosition(argumentIndex, pragma[only_bind_into](indirectionIndex)) and
|
||||
this.getCallInstruction() = dfCall and
|
||||
this.getCallInstruction() = dfCall.asCallInstruction() and
|
||||
super.hasAddressOperandAndIndirectionIndex(_, pragma[only_bind_into](indirectionIndex))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument node that is part of a summary. These only occur when the
|
||||
* summary contains a synthesized call.
|
||||
*/
|
||||
class SummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
|
||||
private SummaryCall call_;
|
||||
private ArgumentPosition pos_;
|
||||
|
||||
SummaryArgumentNode() {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call_.getReceiver(), this.getSummaryNode(), pos_)
|
||||
}
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
call = call_ and
|
||||
pos = pos_
|
||||
}
|
||||
}
|
||||
|
||||
/** A parameter position represented by an integer. */
|
||||
class ParameterPosition = Position;
|
||||
|
||||
@@ -432,24 +451,42 @@ class IndirectionPosition extends Position, TIndirectionPosition {
|
||||
}
|
||||
|
||||
newtype TPosition =
|
||||
TDirectPosition(int index) { exists(any(CallInstruction c).getArgument(index)) } or
|
||||
TDirectPosition(int argumentIndex) { exists(any(CallInstruction c).getArgument(argumentIndex)) } or
|
||||
TIndirectionPosition(int argumentIndex, int indirectionIndex) {
|
||||
hasOperandAndIndex(_, any(CallInstruction call).getArgumentOperand(argumentIndex),
|
||||
Ssa::hasIndirectOperand(any(CallInstruction call).getArgumentOperand(argumentIndex),
|
||||
indirectionIndex)
|
||||
}
|
||||
|
||||
private newtype TReturnKind =
|
||||
TNormalReturnKind(int index) {
|
||||
exists(IndirectReturnNode return |
|
||||
return.isNormalReturn() and
|
||||
index = return.getIndirectionIndex() - 1 // We subtract one because the return loads the value.
|
||||
)
|
||||
TNormalReturnKind(int indirectionIndex) {
|
||||
// derive a possible return indirection from SSA
|
||||
// (this is a more durable approach if SSA infers additional indirections for any reason)
|
||||
Ssa::hasIndirectOperand(any(ReturnValueInstruction ret).getReturnAddressOperand(),
|
||||
indirectionIndex + 1) // We subtract one because the return loads the value.
|
||||
or
|
||||
// derive a possible return kind from the AST
|
||||
// (this approach includes functions declared that have no body; they may still have flow summaries)
|
||||
indirectionIndex =
|
||||
[0 .. max(Cpp::Function f |
|
||||
not exists(f.getBlock())
|
||||
|
|
||||
Ssa::getMaxIndirectionsForType(f.getUnspecifiedType()) - 1 // -1 because a returned value is a prvalue not a glvalue
|
||||
)]
|
||||
} or
|
||||
TIndirectReturnKind(int argumentIndex, int indirectionIndex) {
|
||||
exists(IndirectReturnNode return |
|
||||
return.isParameterReturn(argumentIndex) and
|
||||
indirectionIndex = return.getIndirectionIndex()
|
||||
// derive a possible return argument from SSA
|
||||
exists(Ssa::FinalParameterUse use |
|
||||
use.getIndirectionIndex() = indirectionIndex and
|
||||
use.getArgumentIndex() = argumentIndex
|
||||
)
|
||||
or
|
||||
// derive a possible return argument from the AST
|
||||
indirectionIndex =
|
||||
[0 .. max(Cpp::Function f |
|
||||
not exists(f.getBlock())
|
||||
|
|
||||
Ssa::getMaxIndirectionsForType(f.getParameter(argumentIndex).getUnspecifiedType()) - 1 // -1 because an argument is a prvalue not a glvalue
|
||||
)]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -457,29 +494,44 @@ private newtype TReturnKind =
|
||||
* from a callable. For C++, this is simply a function return.
|
||||
*/
|
||||
class ReturnKind extends TReturnKind {
|
||||
/**
|
||||
* Gets the indirection index of this return kind.
|
||||
*/
|
||||
abstract int getIndirectionIndex();
|
||||
|
||||
/** Gets a textual representation of this return kind. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
private class NormalReturnKind extends ReturnKind, TNormalReturnKind {
|
||||
int index;
|
||||
/**
|
||||
* A value returned from a callable using a `return` statement, that is, a "normal" return.
|
||||
*/
|
||||
class NormalReturnKind extends ReturnKind, TNormalReturnKind {
|
||||
int indirectionIndex;
|
||||
|
||||
NormalReturnKind() { this = TNormalReturnKind(index) }
|
||||
NormalReturnKind() { this = TNormalReturnKind(indirectionIndex) }
|
||||
|
||||
override int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
override string toString() { result = "indirect return" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A value returned from a callable through a parameter.
|
||||
*/
|
||||
private class IndirectReturnKind extends ReturnKind, TIndirectReturnKind {
|
||||
int argumentIndex;
|
||||
int indirectionIndex;
|
||||
|
||||
IndirectReturnKind() { this = TIndirectReturnKind(argumentIndex, indirectionIndex) }
|
||||
|
||||
override int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
override string toString() { result = "indirect outparam[" + argumentIndex.toString() + "]" }
|
||||
}
|
||||
|
||||
/** A data flow node that occurs as the result of a `ReturnStmt`. */
|
||||
class ReturnNode extends Node instanceof IndirectReturnNode {
|
||||
abstract class ReturnNode extends Node {
|
||||
/** Gets the kind of this returned value. */
|
||||
abstract ReturnKind getKind();
|
||||
}
|
||||
@@ -510,6 +562,17 @@ class ReturnIndirectionNode extends IndirectReturnNode, ReturnNode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A return node that is part of a summary.
|
||||
*/
|
||||
private class SummaryReturnNode extends ReturnNode, FlowSummaryNode {
|
||||
private ReturnKind rk;
|
||||
|
||||
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) }
|
||||
|
||||
override ReturnKind getKind() { result = rk }
|
||||
}
|
||||
|
||||
private Operand fullyConvertedCallStepImpl(Operand op) {
|
||||
not exists(getANonConversionUse(op)) and
|
||||
exists(Instruction instr |
|
||||
@@ -616,7 +679,10 @@ predicate simpleOutNode(Node node, CallInstruction call) {
|
||||
instructionForFullyConvertedCall(node.asInstruction(), call)
|
||||
}
|
||||
|
||||
/** A data flow node that represents the output of a call. */
|
||||
/**
|
||||
* A data flow node that represents the output of a call (for example, a
|
||||
* return value) at the call site.
|
||||
*/
|
||||
class OutNode extends Node {
|
||||
OutNode() {
|
||||
// Return values not hidden behind indirections
|
||||
@@ -627,11 +693,15 @@ class OutNode extends Node {
|
||||
or
|
||||
// Modified arguments hidden behind indirections
|
||||
this instanceof IndirectArgumentOutNode
|
||||
or
|
||||
// Summary node
|
||||
FlowSummaryImpl::Private::summaryOutNode(_, this.(FlowSummaryNode).getSummaryNode(), _)
|
||||
}
|
||||
|
||||
/** Gets the underlying call. */
|
||||
abstract DataFlowCall getCall();
|
||||
|
||||
/** Gets the kind of this out node. */
|
||||
abstract ReturnKind getReturnKind();
|
||||
}
|
||||
|
||||
@@ -640,25 +710,44 @@ private class DirectCallOutNode extends OutNode {
|
||||
|
||||
DirectCallOutNode() { simpleOutNode(this, call) }
|
||||
|
||||
override DataFlowCall getCall() { result = call }
|
||||
override DataFlowCall getCall() { result.asCallInstruction() = call }
|
||||
|
||||
override ReturnKind getReturnKind() { result = TNormalReturnKind(0) }
|
||||
}
|
||||
|
||||
private class IndirectCallOutNode extends OutNode, IndirectReturnOutNode {
|
||||
override DataFlowCall getCall() { result = this.getCallInstruction() }
|
||||
override DataFlowCall getCall() { result.asCallInstruction() = this.getCallInstruction() }
|
||||
|
||||
override ReturnKind getReturnKind() { result = TNormalReturnKind(this.getIndirectionIndex()) }
|
||||
}
|
||||
|
||||
private class SideEffectOutNode extends OutNode, IndirectArgumentOutNode {
|
||||
override DataFlowCall getCall() { result = this.getCallInstruction() }
|
||||
override DataFlowCall getCall() { result.asCallInstruction() = this.getCallInstruction() }
|
||||
|
||||
override ReturnKind getReturnKind() {
|
||||
result = TIndirectReturnKind(this.getArgumentIndex(), this.getIndirectionIndex())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An output node that is part of a summary. An output node is needed when the
|
||||
* model contains a synthesized call (`SummaryCall`) and the return value of
|
||||
* that call is needed by the summary (for example when the model has flow from
|
||||
* `Argument[0].ReturnValue`).
|
||||
*/
|
||||
private class SummaryOutNode extends OutNode, FlowSummaryNode {
|
||||
private SummaryCall call;
|
||||
private ReturnKind kind_;
|
||||
|
||||
SummaryOutNode() {
|
||||
FlowSummaryImpl::Private::summaryOutNode(call.getReceiver(), this.getSummaryNode(), kind_)
|
||||
}
|
||||
|
||||
override DataFlowCall getCall() { result = call }
|
||||
|
||||
override ReturnKind getReturnKind() { result = kind_ }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node that can read the value returned from `call` with return kind
|
||||
* `kind`.
|
||||
@@ -721,6 +810,10 @@ predicate jumpStep(Node n1, Node n2) {
|
||||
v = n1.asIndirectVariable(globalDef.getIndirection())
|
||||
)
|
||||
)
|
||||
or
|
||||
// models-as-data summarized flow
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(n1.(FlowSummaryNode).getSummaryNode(),
|
||||
n2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -729,25 +822,35 @@ predicate jumpStep(Node n1, Node n2) {
|
||||
* value of `node1`.
|
||||
*
|
||||
* The boolean `certain` is true if the destination address does not involve
|
||||
* any pointer arithmetic, and false otherwise.
|
||||
* any pointer arithmetic, and false otherwise. This has to do with whether a
|
||||
* store step can be used to clear a field (see `clearsContent`).
|
||||
*/
|
||||
predicate storeStepImpl(Node node1, Content c, PostFieldUpdateNode node2, boolean certain) {
|
||||
exists(int indirectionIndex1, int numberOfLoads, StoreInstruction store |
|
||||
predicate storeStepImpl(Node node1, Content c, Node node2, boolean certain) {
|
||||
exists(
|
||||
PostFieldUpdateNode postFieldUpdate, int indirectionIndex1, int numberOfLoads,
|
||||
StoreInstruction store
|
||||
|
|
||||
postFieldUpdate = node2 and
|
||||
nodeHasInstruction(node1, store, pragma[only_bind_into](indirectionIndex1)) and
|
||||
node2.getIndirectionIndex() = 1 and
|
||||
numberOfLoadsFromOperand(node2.getFieldAddress(), store.getDestinationAddressOperand(),
|
||||
numberOfLoads, certain)
|
||||
postFieldUpdate.getIndirectionIndex() = 1 and
|
||||
numberOfLoadsFromOperand(postFieldUpdate.getFieldAddress(),
|
||||
store.getDestinationAddressOperand(), numberOfLoads, certain)
|
||||
|
|
||||
exists(FieldContent fc | fc = c |
|
||||
fc.getField() = node2.getUpdatedField() and
|
||||
fc.getField() = postFieldUpdate.getUpdatedField() and
|
||||
fc.getIndirectionIndex() = 1 + indirectionIndex1 + numberOfLoads
|
||||
)
|
||||
or
|
||||
exists(UnionContent uc | uc = c |
|
||||
uc.getAField() = node2.getUpdatedField() and
|
||||
uc.getAField() = postFieldUpdate.getUpdatedField() and
|
||||
uc.getIndirectionIndex() = 1 + indirectionIndex1 + numberOfLoads
|
||||
)
|
||||
)
|
||||
or
|
||||
// models-as-data summarized flow
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode()) and
|
||||
certain = true
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -834,6 +937,10 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
|
||||
uc.getIndirectionIndex() = indirectionIndex2 + numberOfLoads
|
||||
)
|
||||
)
|
||||
or
|
||||
// models-as-data summarized flow
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -907,21 +1014,213 @@ class CastNode extends Node {
|
||||
CastNode() { none() } // stub implementation
|
||||
}
|
||||
|
||||
cached
|
||||
private newtype TDataFlowCallable =
|
||||
TSourceCallable(Cpp::Declaration decl) {
|
||||
not decl instanceof FlowSummaryImpl::Public::SummarizedCallable
|
||||
} or
|
||||
TSummarizedCallable(FlowSummaryImpl::Public::SummarizedCallable c)
|
||||
|
||||
/**
|
||||
* A function that may contain code or a variable that may contain itself. When
|
||||
* flow crosses from one _enclosing callable_ to another, the interprocedural
|
||||
* data-flow library discards call contexts and inserts a node in the big-step
|
||||
* relation used for human-readable path explanations.
|
||||
* A callable, which may be:
|
||||
* - a function (that may contain code)
|
||||
* - a summarized function (that may contain only `FlowSummaryNode`s)
|
||||
* - a variable (this is used as context for global initialization, and also
|
||||
* for the mid-point in interprocedural data flow between a write and read
|
||||
* of a global variable in different functions).
|
||||
* When flow crosses from one _enclosing callable_ to another, the
|
||||
* interprocedural data-flow library discards call contexts and inserts a node
|
||||
* in the big-step relation used for human-readable path explanations.
|
||||
*/
|
||||
class DataFlowCallable = Cpp::Declaration;
|
||||
class DataFlowCallable extends TDataFlowCallable {
|
||||
/** Gets the location of this callable. */
|
||||
Location getLocation() { none() }
|
||||
|
||||
/** Gets a textual representation of this callable. */
|
||||
string toString() { none() }
|
||||
|
||||
/**
|
||||
* Gets the `Declaration` corresponding to this callable if it exists in the database.
|
||||
* For summarized callables (which may not exist in the database), use `asSummarizedCallable`.
|
||||
*/
|
||||
Cpp::Declaration asSourceCallable() { this = TSourceCallable(result) }
|
||||
|
||||
/**
|
||||
* Gets the underlying summarized callable, if
|
||||
* this callable is generated from a models-as-data
|
||||
* model.
|
||||
*/
|
||||
FlowSummaryImpl::Public::SummarizedCallable asSummarizedCallable() {
|
||||
this = TSummarizedCallable(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying `Declaration` of this `DataFlowCallable`. This
|
||||
* predicate returns a result for both source and summarized callables.
|
||||
*/
|
||||
Cpp::Declaration getUnderlyingCallable() {
|
||||
result = this.asSummarizedCallable() or // SummarizedCallable = Function (in CPP)
|
||||
result = this.asSourceCallable()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A source callable, conceptually, a function in the source code for the
|
||||
* purpose of computing data flow. In practice this excludes functions that
|
||||
* are summarized using models-as-data (as we don't want to create
|
||||
* unmodeled flows or duplicate paths), and includes variables (for reasons
|
||||
* explained in `DataFlowCallable`).
|
||||
*/
|
||||
class SourceCallable extends DataFlowCallable, TSourceCallable {
|
||||
Cpp::Declaration decl;
|
||||
|
||||
SourceCallable() { this = TSourceCallable(decl) }
|
||||
|
||||
override string toString() { result = decl.toString() }
|
||||
|
||||
override Location getLocation() { result = decl.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A summarized callable, that is, a function synthesized from one or more
|
||||
* models-as-data models as a place to contain the corresponding
|
||||
* `FlowSummaryNode`s.
|
||||
*/
|
||||
class SummarizedCallable extends DataFlowCallable, TSummarizedCallable {
|
||||
FlowSummaryImpl::Public::SummarizedCallable sc;
|
||||
|
||||
SummarizedCallable() { this = TSummarizedCallable(sc) }
|
||||
|
||||
override string toString() { result = sc.toString() }
|
||||
|
||||
override Location getLocation() { result = sc.getLocation() }
|
||||
}
|
||||
|
||||
class DataFlowExpr = Expr;
|
||||
|
||||
class DataFlowType = Type;
|
||||
|
||||
/** A function call relevant for data flow. */
|
||||
class DataFlowCall extends CallInstruction {
|
||||
DataFlowCallable getEnclosingCallable() { result = this.getEnclosingFunction() }
|
||||
cached
|
||||
private newtype TDataFlowCall =
|
||||
TNormalCall(CallInstruction call) or
|
||||
TSummaryCall(
|
||||
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
|
||||
) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
|
||||
/**
|
||||
* A function call relevant for data flow. This includes calls from source
|
||||
* code and calls inside library callables with a flow summary.
|
||||
*/
|
||||
class DataFlowCall extends TDataFlowCall {
|
||||
/**
|
||||
* Gets the underlying data flow call instruction, if any.
|
||||
*/
|
||||
CallInstruction asCallInstruction() { none() }
|
||||
|
||||
/**
|
||||
* Gets the operand the specifies the target function of the call.
|
||||
*/
|
||||
CallTargetOperand getCallTargetOperand() { none() }
|
||||
|
||||
/**
|
||||
* Gets the `Function` that the call targets, if this is statically known.
|
||||
*/
|
||||
DataFlowCallable getStaticCallTarget() { none() }
|
||||
|
||||
/**
|
||||
* Gets the `index`'th argument operand. The qualifier is considered to have index `-1`.
|
||||
*/
|
||||
ArgumentOperand getArgumentOperand(int index) { none() }
|
||||
|
||||
/**
|
||||
* Gets the argument at the specified index, or `this` if `index` is `-1`.
|
||||
*/
|
||||
pragma[noinline]
|
||||
final Instruction getArgument(int index) { result = this.getArgumentOperand(index).getDef() }
|
||||
|
||||
/**
|
||||
* Gets the number of arguments of the call, including the `this` pointer, if any.
|
||||
*/
|
||||
final int getNumberOfArguments() { result = count(this.getArgumentOperand(_)) }
|
||||
|
||||
/**
|
||||
* Gets the enclosing callable, if any.
|
||||
*/
|
||||
DataFlowCallable getEnclosingCallable() { none() }
|
||||
|
||||
/**
|
||||
* Gets a textual representation of this call.
|
||||
*/
|
||||
string toString() { none() }
|
||||
|
||||
/**
|
||||
* Gets the location of this call.
|
||||
*/
|
||||
Location getLocation() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A function call relevant for data flow, that exists in source code.
|
||||
*/
|
||||
private class NormalCall extends DataFlowCall, TNormalCall {
|
||||
private CallInstruction call;
|
||||
|
||||
NormalCall() { this = TNormalCall(call) }
|
||||
|
||||
override CallInstruction asCallInstruction() { result = call }
|
||||
|
||||
override CallTargetOperand getCallTargetOperand() { result = call.getCallTargetOperand() }
|
||||
|
||||
override DataFlowCallable getStaticCallTarget() {
|
||||
result.getUnderlyingCallable() = call.getStaticCallTarget()
|
||||
}
|
||||
|
||||
override ArgumentOperand getArgumentOperand(int index) { result = call.getArgumentOperand(index) }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.getUnderlyingCallable() = call.getEnclosingFunction()
|
||||
}
|
||||
|
||||
override string toString() { result = call.toString() }
|
||||
|
||||
override Location getLocation() { result = call.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A synthesized call inside a callable with a flow summary.
|
||||
*
|
||||
* For example, consider the function:
|
||||
* ```
|
||||
* int myFunction(int (*funPtr)());
|
||||
* ```
|
||||
* with an accompanying models-as-data flow summary involving `funPtr` (for
|
||||
* example from `Argument[0].ReturnValue` to `ReturnValue`). A `SummaryCall`
|
||||
* will be synthesized representing a call to `funPtr` inside `myFunction`,
|
||||
* so that flow can be connected as described in the model.
|
||||
*/
|
||||
class SummaryCall extends DataFlowCall, TSummaryCall {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private FlowSummaryImpl::Private::SummaryNode receiver;
|
||||
|
||||
SummaryCall() { this = TSummaryCall(c, receiver) }
|
||||
|
||||
/**
|
||||
* Gets the data flow node that holds the address of the function this call
|
||||
* targets.
|
||||
*/
|
||||
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
|
||||
|
||||
// no implementation for `getCallTargetOperand()`, `getStaticCallTarget()`
|
||||
// or `getArgumentOperand(int index)`. This is because the flow summary
|
||||
// library is responsible for finding the call target, and there are no
|
||||
// IR nodes available for the call target operand or argument operands.
|
||||
override DataFlowCallable getEnclosingCallable() { result = TSummarizedCallable(c) }
|
||||
|
||||
override string toString() { result = "[summary] call to " + receiver + " in " + c }
|
||||
|
||||
override UnknownLocation getLocation() { any() }
|
||||
}
|
||||
|
||||
module IsUnreachableInCall {
|
||||
@@ -950,7 +1249,7 @@ module IsUnreachableInCall {
|
||||
|
||||
predicate isUnreachableInCall(Node n, DataFlowCall call) {
|
||||
exists(
|
||||
DirectParameterNode paramNode, ConstantIntegralTypeArgumentNode arg,
|
||||
InstructionDirectParameterNode paramNode, ConstantIntegralTypeArgumentNode arg,
|
||||
IntegerConstantInstruction constant, int k, Operand left, Operand right, IRBlock block
|
||||
|
|
||||
// arg flows into `paramNode`
|
||||
@@ -1009,13 +1308,26 @@ predicate nodeIsHidden(Node n) {
|
||||
n instanceof InitialGlobalValue
|
||||
}
|
||||
|
||||
predicate neverSkipInPathGraph(Node n) {
|
||||
// Always show the right-hand side of assignments in the path graph
|
||||
exists(n.asDefinition())
|
||||
or
|
||||
exists(n.asIndirectDefinition())
|
||||
}
|
||||
|
||||
class LambdaCallKind = Unit;
|
||||
|
||||
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
|
||||
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) { none() }
|
||||
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
|
||||
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable() and
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() }
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() and
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
|
||||
@@ -1031,7 +1343,15 @@ predicate knownSinkModel(Node sink, string model) { none() }
|
||||
* One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
|
||||
* by default as a heuristic.
|
||||
*/
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) { p instanceof IndirectParameterNode }
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) {
|
||||
p instanceof IndirectParameterNode
|
||||
or
|
||||
// models-as-data summarized flow
|
||||
exists(DataFlowCallable c, ParameterPosition pos |
|
||||
p.isParameterOf(c, pos) and
|
||||
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(c.asSummarizedCallable(), pos)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fieldHasApproxName(Field f, string s) {
|
||||
s = f.getName().charAt(0) and
|
||||
@@ -1143,7 +1463,7 @@ private predicate getAdditionalFlowIntoCallNodeTermStep(Node node1, Node node2)
|
||||
/** Gets the `IRVariable` associated with the parameter node `p`. */
|
||||
pragma[nomagic]
|
||||
private IRVariable getIRVariableForParameterNode(ParameterNode p) {
|
||||
result = p.(DirectParameterNode).getIRVariable()
|
||||
result = p.(InstructionDirectParameterNode).getIRVariable()
|
||||
or
|
||||
result.getAst() = p.(IndirectParameterNode).getParameter()
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import DataFlowPrivate
|
||||
private import ModelUtil
|
||||
private import SsaInternals as Ssa
|
||||
@@ -59,7 +60,17 @@ private newtype TIRDataFlowNode =
|
||||
)
|
||||
} or
|
||||
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
|
||||
TInitialGlobalValue(Ssa::GlobalDef globalUse)
|
||||
TInitialGlobalValue(Ssa::GlobalDef globalUse) or
|
||||
TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) {
|
||||
// Rule out parameters of catch blocks.
|
||||
not exists(p.getCatchBlock()) and
|
||||
// We subtract one because `getMaxIndirectionsForType` returns the maximum
|
||||
// indirection for a glvalue of a given type, and this doesn't apply to
|
||||
// parameters.
|
||||
indirectionIndex = [0 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
|
||||
not any(InitializeParameterInstruction init).getParameter() = p
|
||||
} or
|
||||
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
|
||||
|
||||
/**
|
||||
* An operand that is defined by a `FieldAddressInstruction`.
|
||||
@@ -387,7 +398,7 @@ class Node extends TIRDataFlowNode {
|
||||
index = 0 and
|
||||
result = this.(ExplicitParameterNode).getParameter()
|
||||
or
|
||||
this.(IndirectParameterNode).hasInstructionAndIndirectionIndex(_, index) and
|
||||
this.(IndirectParameterNode).getIndirectionIndex() = index and
|
||||
result = this.(IndirectParameterNode).getParameter()
|
||||
}
|
||||
|
||||
@@ -738,37 +749,65 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A node representing an indirection of a parameter.
|
||||
* A node representing a parameter for a function with no body.
|
||||
*/
|
||||
class IndirectParameterNode extends Node instanceof IndirectInstruction {
|
||||
InitializeParameterInstruction init;
|
||||
class BodyLessParameterNodeImpl extends Node, TBodyLessParameterNodeImpl {
|
||||
Parameter p;
|
||||
int indirectionIndex;
|
||||
|
||||
IndirectParameterNode() { IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _) }
|
||||
|
||||
int getArgumentIndex() { init.hasIndex(result) }
|
||||
|
||||
/** Gets the parameter whose indirection is initialized. */
|
||||
Parameter getParameter() { result = init.getParameter() }
|
||||
BodyLessParameterNodeImpl() { this = TBodyLessParameterNodeImpl(p, indirectionIndex) }
|
||||
|
||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||
|
||||
override Declaration getFunction() { result = init.getEnclosingFunction() }
|
||||
override Declaration getFunction() { result = p.getFunction() }
|
||||
|
||||
/** Gets the underlying operand and the underlying indirection index. */
|
||||
predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) {
|
||||
IndirectInstruction.super.hasInstructionAndIndirectionIndex(instr, index)
|
||||
/** Gets the indirection index of this node. */
|
||||
int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
override DataFlowType getType() {
|
||||
result = getTypeImpl(p.getUnderlyingType(), this.getIndirectionIndex())
|
||||
}
|
||||
|
||||
override Location getLocationImpl() { result = this.getParameter().getLocation() }
|
||||
|
||||
override string toStringImpl() {
|
||||
exists(string prefix | prefix = stars(this) |
|
||||
result = prefix + this.getParameter().toString()
|
||||
or
|
||||
not exists(this.getParameter()) and
|
||||
result = prefix + "this"
|
||||
)
|
||||
final override Location getLocationImpl() {
|
||||
result = unique( | | p.getLocation())
|
||||
or
|
||||
count(p.getLocation()) != 1 and
|
||||
result instanceof UnknownDefaultLocation
|
||||
}
|
||||
|
||||
final override string toStringImpl() {
|
||||
exists(string prefix | prefix = stars(this) | result = prefix + p.toString())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node used to model flow summaries. That is, a dataflow node
|
||||
* that is synthesized to represent a parameter, return value, or other part
|
||||
* of a models-as-data modeled function.
|
||||
*/
|
||||
class FlowSummaryNode extends Node, TFlowSummaryNode {
|
||||
/**
|
||||
* Gets the models-as-data `SummaryNode` associated with this dataflow
|
||||
* `FlowSummaryNode`.
|
||||
*/
|
||||
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
|
||||
|
||||
/**
|
||||
* Gets the summarized callable that this node belongs to.
|
||||
*/
|
||||
FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() {
|
||||
result = this.getSummaryNode().getSummarizedCallable()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enclosing callable. For a `FlowSummaryNode` this is always the
|
||||
* summarized function this node is part of.
|
||||
*/
|
||||
override Declaration getEnclosingCallable() { result = this.getSummarizedCallable() }
|
||||
|
||||
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
|
||||
|
||||
override string toStringImpl() { result = this.getSummaryNode().toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -826,6 +865,9 @@ class IndirectArgumentOutNode extends PostUpdateNodeImpl {
|
||||
|
||||
CallInstruction getCallInstruction() { result.getAnArgumentOperand() = operand }
|
||||
|
||||
/**
|
||||
* Gets the `Function` that the call targets, if this is statically known.
|
||||
*/
|
||||
Function getStaticCallTarget() { result = this.getCallInstruction().getStaticCallTarget() }
|
||||
|
||||
override string toStringImpl() {
|
||||
@@ -1620,68 +1662,36 @@ class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of a parameter at function entry, viewed as a node in a data
|
||||
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
|
||||
* and implicit parameters such as `this` in `x.f()`.
|
||||
*
|
||||
* To match a specific kind of parameter, consider using one of the subclasses
|
||||
* `ExplicitParameterNode`, `ThisParameterNode`, or
|
||||
* `ParameterIndirectionNode`.
|
||||
*/
|
||||
class ParameterNode extends Node {
|
||||
ParameterNode() {
|
||||
// To avoid making this class abstract, we enumerate its values here
|
||||
this.asInstruction() instanceof InitializeParameterInstruction
|
||||
or
|
||||
this instanceof IndirectParameterNode
|
||||
}
|
||||
|
||||
abstract private class AbstractParameterNode extends Node {
|
||||
/**
|
||||
* Holds if this node is the parameter of `f` at the specified position. The
|
||||
* implicit `this` parameter is considered to have position `-1`, and
|
||||
* pointer-indirection parameters are at further negative positions.
|
||||
*/
|
||||
predicate isParameterOf(Function f, ParameterPosition pos) { none() } // overridden by subclasses
|
||||
abstract predicate isParameterOf(DataFlowCallable f, ParameterPosition pos);
|
||||
|
||||
/** Gets the `Parameter` associated with this node, if it exists. */
|
||||
Parameter getParameter() { none() } // overridden by subclasses
|
||||
}
|
||||
|
||||
/** An explicit positional parameter, including `this`, but not `...`. */
|
||||
class DirectParameterNode extends InstructionNode {
|
||||
override InitializeParameterInstruction instr;
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Gets the `IRVariable` that this parameter references.
|
||||
*/
|
||||
IRVariable getIRVariable() { result = instr.getIRVariable() }
|
||||
abstract private class AbstractIndirectParameterNode extends AbstractParameterNode {
|
||||
/** Gets the indirection index of this parameter node. */
|
||||
abstract int getIndirectionIndex();
|
||||
}
|
||||
|
||||
/** An explicit positional parameter, not including `this` or `...`. */
|
||||
private class ExplicitParameterNode extends ParameterNode, DirectParameterNode {
|
||||
ExplicitParameterNode() { exists(instr.getParameter()) }
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A node representing an indirection of a parameter.
|
||||
*/
|
||||
final class IndirectParameterNode = AbstractIndirectParameterNode;
|
||||
|
||||
override predicate isParameterOf(Function f, ParameterPosition pos) {
|
||||
f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = instr.getParameter().toString() }
|
||||
|
||||
override Parameter getParameter() { result = instr.getParameter() }
|
||||
}
|
||||
|
||||
/** An implicit `this` parameter. */
|
||||
class ThisParameterNode extends ParameterNode, DirectParameterNode {
|
||||
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }
|
||||
|
||||
override predicate isParameterOf(Function f, ParameterPosition pos) {
|
||||
pos.(DirectPosition).getIndex() = -1 and instr.getEnclosingFunction() = f
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = "this" }
|
||||
pragma[noinline]
|
||||
private predicate indirectParameterNodeHasArgumentIndexAndIndex(
|
||||
IndirectInstructionParameterNode node, int argumentIndex, int indirectionIndex
|
||||
) {
|
||||
node.hasInstructionAndIndirectionIndex(_, indirectionIndex) and
|
||||
node.getArgumentIndex() = argumentIndex
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
@@ -1692,23 +1702,167 @@ private predicate indirectPositionHasArgumentIndexAndIndex(
|
||||
pos.getIndirectionIndex() = indirectionIndex
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate indirectParameterNodeHasArgumentIndexAndIndex(
|
||||
IndirectParameterNode node, int argumentIndex, int indirectionIndex
|
||||
) {
|
||||
node.hasInstructionAndIndirectionIndex(_, indirectionIndex) and
|
||||
node.getArgumentIndex() = argumentIndex
|
||||
}
|
||||
private class IndirectInstructionParameterNode extends AbstractIndirectParameterNode instanceof IndirectInstruction
|
||||
{
|
||||
InitializeParameterInstruction init;
|
||||
|
||||
/** A synthetic parameter to model the pointed-to object of a pointer parameter. */
|
||||
class ParameterIndirectionNode extends ParameterNode instanceof IndirectParameterNode {
|
||||
override predicate isParameterOf(Function f, ParameterPosition pos) {
|
||||
IndirectParameterNode.super.getEnclosingCallable() = f and
|
||||
IndirectInstructionParameterNode() {
|
||||
IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _)
|
||||
}
|
||||
|
||||
int getArgumentIndex() { init.hasIndex(result) }
|
||||
|
||||
override string toStringImpl() {
|
||||
exists(string prefix | prefix = stars(this) |
|
||||
result = prefix + this.getParameter().toString()
|
||||
or
|
||||
not exists(this.getParameter()) and
|
||||
result = prefix + "this"
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the parameter whose indirection is initialized. */
|
||||
override Parameter getParameter() { result = init.getParameter() }
|
||||
|
||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||
|
||||
override Declaration getFunction() { result = init.getEnclosingFunction() }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
|
||||
this.getEnclosingCallable() = f.getUnderlyingCallable() and
|
||||
exists(int argumentIndex, int indirectionIndex |
|
||||
indirectPositionHasArgumentIndexAndIndex(pos, argumentIndex, indirectionIndex) and
|
||||
indirectParameterNodeHasArgumentIndexAndIndex(this, argumentIndex, indirectionIndex)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the underlying operand and the underlying indirection index. */
|
||||
predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) {
|
||||
IndirectInstruction.super.hasInstructionAndIndirectionIndex(instr, index)
|
||||
}
|
||||
|
||||
final override int getIndirectionIndex() { this.hasInstructionAndIndirectionIndex(init, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of a parameter at function entry, viewed as a node in a data
|
||||
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
|
||||
* and implicit parameters such as `this` in `x.f()`.
|
||||
*
|
||||
* To match a specific kind of parameter, consider using one of the subclasses
|
||||
* `ExplicitParameterNode`, `ThisParameterNode`, or
|
||||
* `ParameterIndirectionNode`.
|
||||
*/
|
||||
final class ParameterNode = AbstractParameterNode;
|
||||
|
||||
abstract private class AbstractDirectParameterNode extends AbstractParameterNode { }
|
||||
|
||||
/** An explicit positional parameter, including `this`, but not `...`. */
|
||||
final class DirectParameterNode = AbstractDirectParameterNode;
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* A non-indirect parameter node that is represented as an `Instruction`.
|
||||
*/
|
||||
abstract class InstructionDirectParameterNode extends InstructionNode, AbstractDirectParameterNode {
|
||||
final override InitializeParameterInstruction instr;
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Gets the `IRVariable` that this parameter references.
|
||||
*/
|
||||
final IRVariable getIRVariable() { result = instr.getIRVariable() }
|
||||
}
|
||||
|
||||
abstract private class AbstractExplicitParameterNode extends AbstractDirectParameterNode { }
|
||||
|
||||
final class ExplicitParameterNode = AbstractExplicitParameterNode;
|
||||
|
||||
/** An explicit positional parameter, not including `this` or `...`. */
|
||||
private class ExplicitParameterInstructionNode extends AbstractExplicitParameterNode,
|
||||
InstructionDirectParameterNode
|
||||
{
|
||||
ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
|
||||
f.getUnderlyingCallable().(Function).getParameter(pos.(DirectPosition).getIndex()) =
|
||||
instr.getParameter()
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = instr.getParameter().toString() }
|
||||
|
||||
override Parameter getParameter() { result = instr.getParameter() }
|
||||
}
|
||||
|
||||
/** An implicit `this` parameter. */
|
||||
class ThisParameterInstructionNode extends AbstractExplicitParameterNode,
|
||||
InstructionDirectParameterNode
|
||||
{
|
||||
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
|
||||
pos.(DirectPosition).getIndex() = -1 and
|
||||
instr.getEnclosingFunction() = f.getUnderlyingCallable()
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = "this" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A parameter node that is part of a summary.
|
||||
*/
|
||||
class SummaryParameterNode extends AbstractParameterNode, FlowSummaryNode {
|
||||
SummaryParameterNode() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
private ParameterPosition getPosition() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result)
|
||||
}
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition p) {
|
||||
c.getUnderlyingCallable() = this.getSummarizedCallable() and
|
||||
p = this.getPosition()
|
||||
}
|
||||
}
|
||||
|
||||
private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode,
|
||||
BodyLessParameterNodeImpl
|
||||
{
|
||||
DirectBodyLessParameterNode() { indirectionIndex = 0 }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
|
||||
exists(Function func |
|
||||
this.getFunction() = func and
|
||||
f.asSourceCallable() = func and
|
||||
func.getParameter(pos.(DirectPosition).getIndex()) = p
|
||||
)
|
||||
}
|
||||
|
||||
override Parameter getParameter() { result = p }
|
||||
}
|
||||
|
||||
private class IndirectBodyLessParameterNode extends AbstractIndirectParameterNode,
|
||||
BodyLessParameterNodeImpl
|
||||
{
|
||||
IndirectBodyLessParameterNode() { not this instanceof DirectBodyLessParameterNode }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
|
||||
exists(Function func, int argumentPosition |
|
||||
this.getFunction() = func and
|
||||
f.asSourceCallable() = func and
|
||||
indirectPositionHasArgumentIndexAndIndex(pos, argumentPosition, indirectionIndex) and
|
||||
func.getParameter(argumentPosition) = p
|
||||
)
|
||||
}
|
||||
|
||||
override int getIndirectionIndex() {
|
||||
result = BodyLessParameterNodeImpl.super.getIndirectionIndex()
|
||||
}
|
||||
|
||||
override Parameter getParameter() { result = p }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1753,6 +1907,22 @@ abstract private class PartialDefinitionNode extends PostUpdateNode {
|
||||
abstract Expr getDefinedExpr();
|
||||
}
|
||||
|
||||
/**
|
||||
* A `PostUpdateNode` that is part of a flow summary. These are synthesized,
|
||||
* for example, when a models-as-data summary models a write to a field since
|
||||
* the write needs to target a `PostUpdateNode`.
|
||||
*/
|
||||
class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode {
|
||||
SummaryPostUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(),
|
||||
result.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node that represents the value of a variable after a function call that
|
||||
* may have changed the variable because it's passed by reference.
|
||||
@@ -1889,10 +2059,20 @@ cached
|
||||
private module Cached {
|
||||
/**
|
||||
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step.
|
||||
* (intra-procedural) step. This relation is only used for local dataflow
|
||||
* (for example `DataFlow::localFlow(source, sink)`) so it contains
|
||||
* special cases that should only apply to local dataflow.
|
||||
*/
|
||||
cached
|
||||
predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFrom, nodeTo, _) }
|
||||
predicate localFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
// common dataflow steps
|
||||
simpleLocalFlowStep(nodeFrom, nodeTo, _)
|
||||
or
|
||||
// models-as-data summarized flow for local data flow (i.e. special case for flow
|
||||
// through calls to modeled functions, without relying on global dataflow to join
|
||||
// the dots).
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo, _)
|
||||
}
|
||||
|
||||
private predicate indirectionOperandFlow(RawIndirectOperand nodeFrom, Node nodeTo) {
|
||||
nodeFrom != nodeTo and
|
||||
@@ -1958,8 +2138,9 @@ private module Cached {
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* This is the local flow predicate that's used as a building block in global
|
||||
* data flow. It may have less flow than the `localFlowStep` predicate.
|
||||
* This is the local flow predicate that's used as a building block in both
|
||||
* local and global data flow. It may have less flow than the `localFlowStep`
|
||||
* predicate.
|
||||
*/
|
||||
cached
|
||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
||||
@@ -2001,6 +2182,10 @@ private module Cached {
|
||||
// function such as `operator[]`.
|
||||
reverseFlow(nodeFrom, nodeTo) and
|
||||
model = ""
|
||||
or
|
||||
// models-as-data summarized flow
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
|
||||
}
|
||||
|
||||
private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
|
||||
@@ -2242,6 +2427,8 @@ private Field getAFieldWithSize(Union u, int bytes) {
|
||||
cached
|
||||
private newtype TContent =
|
||||
TFieldContent(Field f, int indirectionIndex) {
|
||||
// the indirection index for field content starts at 1 (because `TFieldContent` is thought of as
|
||||
// the address of the field, `FieldAddress` in the IR).
|
||||
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(f.getUnspecifiedType())] and
|
||||
// Reads and writes of union fields are tracked using `UnionContent`.
|
||||
not f.getDeclaringType() instanceof Union
|
||||
@@ -2251,7 +2438,8 @@ private newtype TContent =
|
||||
f = u.getAField() and
|
||||
bytes = getFieldSize(f) and
|
||||
// We key `UnionContent` by the union instead of its fields since a write to one
|
||||
// field can be read by any read of the union's fields.
|
||||
// field can be read by any read of the union's fields. Again, the indirection index
|
||||
// is 1-based (because 0 is considered the address).
|
||||
indirectionIndex =
|
||||
[1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))]
|
||||
)
|
||||
@@ -2285,16 +2473,14 @@ class Content extends TContent {
|
||||
abstract predicate impliesClearOf(Content c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string consisting of `n` star characters ("*"), where n >= 0. This is
|
||||
* used to represent indirection.
|
||||
*/
|
||||
bindingset[n]
|
||||
string repeatStars(int n) { result = concat(int i | i in [1 .. n] | "*") }
|
||||
|
||||
private module ContentStars {
|
||||
private int maxNumberOfIndirections() { result = max(any(Content c).getIndirectionIndex()) }
|
||||
|
||||
private string repeatStars(int n) {
|
||||
n = 0 and result = ""
|
||||
or
|
||||
n = [1 .. maxNumberOfIndirections()] and
|
||||
result = "*" + repeatStars(n - 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of stars (i.e., `*`s) needed to produce the `toString`
|
||||
* output for `c`.
|
||||
@@ -2374,6 +2560,12 @@ class UnionContent extends Content, TUnionContent {
|
||||
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
|
||||
*/
|
||||
class ContentSet instanceof Content {
|
||||
/**
|
||||
* Holds if this content set is the singleton `{c}`. At present, this is
|
||||
* the only kind of content set supported in C/C++.
|
||||
*/
|
||||
predicate isSingleton(Content c) { this = c }
|
||||
|
||||
/** Gets a content that may be stored into when storing into this set. */
|
||||
Content getAStoreContent() { result = this }
|
||||
|
||||
@@ -2591,5 +2783,5 @@ class AdditionalCallTarget extends Unit {
|
||||
/**
|
||||
* Gets a viable target for `call`.
|
||||
*/
|
||||
abstract DataFlowCallable viableTarget(Call call);
|
||||
abstract Declaration viableTarget(Call call);
|
||||
}
|
||||
|
||||
@@ -3,12 +3,26 @@
|
||||
* `toString` for `Instruction` and `Operand` dataflow nodes.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import codeql.util.Unit
|
||||
private import Node0ToString
|
||||
private import DataFlowUtil
|
||||
private import DataFlowPrivate
|
||||
|
||||
/**
|
||||
* Gets the string representation of the unconverted expression `loc` if
|
||||
* `loc` is an `Expression`.
|
||||
*
|
||||
* Otherwise, this gets the string representation of `loc`.
|
||||
*/
|
||||
private string unconvertedAstToString(Locatable loc) {
|
||||
result = loc.(Expr).getUnconverted().toString()
|
||||
or
|
||||
not loc instanceof Expr and
|
||||
result = loc.toString()
|
||||
}
|
||||
|
||||
private class NormalNode0ToString extends Node0ToString {
|
||||
NormalNode0ToString() {
|
||||
// Silence warning about `this` not being bound.
|
||||
@@ -18,14 +32,10 @@ private class NormalNode0ToString extends Node0ToString {
|
||||
override string instructionToString(Instruction i) {
|
||||
if i.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
|
||||
then result = "this"
|
||||
else result = i.getAst().toString()
|
||||
else result = unconvertedAstToString(i.getAst())
|
||||
}
|
||||
|
||||
override string operandToString(Operand op) {
|
||||
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
|
||||
then result = "this"
|
||||
else result = op.getDef().getAst().toString()
|
||||
}
|
||||
override string operandToString(Operand op) { result = this.instructionToString(op.getDef()) }
|
||||
|
||||
override string toExprString(Node n) {
|
||||
result = n.asExpr(0).toString()
|
||||
|
||||
@@ -19,15 +19,6 @@ private module SourceVariables {
|
||||
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||
}
|
||||
|
||||
private int maxNumberOfIndirections() { result = max(SourceVariable sv | | sv.getIndirection()) }
|
||||
|
||||
private string repeatStars(int n) {
|
||||
n = 0 and result = ""
|
||||
or
|
||||
n = [1 .. maxNumberOfIndirections()] and
|
||||
result = "*" + repeatStars(n - 1)
|
||||
}
|
||||
|
||||
class SourceVariable extends TSourceVariable {
|
||||
BaseSourceVariable base;
|
||||
int ind;
|
||||
@@ -74,19 +65,28 @@ private module SourceVariables {
|
||||
import SourceVariables
|
||||
|
||||
/**
|
||||
* Holds if the `(operand, indirectionIndex)` columns should be
|
||||
* assigned a `RawIndirectOperand` value.
|
||||
* Holds if `indirectionIndex` is a valid non-zero indirection index for
|
||||
* operand `op`. That is, `indirectionIndex` is between 1 and the maximum
|
||||
* indirection for the operand's type.
|
||||
*/
|
||||
predicate hasRawIndirectOperand(Operand op, int indirectionIndex) {
|
||||
predicate hasIndirectOperand(Operand op, int indirectionIndex) {
|
||||
exists(CppType type, int m |
|
||||
not ignoreOperand(op) and
|
||||
type = getLanguageType(op) and
|
||||
m = countIndirectionsForCppType(type) and
|
||||
indirectionIndex = [1 .. m] and
|
||||
not hasIRRepresentationOfIndirectOperand(op, indirectionIndex, _, _)
|
||||
indirectionIndex = [1 .. m]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `(operand, indirectionIndex)` columns should be
|
||||
* assigned a `RawIndirectOperand` value.
|
||||
*/
|
||||
predicate hasRawIndirectOperand(Operand op, int indirectionIndex) {
|
||||
hasIndirectOperand(op, indirectionIndex) and
|
||||
not hasIRRepresentationOfIndirectOperand(op, indirectionIndex, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `(instr, indirectionIndex)` columns should be
|
||||
* assigned a `RawIndirectInstruction` value.
|
||||
@@ -443,6 +443,8 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
||||
|
||||
Parameter getParameter() { result = p }
|
||||
|
||||
int getArgumentIndex() { result = p.getIndex() }
|
||||
|
||||
override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, ind) }
|
||||
|
||||
override int getIndirection() { result = ind + 1 }
|
||||
@@ -891,7 +893,7 @@ private predicate isArgumentOfCallableInstruction(DataFlowCall call, Instruction
|
||||
}
|
||||
|
||||
private predicate isArgumentOfCallableOperand(DataFlowCall call, Operand operand) {
|
||||
operand.(ArgumentOperand).getCall() = call
|
||||
operand = call.getArgumentOperand(_)
|
||||
or
|
||||
exists(FieldAddressInstruction fai |
|
||||
fai.getObjectAddressOperand() = operand and
|
||||
|
||||
@@ -6,16 +6,26 @@ private import semmle.code.cpp.models.interfaces.SideEffect
|
||||
private import DataFlowUtil
|
||||
private import DataFlowPrivate
|
||||
private import SsaInternals as Ssa
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import semmle.code.cpp.ir.dataflow.FlowSteps
|
||||
|
||||
/**
|
||||
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step.
|
||||
* (intra-procedural) step. This relation is only used for local taint flow
|
||||
* (for example `TaintTracking::localTaint(source, sink)`) so it may contain
|
||||
* special cases that should only apply to local taint flow.
|
||||
*/
|
||||
predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
// dataflow step
|
||||
DataFlow::localFlowStep(nodeFrom, nodeTo)
|
||||
or
|
||||
// taint flow step
|
||||
localAdditionalTaintStep(nodeFrom, nodeTo, _)
|
||||
or
|
||||
// models-as-data summarized flow for local data flow (i.e. special case for flow
|
||||
// through calls to modeled functions, without relying on global dataflow to join
|
||||
// the dots).
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(nodeFrom, nodeTo, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,6 +52,10 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT
|
||||
any(Ssa::Indirection ind).isAdditionalTaintStep(nodeFrom, nodeTo) and
|
||||
model = ""
|
||||
or
|
||||
// models-as-data summarized flow
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
|
||||
or
|
||||
// object->field conflation for content that is a `TaintInheritingContent`.
|
||||
exists(DataFlow::ContentSet f |
|
||||
readStep(nodeFrom, f, nodeTo) and
|
||||
|
||||
@@ -41,5 +41,5 @@ class IREscapeAnalysisConfiguration extends TIREscapeAnalysisConfiguration {
|
||||
* Holds if the escape analysis done by SSA construction should be sound. By default, the SSA is
|
||||
* built assuming that no variable's address ever escapes.
|
||||
*/
|
||||
predicate useSoundEscapeAnalysis() { none() }
|
||||
predicate useSoundEscapeAnalysis() { any() }
|
||||
}
|
||||
|
||||
@@ -1259,7 +1259,9 @@ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr {
|
||||
expr instanceof NotExpr or
|
||||
expr instanceof ComplementExpr or
|
||||
expr instanceof UnaryPlusExpr or
|
||||
expr instanceof UnaryMinusExpr
|
||||
expr instanceof UnaryMinusExpr or
|
||||
expr instanceof CoAwaitExpr or
|
||||
expr instanceof CoYieldExpr
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
@@ -1299,6 +1301,12 @@ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr {
|
||||
expr instanceof UnaryPlusExpr and result instanceof Opcode::CopyValue
|
||||
or
|
||||
expr instanceof UnaryMinusExpr and result instanceof Opcode::Negate
|
||||
or
|
||||
// TODO: Use a new opcode to represent "awaiting the value"
|
||||
expr instanceof CoAwaitExpr and result instanceof Opcode::CopyValue
|
||||
or
|
||||
// TODO: Use a new opcode to represent "awaiting the value"
|
||||
expr instanceof CoYieldExpr and result instanceof Opcode::CopyValue
|
||||
}
|
||||
|
||||
private TranslatedExpr getOperand() {
|
||||
|
||||
@@ -1501,3 +1501,41 @@ class TranslatedVlaDeclarationStmt extends TranslatedStmt {
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
class TranslatedCoReturnStmt extends TranslatedStmt {
|
||||
override CoReturnStmt stmt;
|
||||
|
||||
private TranslatedExpr getTranslatedOperand() {
|
||||
result = getTranslatedExpr(stmt.getOperand().getFullyConverted())
|
||||
}
|
||||
|
||||
override TranslatedExpr getChildInternal(int id) {
|
||||
id = 0 and
|
||||
result = this.getTranslatedOperand()
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getTranslatedOperand().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getTranslatedOperand() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
private import implementations.Allocation
|
||||
private import implementations.Deallocation
|
||||
private import implementations.Fopen
|
||||
private import implementations.Fread
|
||||
private import implementations.Getenv
|
||||
private import implementations.Gets
|
||||
@@ -41,4 +42,4 @@ private import implementations.SqLite3
|
||||
private import implementations.PostgreSql
|
||||
private import implementations.System
|
||||
private import implementations.StructuredExceptionHandling
|
||||
private import implementations.Fopen
|
||||
private import implementations.ZMQ
|
||||
|
||||
@@ -112,3 +112,21 @@ private class GetsFunction extends DataFlowFunction, ArrayFunction, AliasFunctio
|
||||
|
||||
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* A model for `getc` and similar functions that are flow sources.
|
||||
*/
|
||||
private class GetcSource extends SourceModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;getc;;;ReturnValue;remote", ";;false;getwc;;;ReturnValue;remote",
|
||||
";;false;_getc_nolock;;;ReturnValue;remote", ";;false;_getwc_nolock;;;ReturnValue;remote",
|
||||
";;false;getch;;;ReturnValue;local", ";;false;_getch;;;ReturnValue;local",
|
||||
";;false;_getwch;;;ReturnValue;local", ";;false;_getch_nolock;;;ReturnValue;local",
|
||||
";;false;_getwch_nolock;;;ReturnValue;local", ";;false;getchar;;;ReturnValue;local",
|
||||
";;false;getwchar;;;ReturnValue;local", ";;false;_getchar_nolock;;;ReturnValue;local",
|
||||
";;false;_getwchar_nolock;;;ReturnValue;local",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
45
cpp/ql/lib/semmle/code/cpp/models/implementations/ZMQ.qll
Normal file
45
cpp/ql/lib/semmle/code/cpp/models/implementations/ZMQ.qll
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Provides implementation classes modeling the ZeroMQ networking library.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
|
||||
/**
|
||||
* Remote flow sources.
|
||||
*/
|
||||
private class ZmqSource extends SourceModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;zmq_recv;;;Argument[*1];remote", ";;false;zmq_recvmsg;;;Argument[*1];remote",
|
||||
";;false;zmq_msg_recv;;;Argument[*0];remote",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote flow sinks.
|
||||
*/
|
||||
private class ZmqSinks extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;zmq_send;;;Argument[*1];remote-sink",
|
||||
";;false;zmq_sendmsg;;;Argument[*1];remote-sink",
|
||||
";;false;zmq_msg_send;;;Argument[*0];remote-sink",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow steps.
|
||||
*/
|
||||
private class ZmqSummaries extends SummaryModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;zmq_msg_init_data;;;Argument[*1];Argument[*0];taint",
|
||||
";;false;zmq_msg_data;;;Argument[*0];ReturnValue[*];taint",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
import cpp
|
||||
import FunctionInputsAndOutputs
|
||||
import semmle.code.cpp.models.Models
|
||||
import semmle.code.cpp.dataflow.ExternalFlow
|
||||
|
||||
/**
|
||||
* A library function that returns data that may be read from a network connection.
|
||||
|
||||
@@ -20,6 +20,9 @@ abstract class RemoteFlowSource extends FlowSource { }
|
||||
/** A data flow source of local user input. */
|
||||
abstract class LocalFlowSource extends FlowSource { }
|
||||
|
||||
/**
|
||||
* A remote data flow source that is defined through a `RemoteFlowSourceFunction` model.
|
||||
*/
|
||||
private class RemoteModelSource extends RemoteFlowSource {
|
||||
string sourceType;
|
||||
|
||||
@@ -34,6 +37,9 @@ private class RemoteModelSource extends RemoteFlowSource {
|
||||
override string getSourceType() { result = sourceType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A local data flow source that is defined through a `LocalFlowSourceFunction` model.
|
||||
*/
|
||||
private class LocalModelSource extends LocalFlowSource {
|
||||
string sourceType;
|
||||
|
||||
@@ -48,6 +54,9 @@ private class LocalModelSource extends LocalFlowSource {
|
||||
override string getSourceType() { result = sourceType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A local data flow source that the `argv` parameter to `main`.
|
||||
*/
|
||||
private class ArgvSource extends LocalFlowSource {
|
||||
ArgvSource() {
|
||||
exists(Function main, Parameter argv |
|
||||
@@ -60,12 +69,33 @@ private class ArgvSource extends LocalFlowSource {
|
||||
override string getSourceType() { result = "a command-line argument" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remote data flow source that is defined through 'models as data'.
|
||||
*/
|
||||
private class ExternalRemoteFlowSource extends RemoteFlowSource {
|
||||
ExternalRemoteFlowSource() { sourceNode(this, "remote") }
|
||||
|
||||
override string getSourceType() { result = "external" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A local data flow source that is defined through 'models as data'.
|
||||
*/
|
||||
private class ExternalLocalFlowSource extends LocalFlowSource {
|
||||
ExternalLocalFlowSource() { sourceNode(this, "local") }
|
||||
|
||||
override string getSourceType() { result = "external" }
|
||||
}
|
||||
|
||||
/** A remote data flow sink. */
|
||||
abstract class RemoteFlowSink extends DataFlow::Node {
|
||||
/** Gets a string that describes the type of this flow sink. */
|
||||
abstract string getSinkType();
|
||||
}
|
||||
|
||||
/**
|
||||
* A remote flow sink derived from the `RemoteFlowSinkFunction` model.
|
||||
*/
|
||||
private class RemoteParameterSink extends RemoteFlowSink {
|
||||
string sourceType;
|
||||
|
||||
@@ -79,3 +109,12 @@ private class RemoteParameterSink extends RemoteFlowSink {
|
||||
|
||||
override string getSinkType() { result = sourceType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remote flow sink defined in a CSV model.
|
||||
*/
|
||||
private class RemoteFlowFromCsvSink extends RemoteFlowSink {
|
||||
RemoteFlowFromCsvSink() { sinkNode(this, "remote-sink") }
|
||||
|
||||
override string getSinkType() { result = "remote flow sink" }
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ private module ParameterSinks {
|
||||
}
|
||||
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
|
||||
/**
|
||||
* Holds if `n` represents the expression `e`, and `e` is a pointer that is
|
||||
@@ -149,11 +150,11 @@ private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon
|
||||
predicate isUse(DataFlow::Node n, Expr e) {
|
||||
isUse0(e) and n.asExpr() = e
|
||||
or
|
||||
exists(CallInstruction call, InitializeParameterInstruction init |
|
||||
exists(DataFlowCall call, InitializeParameterInstruction init |
|
||||
n.asOperand().getDef().getUnconvertedResultExpression() = e and
|
||||
pragma[only_bind_into](init) = ParameterSinks::getAnAlwaysDereferencedParameter() and
|
||||
viableParamArg(call, DataFlow::instructionNode(init), n) and
|
||||
pragma[only_bind_out](init.getEnclosingFunction()) =
|
||||
pragma[only_bind_out](call.getStaticCallTarget())
|
||||
pragma[only_bind_out](call.asCallInstruction().getStaticCallTarget())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ predicate useFunc(GlobalVariable v, Function f) {
|
||||
}
|
||||
|
||||
predicate uninitialisedBefore(GlobalVariable v, Function f) {
|
||||
f.hasGlobalName("main")
|
||||
f.hasGlobalName("main") and
|
||||
not initialisedAtDeclaration(v) and
|
||||
not isStdlibVariable(v)
|
||||
or
|
||||
exists(Call call, Function g |
|
||||
uninitialisedBefore(v, g) and
|
||||
@@ -98,10 +100,15 @@ predicate callReaches(Call call, ControlFlowNode successor) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `v` has an initializer. */
|
||||
predicate initialisedAtDeclaration(GlobalVariable v) { exists(v.getInitializer()) }
|
||||
|
||||
/** Holds if `v` is a global variable that does not need to be initialized. */
|
||||
predicate isStdlibVariable(GlobalVariable v) { v.hasGlobalName(["stdin", "stdout", "stderr"]) }
|
||||
|
||||
from GlobalVariable v, Function f
|
||||
where
|
||||
uninitialisedBefore(v, f) and
|
||||
useFunc(v, f)
|
||||
select f,
|
||||
"The variable '" + v.getName() +
|
||||
" is used in this function but may not be initialized when it is called."
|
||||
select f, "The variable $@ is used in this function but may not be initialized when it is called.",
|
||||
v, v.getName()
|
||||
|
||||
@@ -15,6 +15,8 @@ import cpp
|
||||
from StackVariable v, ControlFlowNode def, VariableAccess checked, VariableAccess unchecked
|
||||
where
|
||||
checked = v.getAnAccess() and
|
||||
// The check can often be in a macro for handling exception
|
||||
not checked.isInMacroExpansion() and
|
||||
dereferenced(checked) and
|
||||
unchecked = v.getAnAccess() and
|
||||
dereferenced(unchecked) and
|
||||
|
||||
@@ -16,6 +16,7 @@ import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
import semmle.code.cpp.models.implementations.Memset
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import ExposedSystemData::PathGraph
|
||||
import SystemData
|
||||
|
||||
@@ -23,11 +24,11 @@ module ExposedSystemDataConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source = any(SystemData sd).getAnExpr() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall fc, FunctionInput input, int arg |
|
||||
fc.getTarget().(RemoteFlowSinkFunction).hasRemoteFlowSink(input, _) and
|
||||
input.isParameterDeref(arg) and
|
||||
fc.getArgument(arg).getAChild*() = sink.asIndirectExpr()
|
||||
)
|
||||
sink instanceof RemoteFlowSink
|
||||
or
|
||||
// workaround for cases where the sink contains the tainted thing as a child; this could
|
||||
// probably be handled better with taint inheriting content or similar modeling.
|
||||
exists(RemoteFlowSink sinkNode | sinkNode.asIndirectExpr().getAChild*() = sink.asIndirectExpr())
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
|
||||
5
cpp/ql/src/change-notes/2024-04-09-reduce-FP.md
Normal file
5
cpp/ql/src/change-notes/2024-04-09-reduce-FP.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The "Global variable may be used before initialization" query (`cpp/global-use-before-init`) no longer raises an alert on global variables that are initialized when they are declared.
|
||||
* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion.
|
||||
@@ -11,7 +11,6 @@
|
||||
* external/cwe/cwe-664
|
||||
*/
|
||||
|
||||
// IMPORTANT: This query does not currently find anything since it relies on extractor and analysis improvements that hasn't yet been released
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
@@ -19,26 +18,20 @@ import semmle.code.cpp.models.implementations.StdContainer
|
||||
import semmle.code.cpp.models.implementations.StdMap
|
||||
import semmle.code.cpp.models.implementations.Iterator
|
||||
|
||||
/**
|
||||
* A configuration to track flow from a temporary variable to the qualifier of
|
||||
* a destructor call
|
||||
*/
|
||||
module TempToDestructorConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asInstruction().(VariableAddressInstruction).getIRVariable() instanceof IRTempVariable
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink.asOperand().(ThisArgumentOperand).getCall().getStaticCallTarget() instanceof Destructor
|
||||
}
|
||||
private predicate tempToDestructorSink(DataFlow::Node sink, CallInstruction call) {
|
||||
call = sink.asOperand().(ThisArgumentOperand).getCall() and
|
||||
call.getStaticCallTarget() instanceof Destructor
|
||||
}
|
||||
|
||||
module TempToDestructorFlow = DataFlow::Global<TempToDestructorConfig>;
|
||||
/** Holds if `pun` is the post-update node of the qualifier of `Call`. */
|
||||
private predicate isPostUpdateOfQualifier(CallInstruction call, DataFlow::PostUpdateNode pun) {
|
||||
call.getThisArgumentOperand() = pun.getPreUpdateNode().asOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `DataFlow::Node` that represents a temporary that will be destroyed
|
||||
* by a call to a destructor, or a `DataFlow::Node` that will transitively be
|
||||
* destroyed by a call to a destructor.
|
||||
* by a call to a destructor when `n` is destroyed, or a `DataFlow::Node` that
|
||||
* will transitively be destroyed by a call to a destructor.
|
||||
*
|
||||
* For the latter case, consider something like:
|
||||
* ```
|
||||
@@ -50,22 +43,25 @@ module TempToDestructorFlow = DataFlow::Global<TempToDestructorConfig>;
|
||||
* destroyed by a call to `std::vector<std::vector<int>>::~vector`,
|
||||
* and thus the result of `get_2d_vector()[0]` is also an invalid reference.
|
||||
*/
|
||||
DataFlow::Node getADestroyedNode() {
|
||||
exists(TempToDestructorFlow::PathNode destroyedTemp | destroyedTemp.isSource() |
|
||||
result = destroyedTemp.getNode()
|
||||
or
|
||||
exists(CallInstruction call |
|
||||
result.asInstruction() = call and
|
||||
DataFlow::localFlow(destroyedTemp.getNode(),
|
||||
DataFlow::operandNode(call.getThisArgumentOperand()))
|
||||
|
|
||||
call.getStaticCallTarget() instanceof StdSequenceContainerAt or
|
||||
call.getStaticCallTarget() instanceof StdMapAt
|
||||
)
|
||||
DataFlow::Node getADestroyedNode(DataFlow::Node n) {
|
||||
// Case 1: The pointer that goes into the destructor call is destroyed
|
||||
exists(CallInstruction destructorCall |
|
||||
tempToDestructorSink(n, destructorCall) and
|
||||
isPostUpdateOfQualifier(destructorCall, result)
|
||||
)
|
||||
or
|
||||
// Case 2: Anything that was derived from the temporary that is now destroyed
|
||||
// is also destroyed.
|
||||
exists(CallInstruction call |
|
||||
result.asInstruction() = call and
|
||||
DataFlow::localFlow(DataFlow::operandNode(call.getThisArgumentOperand()), n)
|
||||
|
|
||||
call.getStaticCallTarget() instanceof StdSequenceContainerAt or
|
||||
call.getStaticCallTarget() instanceof StdMapAt
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSinkImpl(DataFlow::Node sink, FunctionCall fc) {
|
||||
predicate destroyedToBeginSink(DataFlow::Node sink, FunctionCall fc) {
|
||||
exists(CallInstruction call |
|
||||
call = sink.asOperand().(ThisArgumentOperand).getCall() and
|
||||
fc = call.getUnconvertedResultExpression() and
|
||||
@@ -74,12 +70,39 @@ predicate isSinkImpl(DataFlow::Node sink, FunctionCall fc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow from any destroyed object to the qualifier of a `begin` or `end` call
|
||||
* A configuration to track flow from a temporary variable to the qualifier of
|
||||
* a destructor call, and subsequently to a qualifier of a call to `begin` or
|
||||
* `end`.
|
||||
*/
|
||||
module DestroyedToBeginConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source = getADestroyedNode() }
|
||||
module Config implements DataFlow::StateConfigSig {
|
||||
newtype FlowState =
|
||||
additional TempToDestructor() or
|
||||
additional DestroyedToBegin(DataFlow::Node n) {
|
||||
exists(DataFlow::Node thisOperand |
|
||||
tempToDestructorSink(thisOperand, _) and
|
||||
n = getADestroyedNode(thisOperand)
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) }
|
||||
predicate isSource(DataFlow::Node source, FlowState state) {
|
||||
source.asInstruction().(VariableAddressInstruction).getIRVariable() instanceof IRTempVariable and
|
||||
state = TempToDestructor()
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
|
||||
) {
|
||||
tempToDestructorSink(node1, _) and
|
||||
state1 = TempToDestructor() and
|
||||
state2 = DestroyedToBegin(node2) and
|
||||
node2 = getADestroyedNode(node1)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink, FlowState state) {
|
||||
// Note: This is a non-trivial cartesian product!
|
||||
// Hopefully, both of these sets are quite small in practice
|
||||
destroyedToBeginSink(sink, _) and state instanceof DestroyedToBegin
|
||||
}
|
||||
|
||||
DataFlow::FlowFeature getAFeature() {
|
||||
// By blocking argument-to-parameter flow we ensure that we don't enter a
|
||||
@@ -96,8 +119,11 @@ module DestroyedToBeginConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
}
|
||||
|
||||
module DestroyedToBeginFlow = DataFlow::Global<DestroyedToBeginConfig>;
|
||||
module Flow = DataFlow::GlobalWithState<Config>;
|
||||
|
||||
from DataFlow::Node source, DataFlow::Node sink, FunctionCall beginOrEnd
|
||||
where DestroyedToBeginFlow::flow(source, sink) and isSinkImpl(sink, beginOrEnd)
|
||||
select source, "This object is destroyed before $@ is called.", beginOrEnd, beginOrEnd.toString()
|
||||
from Flow::PathNode source, Flow::PathNode sink, FunctionCall beginOrEnd, DataFlow::Node mid
|
||||
where
|
||||
Flow::flowPath(source, sink) and
|
||||
destroyedToBeginSink(sink.getNode(), beginOrEnd) and
|
||||
sink.getState() = Config::DestroyedToBegin(mid)
|
||||
select mid, "This object is destroyed before $@ is called.", beginOrEnd, beginOrEnd.toString()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.9.10
|
||||
version: 0.9.11-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
| test.cpp:15:8:15:11 | Load: aptr | VNLength(InitializeParameter: count) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:19:8:19:8 | Load: a | VNLength(Chi: ptr) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:21:8:21:8 | Load: a | VNLength(Chi: ptr) | -1 | ZeroOffset | 0 |
|
||||
| test.cpp:23:8:23:8 | Load: a | VNLength(Chi: ptr) | 1 | ZeroOffset | 0 |
|
||||
| test.cpp:27:8:27:8 | Load: c | VNLength(Chi: ptr) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:28:8:28:24 | Convert: (unsigned char *)... | VNLength(Chi: ptr) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:30:8:30:8 | Load: v | VNLength(Chi: ptr) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:19:8:19:8 | Load: a | VNLength(Load: count) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:21:8:21:8 | Load: a | VNLength(Load: count) | -1 | ZeroOffset | 0 |
|
||||
| test.cpp:23:8:23:8 | Load: a | VNLength(Load: count) | 1 | ZeroOffset | 0 |
|
||||
| test.cpp:27:8:27:8 | Load: c | VNLength(Load: count) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:28:8:28:24 | Convert: (unsigned char *)... | VNLength(Load: count) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:30:8:30:8 | Load: v | VNLength(Load: count) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:34:8:34:12 | Convert: array to pointer conversion | ZeroLength | 100 | ZeroOffset | 0 |
|
||||
| test.cpp:37:10:37:10 | Load: b | VNLength(Chi: ptr) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:37:10:37:10 | Load: b | VNLength(Load: count) | 0 | ZeroOffset | 0 |
|
||||
| test.cpp:44:8:44:8 | Load: a | VNLength(InitializeParameter: count) | 0 | ZeroOffset | 2 |
|
||||
| test.cpp:53:10:53:10 | Load: a | VNLength(InitializeParameter: count) | 0 | ZeroOffset | 2 |
|
||||
| test.cpp:56:10:56:10 | Load: a | VNLength(InitializeParameter: count) | 0 | ZeroOffset | 3 |
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
| inline_assembly.c:10:3:10:7 | Store: ... = ... | positive strictlyPositive |
|
||||
| inline_assembly.c:10:7:10:7 | Constant: (unsigned int)... | positive strictlyPositive |
|
||||
| inline_assembly.c:12:32:12:32 | Load: y | positive strictlyPositive |
|
||||
| inline_assembly.c:21:32:21:32 | Load: y | positive strictlyPositive |
|
||||
| inline_assembly.c:21:29:21:29 | Load: x | positive |
|
||||
| inline_assembly.c:21:32:21:32 | Load: y | positive |
|
||||
| minmax.c:16:9:16:10 | Constant: 1 | positive strictlyPositive |
|
||||
| minmax.c:16:9:16:10 | Store: 1 | positive strictlyPositive |
|
||||
| minmax.c:16:16:16:17 | Constant: 2 | positive strictlyPositive |
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
edges
|
||||
| test.cpp:22:27:22:30 | **argv | test.cpp:29:13:29:20 | *filePath | provenance | |
|
||||
| test.cpp:22:27:22:30 | **argv | test.cpp:23:20:23:26 | *access to array | provenance | |
|
||||
| test.cpp:23:20:23:26 | *access to array | test.cpp:29:13:29:20 | *filePath | provenance | |
|
||||
nodes
|
||||
| test.cpp:22:27:22:30 | **argv | semmle.label | **argv |
|
||||
| test.cpp:23:20:23:26 | *access to array | semmle.label | *access to array |
|
||||
| test.cpp:29:13:29:20 | *filePath | semmle.label | *filePath |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
edges
|
||||
| test.cpp:22:17:22:21 | ... * ... | test.cpp:22:17:22:21 | ... * ... | provenance | |
|
||||
| test.cpp:22:17:22:21 | ... * ... | test.cpp:23:33:23:37 | size1 | provenance | |
|
||||
| test.cpp:37:24:37:27 | size | test.cpp:37:46:37:49 | size | provenance | |
|
||||
| test.cpp:45:36:45:40 | ... * ... | test.cpp:37:24:37:27 | size | provenance | |
|
||||
@@ -7,6 +8,7 @@ nodes
|
||||
| test.cpp:15:31:15:35 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:19:34:19:38 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:22:17:22:21 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:22:17:22:21 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:23:33:23:37 | size1 | semmle.label | size1 |
|
||||
| test.cpp:30:18:30:32 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:31:18:31:32 | ... * ... | semmle.label | ... * ... |
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
edges
|
||||
| test.cpp:4:17:4:22 | call to malloc | test.cpp:4:17:4:22 | call to malloc | provenance | |
|
||||
| test.cpp:4:17:4:22 | call to malloc | test.cpp:6:9:6:11 | arr | provenance | |
|
||||
| test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr | provenance | |
|
||||
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:28:19:28:26 | call to mk_array [p] | provenance | |
|
||||
@@ -6,7 +7,9 @@ edges
|
||||
| test.cpp:21:5:21:7 | *arr [post update] [p] | test.cpp:22:5:22:7 | *arr [p] | provenance | |
|
||||
| test.cpp:21:5:21:24 | ... = ... | test.cpp:21:5:21:7 | *arr [post update] [p] | provenance | |
|
||||
| test.cpp:21:13:21:18 | call to malloc | test.cpp:21:5:21:24 | ... = ... | provenance | |
|
||||
| test.cpp:22:5:22:7 | *arr [p] | test.cpp:19:9:19:16 | *mk_array [p] | provenance | |
|
||||
| test.cpp:22:5:22:7 | *arr [p] | test.cpp:24:12:24:14 | arr [p] | provenance | |
|
||||
| test.cpp:24:12:24:14 | arr [p] | test.cpp:19:9:19:16 | *mk_array [p] | provenance | |
|
||||
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:28:19:28:26 | call to mk_array [p] | provenance | |
|
||||
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | *arr [p] | provenance | |
|
||||
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | *arr [p] | provenance | |
|
||||
| test.cpp:31:9:31:11 | *arr [p] | test.cpp:31:13:31:13 | p | provenance | |
|
||||
@@ -28,7 +31,9 @@ edges
|
||||
| test.cpp:69:5:69:7 | *arr [post update] [p] | test.cpp:70:5:70:7 | *arr [p] | provenance | |
|
||||
| test.cpp:69:5:69:25 | ... = ... | test.cpp:69:5:69:7 | *arr [post update] [p] | provenance | |
|
||||
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... | provenance | |
|
||||
| test.cpp:70:5:70:7 | *arr [p] | test.cpp:67:10:67:19 | **mk_array_p [p] | provenance | |
|
||||
| test.cpp:70:5:70:7 | *arr [p] | test.cpp:72:12:72:14 | *arr [p] | provenance | |
|
||||
| test.cpp:72:12:72:14 | *arr [p] | test.cpp:67:10:67:19 | **mk_array_p [p] | provenance | |
|
||||
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:76:20:76:29 | *call to mk_array_p [p] | provenance | |
|
||||
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:79:9:79:11 | *arr [p] | provenance | |
|
||||
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:83:9:83:11 | *arr [p] | provenance | |
|
||||
| test.cpp:79:9:79:11 | *arr [p] | test.cpp:79:14:79:14 | p | provenance | |
|
||||
@@ -43,6 +48,7 @@ edges
|
||||
| test.cpp:98:18:98:27 | test6_callee output argument [p] | test.cpp:98:18:98:27 | *call to mk_array_p [p] | provenance | |
|
||||
nodes
|
||||
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:6:9:6:11 | arr | semmle.label | arr |
|
||||
| test.cpp:10:9:10:11 | arr | semmle.label | arr |
|
||||
| test.cpp:19:9:19:16 | *mk_array [p] | semmle.label | *mk_array [p] |
|
||||
@@ -50,6 +56,8 @@ nodes
|
||||
| test.cpp:21:5:21:24 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:21:13:21:18 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:22:5:22:7 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:24:12:24:14 | arr [p] | semmle.label | arr [p] |
|
||||
| test.cpp:28:19:28:26 | call to mk_array [p] | semmle.label | call to mk_array [p] |
|
||||
| test.cpp:28:19:28:26 | call to mk_array [p] | semmle.label | call to mk_array [p] |
|
||||
| test.cpp:31:9:31:11 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:31:13:31:13 | p | semmle.label | p |
|
||||
@@ -74,6 +82,8 @@ nodes
|
||||
| test.cpp:69:5:69:25 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:69:14:69:19 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:70:5:70:7 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:72:12:72:14 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | semmle.label | *call to mk_array_p [p] |
|
||||
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | semmle.label | *call to mk_array_p [p] |
|
||||
| test.cpp:79:9:79:11 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:79:14:79:14 | p | semmle.label | p |
|
||||
|
||||
@@ -18,8 +18,9 @@ edges
|
||||
| test.cpp:77:32:77:34 | buf | test.cpp:77:26:77:44 | & ... | provenance | |
|
||||
| test.cpp:79:27:79:34 | buf | test.cpp:70:33:70:33 | p | provenance | |
|
||||
| test.cpp:79:32:79:34 | buf | test.cpp:79:27:79:34 | buf | provenance | |
|
||||
| test.cpp:85:34:85:36 | buf | test.cpp:87:5:87:31 | access to array | provenance | |
|
||||
| test.cpp:85:34:85:36 | buf | test.cpp:88:5:88:27 | access to array | provenance | |
|
||||
| test.cpp:85:21:85:36 | buf | test.cpp:87:5:87:31 | access to array | provenance | |
|
||||
| test.cpp:85:21:85:36 | buf | test.cpp:88:5:88:27 | access to array | provenance | |
|
||||
| test.cpp:85:34:85:36 | buf | test.cpp:85:21:85:36 | buf | provenance | |
|
||||
| test.cpp:96:13:96:15 | arr | test.cpp:96:13:96:18 | access to array | provenance | |
|
||||
| test.cpp:111:17:111:19 | arr | test.cpp:111:17:111:22 | access to array | provenance | |
|
||||
| test.cpp:111:17:111:19 | arr | test.cpp:115:35:115:40 | access to array | provenance | |
|
||||
@@ -32,17 +33,21 @@ edges
|
||||
| test.cpp:119:17:119:19 | arr | test.cpp:119:17:119:22 | access to array | provenance | |
|
||||
| test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array | provenance | |
|
||||
| test.cpp:134:25:134:27 | arr | test.cpp:136:9:136:16 | ... += ... | provenance | |
|
||||
| test.cpp:136:9:136:16 | ... += ... | test.cpp:136:9:136:16 | ... += ... | provenance | |
|
||||
| test.cpp:136:9:136:16 | ... += ... | test.cpp:138:13:138:15 | arr | provenance | |
|
||||
| test.cpp:143:18:143:21 | asdf | test.cpp:134:25:134:27 | arr | provenance | |
|
||||
| test.cpp:143:18:143:21 | asdf | test.cpp:143:18:143:21 | asdf | provenance | |
|
||||
| test.cpp:146:26:146:26 | *p | test.cpp:147:4:147:9 | -- ... | provenance | |
|
||||
| test.cpp:156:12:156:14 | buf | test.cpp:156:12:156:18 | ... + ... | provenance | |
|
||||
| test.cpp:156:12:156:18 | ... + ... | test.cpp:156:12:156:18 | ... + ... | provenance | |
|
||||
| test.cpp:156:12:156:18 | ... + ... | test.cpp:158:17:158:18 | *& ... | provenance | |
|
||||
| test.cpp:158:17:158:18 | *& ... | test.cpp:146:26:146:26 | *p | provenance | |
|
||||
| test.cpp:218:23:218:28 | buffer | test.cpp:220:5:220:11 | access to array | provenance | |
|
||||
| test.cpp:218:23:218:28 | buffer | test.cpp:221:5:221:11 | access to array | provenance | |
|
||||
| test.cpp:229:25:229:29 | array | test.cpp:231:5:231:10 | access to array | provenance | |
|
||||
| test.cpp:229:25:229:29 | array | test.cpp:232:5:232:10 | access to array | provenance | |
|
||||
| test.cpp:218:16:218:28 | buffer | test.cpp:220:5:220:11 | access to array | provenance | |
|
||||
| test.cpp:218:16:218:28 | buffer | test.cpp:221:5:221:11 | access to array | provenance | |
|
||||
| test.cpp:218:23:218:28 | buffer | test.cpp:218:16:218:28 | buffer | provenance | |
|
||||
| test.cpp:229:17:229:29 | array | test.cpp:231:5:231:10 | access to array | provenance | |
|
||||
| test.cpp:229:17:229:29 | array | test.cpp:232:5:232:10 | access to array | provenance | |
|
||||
| test.cpp:229:25:229:29 | array | test.cpp:229:17:229:29 | array | provenance | |
|
||||
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array | provenance | |
|
||||
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array | provenance | |
|
||||
| test.cpp:274:14:274:20 | buffer3 | test.cpp:245:30:245:30 | p | provenance | |
|
||||
@@ -61,13 +66,16 @@ edges
|
||||
| test.cpp:306:20:306:23 | arr1 | test.cpp:306:20:306:23 | arr1 | provenance | |
|
||||
| test.cpp:309:20:309:23 | arr2 | test.cpp:292:25:292:27 | arr | provenance | |
|
||||
| test.cpp:309:20:309:23 | arr2 | test.cpp:309:20:309:23 | arr2 | provenance | |
|
||||
| test.cpp:319:13:319:27 | ... = ... | test.cpp:325:24:325:26 | end | provenance | |
|
||||
| test.cpp:319:19:319:22 | temp | test.cpp:319:19:319:27 | ... + ... | provenance | |
|
||||
| test.cpp:319:19:319:22 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
|
||||
| test.cpp:319:19:319:27 | ... + ... | test.cpp:325:24:325:26 | end | provenance | |
|
||||
| test.cpp:319:19:319:27 | ... + ... | test.cpp:319:13:319:27 | ... = ... | provenance | |
|
||||
| test.cpp:322:13:322:27 | ... = ... | test.cpp:325:24:325:26 | end | provenance | |
|
||||
| test.cpp:322:19:322:22 | temp | test.cpp:322:19:322:27 | ... + ... | provenance | |
|
||||
| test.cpp:322:19:322:22 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
|
||||
| test.cpp:322:19:322:27 | ... + ... | test.cpp:325:24:325:26 | end | provenance | |
|
||||
| test.cpp:322:19:322:27 | ... + ... | test.cpp:322:13:322:27 | ... = ... | provenance | |
|
||||
| test.cpp:324:23:324:26 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
|
||||
| test.cpp:324:23:324:32 | ... + ... | test.cpp:324:23:324:32 | ... + ... | provenance | |
|
||||
| test.cpp:324:23:324:32 | ... + ... | test.cpp:325:15:325:19 | temp2 | provenance | |
|
||||
nodes
|
||||
| test.cpp:34:5:34:24 | access to array | semmle.label | access to array |
|
||||
@@ -103,6 +111,7 @@ nodes
|
||||
| test.cpp:77:32:77:34 | buf | semmle.label | buf |
|
||||
| test.cpp:79:27:79:34 | buf | semmle.label | buf |
|
||||
| test.cpp:79:32:79:34 | buf | semmle.label | buf |
|
||||
| test.cpp:85:21:85:36 | buf | semmle.label | buf |
|
||||
| test.cpp:85:34:85:36 | buf | semmle.label | buf |
|
||||
| test.cpp:87:5:87:31 | access to array | semmle.label | access to array |
|
||||
| test.cpp:88:5:88:27 | access to array | semmle.label | access to array |
|
||||
@@ -118,6 +127,7 @@ nodes
|
||||
| test.cpp:128:9:128:14 | access to array | semmle.label | access to array |
|
||||
| test.cpp:134:25:134:27 | arr | semmle.label | arr |
|
||||
| test.cpp:136:9:136:16 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:136:9:136:16 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:138:13:138:15 | arr | semmle.label | arr |
|
||||
| test.cpp:143:18:143:21 | asdf | semmle.label | asdf |
|
||||
| test.cpp:143:18:143:21 | asdf | semmle.label | asdf |
|
||||
@@ -125,10 +135,13 @@ nodes
|
||||
| test.cpp:147:4:147:9 | -- ... | semmle.label | -- ... |
|
||||
| test.cpp:156:12:156:14 | buf | semmle.label | buf |
|
||||
| test.cpp:156:12:156:18 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:156:12:156:18 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:158:17:158:18 | *& ... | semmle.label | *& ... |
|
||||
| test.cpp:218:16:218:28 | buffer | semmle.label | buffer |
|
||||
| test.cpp:218:23:218:28 | buffer | semmle.label | buffer |
|
||||
| test.cpp:220:5:220:11 | access to array | semmle.label | access to array |
|
||||
| test.cpp:221:5:221:11 | access to array | semmle.label | access to array |
|
||||
| test.cpp:229:17:229:29 | array | semmle.label | array |
|
||||
| test.cpp:229:25:229:29 | array | semmle.label | array |
|
||||
| test.cpp:231:5:231:10 | access to array | semmle.label | access to array |
|
||||
| test.cpp:232:5:232:10 | access to array | semmle.label | access to array |
|
||||
@@ -152,12 +165,15 @@ nodes
|
||||
| test.cpp:306:20:306:23 | arr1 | semmle.label | arr1 |
|
||||
| test.cpp:309:20:309:23 | arr2 | semmle.label | arr2 |
|
||||
| test.cpp:309:20:309:23 | arr2 | semmle.label | arr2 |
|
||||
| test.cpp:319:13:319:27 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:319:19:319:22 | temp | semmle.label | temp |
|
||||
| test.cpp:319:19:319:27 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:322:13:322:27 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:322:19:322:22 | temp | semmle.label | temp |
|
||||
| test.cpp:322:19:322:27 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:324:23:324:26 | temp | semmle.label | temp |
|
||||
| test.cpp:324:23:324:32 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:324:23:324:32 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:325:15:325:19 | temp2 | semmle.label | temp2 |
|
||||
| test.cpp:325:24:325:26 | end | semmle.label | end |
|
||||
| test.cpp:325:24:325:26 | end | semmle.label | end |
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
edges
|
||||
| test.cpp:45:18:45:23 | buffer | test.cpp:45:7:45:10 | *func | provenance | |
|
||||
| test.cpp:74:24:74:30 | medical | test.cpp:78:24:78:27 | temp | provenance | |
|
||||
| test.cpp:45:18:45:23 | buffer | test.cpp:47:10:47:15 | buffer | provenance | |
|
||||
| test.cpp:47:10:47:15 | buffer | test.cpp:45:7:45:10 | *func | provenance | |
|
||||
| test.cpp:74:24:74:30 | medical | test.cpp:77:16:77:22 | medical | provenance | |
|
||||
| test.cpp:74:24:74:30 | medical | test.cpp:81:22:81:28 | medical | provenance | |
|
||||
| test.cpp:77:16:77:22 | medical | test.cpp:77:16:77:22 | medical | provenance | |
|
||||
| test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp | provenance | |
|
||||
| test.cpp:77:16:77:22 | medical | test.cpp:81:22:81:28 | medical | provenance | |
|
||||
| test.cpp:81:17:81:20 | call to func | test.cpp:81:17:81:20 | call to func | provenance | |
|
||||
| test.cpp:81:17:81:20 | call to func | test.cpp:82:24:82:28 | buff5 | provenance | |
|
||||
| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer | provenance | |
|
||||
| test.cpp:81:22:81:28 | medical | test.cpp:81:17:81:20 | call to func | provenance | |
|
||||
@@ -12,12 +15,15 @@ edges
|
||||
nodes
|
||||
| test.cpp:45:7:45:10 | *func | semmle.label | *func |
|
||||
| test.cpp:45:18:45:23 | buffer | semmle.label | buffer |
|
||||
| test.cpp:47:10:47:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:57:9:57:18 | theZipcode | semmle.label | theZipcode |
|
||||
| test.cpp:74:24:74:30 | medical | semmle.label | medical |
|
||||
| test.cpp:74:24:74:30 | medical | semmle.label | medical |
|
||||
| test.cpp:77:16:77:22 | medical | semmle.label | medical |
|
||||
| test.cpp:77:16:77:22 | medical | semmle.label | medical |
|
||||
| test.cpp:78:24:78:27 | temp | semmle.label | temp |
|
||||
| test.cpp:81:17:81:20 | call to func | semmle.label | call to func |
|
||||
| test.cpp:81:17:81:20 | call to func | semmle.label | call to func |
|
||||
| test.cpp:81:22:81:28 | medical | semmle.label | medical |
|
||||
| test.cpp:82:24:82:28 | buff5 | semmle.label | buff5 |
|
||||
| test.cpp:96:37:96:46 | theZipcode | semmle.label | theZipcode |
|
||||
|
||||
@@ -2,12 +2,9 @@
|
||||
| test.cpp:680:30:680:30 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:680:17:680:17 | call to end | call to end |
|
||||
| test.cpp:683:31:683:32 | call to at | This object is destroyed before $@ is called. | test.cpp:683:17:683:17 | call to begin | call to begin |
|
||||
| test.cpp:683:31:683:32 | call to at | This object is destroyed before $@ is called. | test.cpp:683:17:683:17 | call to end | call to end |
|
||||
| test.cpp:689:17:689:29 | temporary object | This object is destroyed before $@ is called. | test.cpp:689:31:689:35 | call to begin | call to begin |
|
||||
| test.cpp:689:46:689:58 | temporary object | This object is destroyed before $@ is called. | test.cpp:689:60:689:62 | call to end | call to end |
|
||||
| test.cpp:689:46:689:58 | pointer to ~vector output argument | This object is destroyed before $@ is called. | test.cpp:689:60:689:62 | call to end | call to end |
|
||||
| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:703:19:703:23 | call to begin | call to begin |
|
||||
| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:703:36:703:38 | call to end | call to end |
|
||||
| test.cpp:716:36:716:48 | temporary object | This object is destroyed before $@ is called. | test.cpp:716:17:716:17 | call to begin | call to begin |
|
||||
| test.cpp:716:36:716:48 | temporary object | This object is destroyed before $@ is called. | test.cpp:716:17:716:17 | call to end | call to end |
|
||||
| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:750:17:750:17 | call to begin | call to begin |
|
||||
| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:750:17:750:17 | call to end | call to end |
|
||||
| test.cpp:735:23:735:23 | call to operator[] | This object is destroyed before $@ is called. | test.cpp:759:17:759:17 | call to begin | call to begin |
|
||||
|
||||
@@ -713,7 +713,7 @@ void test() {
|
||||
for(auto it = v.begin(); it != v.end(); ++it) {} // GOOD
|
||||
}
|
||||
|
||||
for (auto x : return_self_by_ref(returnValue())) {} // BAD
|
||||
for (auto x : return_self_by_ref(returnValue())) {} // BAD [NOT DETECTED]
|
||||
|
||||
for (auto x : return_self_by_value(returnValue())) {} // GOOD
|
||||
}
|
||||
@@ -766,3 +766,30 @@ void test2() {
|
||||
for (auto x : value) {}
|
||||
}
|
||||
}
|
||||
|
||||
void test3() {
|
||||
const std::vector<std::vector<int>>& v = returnValue(); // GOOD
|
||||
for(const std::vector<int>& x : v) {}
|
||||
}
|
||||
|
||||
struct A : public std::vector<int> {
|
||||
void foo(std::vector<int>& result) {
|
||||
int i = 0;
|
||||
while (i < 10) {
|
||||
A chunk;
|
||||
result.insert(result.end(), chunk.begin(), chunk.end());
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
~A() = default;
|
||||
};
|
||||
|
||||
void test4() {
|
||||
// This creates a temporary, after which `~A` is called at the semicolon, and
|
||||
// `~A` calls `~vector<int>` inside the compiler-generated destructor.
|
||||
// If we don't preserve the call context and return to the destructor call in this
|
||||
// function we may end up in the destructor call `chunk.~A()`in `A.foo`. This destructor
|
||||
// call can flow to `begin` through the back-edge and cause a strange FP.
|
||||
auto zero = A().size();
|
||||
}
|
||||
@@ -125,8 +125,8 @@
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:3:384:8 | *call to memcpy |
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:10:384:13 | memcpy output argument |
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:16:384:23 | *& ... |
|
||||
| test.cpp:384:16:384:23 | **(const void *)... | test.cpp:384:3:384:8 | **call to memcpy |
|
||||
| test.cpp:384:16:384:23 | **(const void *)... | test.cpp:384:10:384:13 | memcpy output argument |
|
||||
| test.cpp:384:16:384:23 | **& ... | test.cpp:384:3:384:8 | **call to memcpy |
|
||||
| test.cpp:384:16:384:23 | **& ... | test.cpp:384:10:384:13 | memcpy output argument |
|
||||
| test.cpp:384:17:384:23 | *source1 | test.cpp:384:16:384:23 | *& ... |
|
||||
| test.cpp:384:17:384:23 | source1 | test.cpp:384:16:384:23 | & ... |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:391:16:391:23 | *& ... |
|
||||
@@ -152,8 +152,8 @@
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:3:391:8 | *call to memcpy |
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:10:391:13 | memcpy output argument |
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:16:391:23 | *& ... |
|
||||
| test.cpp:391:16:391:23 | **(const void *)... | test.cpp:391:3:391:8 | **call to memcpy |
|
||||
| test.cpp:391:16:391:23 | **(const void *)... | test.cpp:391:10:391:13 | memcpy output argument |
|
||||
| test.cpp:391:16:391:23 | **& ... | test.cpp:391:3:391:8 | **call to memcpy |
|
||||
| test.cpp:391:16:391:23 | **& ... | test.cpp:391:10:391:13 | memcpy output argument |
|
||||
| test.cpp:391:17:391:23 | *source1 | test.cpp:391:16:391:23 | *& ... |
|
||||
| test.cpp:391:17:391:23 | source1 | test.cpp:391:16:391:23 | & ... |
|
||||
| test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp |
|
||||
|
||||
@@ -7,12 +7,12 @@ incorrectBaseType
|
||||
| flowOut.cpp:84:9:84:10 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||
| flowOut.cpp:101:13:101:14 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||
| self_parameter_flow.cpp:8:8:8:9 | *& ... | Expected 'Node.getType()' to be unsigned char, but it was unsigned char * |
|
||||
| test.cpp:67:28:67:37 | (reference dereference) | Expected 'Node.getType()' to be const int, but it was int * |
|
||||
| test.cpp:67:28:67:37 | call to move | Expected 'Node.getType()' to be const int, but it was int * |
|
||||
| test.cpp:531:39:531:40 | *& ... | Expected 'Node.getType()' to be int, but it was const int * |
|
||||
| test.cpp:615:13:615:21 | *& ... | Expected 'Node.getType()' to be int, but it was void |
|
||||
| test.cpp:704:22:704:25 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||
| test.cpp:715:24:715:25 | *& ... | Expected 'Node.getType()' to be unsigned char, but it was unsigned char * |
|
||||
| test.cpp:848:23:848:25 | (reference dereference) | Expected 'Node.getType()' to be int, but it was int * |
|
||||
| test.cpp:848:23:848:25 | rpx | Expected 'Node.getType()' to be int, but it was int * |
|
||||
| test.cpp:854:10:854:36 | * ... | Expected 'Node.getType()' to be const int, but it was int |
|
||||
| test.cpp:867:10:867:30 | * ... | Expected 'Node.getType()' to be const int, but it was int |
|
||||
| test.cpp:1062:52:1062:53 | *& ... | Expected 'Node.getType()' to be char, but it was char * |
|
||||
|
||||
@@ -6,13 +6,17 @@ edges
|
||||
| A.cpp:28:8:28:10 | *this [c] | A.cpp:28:23:28:26 | *this [c] | provenance | |
|
||||
| A.cpp:28:23:28:26 | *this [c] | A.cpp:28:29:28:29 | c | provenance | |
|
||||
| A.cpp:28:29:28:29 | c | A.cpp:28:8:28:10 | *get | provenance | |
|
||||
| A.cpp:28:29:28:29 | c | A.cpp:28:29:28:29 | c | provenance | |
|
||||
| A.cpp:29:23:29:23 | c | A.cpp:31:20:31:20 | c | provenance | |
|
||||
| A.cpp:31:14:31:21 | call to B [c] | A.cpp:29:15:29:18 | **make [c] | provenance | |
|
||||
| A.cpp:31:14:31:21 | *new [c] | A.cpp:29:15:29:18 | **make [c] | provenance | |
|
||||
| A.cpp:31:14:31:21 | call to B [c] | A.cpp:31:14:31:21 | *new [c] | provenance | |
|
||||
| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c | provenance | |
|
||||
| A.cpp:31:20:31:20 | c | A.cpp:31:14:31:21 | call to B [c] | provenance | |
|
||||
| A.cpp:41:5:41:6 | insert output argument | A.cpp:43:10:43:12 | *& ... | provenance | |
|
||||
| A.cpp:41:15:41:21 | new | A.cpp:41:5:41:6 | insert output argument | provenance | |
|
||||
| A.cpp:47:12:47:18 | new | A.cpp:47:12:47:18 | new | provenance | |
|
||||
| A.cpp:47:12:47:18 | new | A.cpp:48:20:48:20 | c | provenance | |
|
||||
| A.cpp:48:12:48:18 | *call to make [c] | A.cpp:48:12:48:18 | *call to make [c] | provenance | |
|
||||
| A.cpp:48:12:48:18 | *call to make [c] | A.cpp:49:10:49:10 | *b [c] | provenance | |
|
||||
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c | provenance | |
|
||||
| A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | *call to make [c] | provenance | |
|
||||
@@ -28,29 +32,39 @@ edges
|
||||
| A.cpp:57:17:57:23 | new | A.cpp:23:10:23:10 | c | provenance | |
|
||||
| A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | call to B [c] | provenance | |
|
||||
| A.cpp:57:17:57:23 | new | A.cpp:57:17:57:23 | new | provenance | |
|
||||
| A.cpp:64:10:64:15 | *call to setOnB [c] | A.cpp:66:10:66:11 | *b2 [c] | provenance | |
|
||||
| A.cpp:64:5:64:29 | *... = ... [c] | A.cpp:66:10:66:11 | *b2 [c] | provenance | |
|
||||
| A.cpp:64:10:64:15 | *call to setOnB [c] | A.cpp:64:5:64:29 | *... = ... [c] | provenance | |
|
||||
| A.cpp:64:21:64:28 | new | A.cpp:64:10:64:15 | *call to setOnB [c] | provenance | |
|
||||
| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c | provenance | |
|
||||
| A.cpp:66:10:66:11 | *b2 [c] | A.cpp:66:10:66:14 | c | provenance | |
|
||||
| A.cpp:73:10:73:19 | *call to setOnBWrap [c] | A.cpp:75:10:75:11 | *b2 [c] | provenance | |
|
||||
| A.cpp:73:5:73:33 | *... = ... [c] | A.cpp:75:10:75:11 | *b2 [c] | provenance | |
|
||||
| A.cpp:73:10:73:19 | *call to setOnBWrap [c] | A.cpp:73:5:73:33 | *... = ... [c] | provenance | |
|
||||
| A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | *call to setOnBWrap [c] | provenance | |
|
||||
| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c | provenance | |
|
||||
| A.cpp:75:10:75:11 | *b2 [c] | A.cpp:75:10:75:14 | c | provenance | |
|
||||
| A.cpp:78:27:78:27 | c | A.cpp:81:21:81:21 | c | provenance | |
|
||||
| A.cpp:81:10:81:15 | *call to setOnB [c] | A.cpp:78:6:78:15 | **setOnBWrap [c] | provenance | |
|
||||
| A.cpp:81:5:81:22 | *... = ... [c] | A.cpp:82:12:82:24 | *... ? ... : ... [c] | provenance | |
|
||||
| A.cpp:81:10:81:15 | *call to setOnB [c] | A.cpp:81:5:81:22 | *... = ... [c] | provenance | |
|
||||
| A.cpp:81:21:81:21 | c | A.cpp:81:10:81:15 | *call to setOnB [c] | provenance | |
|
||||
| A.cpp:81:21:81:21 | c | A.cpp:85:26:85:26 | c | provenance | |
|
||||
| A.cpp:82:12:82:24 | *... ? ... : ... [c] | A.cpp:78:6:78:15 | **setOnBWrap [c] | provenance | |
|
||||
| A.cpp:85:26:85:26 | c | A.cpp:90:15:90:15 | c | provenance | |
|
||||
| A.cpp:90:7:90:8 | set output argument [c] | A.cpp:85:9:85:14 | **setOnB [c] | provenance | |
|
||||
| A.cpp:90:7:90:8 | set output argument [c] | A.cpp:91:14:91:15 | *b2 [c] | provenance | |
|
||||
| A.cpp:90:15:90:15 | c | A.cpp:27:17:27:17 | c | provenance | |
|
||||
| A.cpp:90:15:90:15 | c | A.cpp:90:7:90:8 | set output argument [c] | provenance | |
|
||||
| A.cpp:91:14:91:15 | *b2 [c] | A.cpp:85:9:85:14 | **setOnB [c] | provenance | |
|
||||
| A.cpp:98:12:98:18 | new | A.cpp:98:12:98:18 | new | provenance | |
|
||||
| A.cpp:98:12:98:18 | new | A.cpp:100:5:100:13 | ... = ... | provenance | |
|
||||
| A.cpp:100:5:100:6 | *c1 [post update] [a] | A.cpp:101:8:101:9 | *c1 [a] | provenance | |
|
||||
| A.cpp:100:5:100:13 | ... = ... | A.cpp:100:5:100:6 | *c1 [post update] [a] | provenance | |
|
||||
| A.cpp:101:8:101:9 | *c1 [a] | A.cpp:103:14:103:14 | *c [a] | provenance | |
|
||||
| A.cpp:103:14:103:14 | *c [a] | A.cpp:107:12:107:13 | *c1 [a] | provenance | |
|
||||
| A.cpp:103:14:103:14 | *c [a] | A.cpp:120:12:120:13 | *c1 [a] | provenance | |
|
||||
| A.cpp:103:14:103:14 | *c [a] | A.cpp:105:18:105:38 | *c [a] | provenance | |
|
||||
| A.cpp:103:14:103:14 | *c [a] | A.cpp:110:18:110:38 | *c [a] | provenance | |
|
||||
| A.cpp:105:18:105:38 | *c [a] | A.cpp:107:12:107:13 | *c1 [a] | provenance | |
|
||||
| A.cpp:107:12:107:13 | *c1 [a] | A.cpp:107:12:107:16 | a | provenance | |
|
||||
| A.cpp:110:18:110:38 | *c [a] | A.cpp:112:7:112:13 | *... = ... [a] | provenance | |
|
||||
| A.cpp:112:7:112:13 | *... = ... [a] | A.cpp:118:18:118:39 | *cc [a] | provenance | |
|
||||
| A.cpp:118:18:118:39 | *cc [a] | A.cpp:120:12:120:13 | *c1 [a] | provenance | |
|
||||
| A.cpp:120:12:120:13 | *c1 [a] | A.cpp:120:12:120:16 | a | provenance | |
|
||||
| A.cpp:124:14:124:14 | *b [c] | A.cpp:131:8:131:8 | f7 output argument [c] | provenance | |
|
||||
| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:124:14:124:14 | *b [c] | provenance | |
|
||||
@@ -73,10 +87,13 @@ edges
|
||||
| A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | *this [post update] [b] | provenance | |
|
||||
| A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | *this [post update] [b] | provenance | |
|
||||
| A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | ... = ... | provenance | |
|
||||
| A.cpp:150:12:150:18 | new | A.cpp:150:12:150:18 | new | provenance | |
|
||||
| A.cpp:150:12:150:18 | new | A.cpp:151:18:151:18 | b | provenance | |
|
||||
| A.cpp:151:12:151:24 | call to D [*b, c] | A.cpp:152:10:152:10 | *d [*b, c] | provenance | |
|
||||
| A.cpp:151:12:151:24 | call to D [*b, c] | A.cpp:153:10:153:10 | *d [*b, c] | provenance | |
|
||||
| A.cpp:151:12:151:24 | call to D [b] | A.cpp:152:10:152:10 | *d [b] | provenance | |
|
||||
| A.cpp:151:12:151:24 | *new [*b, c] | A.cpp:152:10:152:10 | *d [*b, c] | provenance | |
|
||||
| A.cpp:151:12:151:24 | *new [*b, c] | A.cpp:153:10:153:10 | *d [*b, c] | provenance | |
|
||||
| A.cpp:151:12:151:24 | *new [b] | A.cpp:152:10:152:10 | *d [b] | provenance | |
|
||||
| A.cpp:151:12:151:24 | call to D [*b, c] | A.cpp:151:12:151:24 | *new [*b, c] | provenance | |
|
||||
| A.cpp:151:12:151:24 | call to D [b] | A.cpp:151:12:151:24 | *new [b] | provenance | |
|
||||
| A.cpp:151:18:151:18 | D output argument [c] | A.cpp:154:10:154:10 | *b [c] | provenance | |
|
||||
| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | provenance | |
|
||||
| A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] | provenance | |
|
||||
@@ -91,24 +108,31 @@ edges
|
||||
| A.cpp:153:10:153:10 | *d [*b, c] | A.cpp:153:13:153:13 | *b [c] | provenance | |
|
||||
| A.cpp:153:13:153:13 | *b [c] | A.cpp:153:10:153:16 | c | provenance | |
|
||||
| A.cpp:154:10:154:10 | *b [c] | A.cpp:154:10:154:13 | c | provenance | |
|
||||
| A.cpp:159:12:159:18 | new | A.cpp:159:12:159:18 | new | provenance | |
|
||||
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b | provenance | |
|
||||
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | *l1 [head] | provenance | |
|
||||
| A.cpp:160:18:160:60 | *new [head] | A.cpp:161:38:161:39 | *l1 [head] | provenance | |
|
||||
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:160:18:160:60 | *new [head] | provenance | |
|
||||
| A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] | provenance | |
|
||||
| A.cpp:160:29:160:29 | b | A.cpp:181:15:181:21 | newHead | provenance | |
|
||||
| A.cpp:161:18:161:40 | call to MyList [*next, head] | A.cpp:162:38:162:39 | *l2 [*next, head] | provenance | |
|
||||
| A.cpp:161:18:161:40 | *new [*next, head] | A.cpp:162:38:162:39 | *l2 [*next, head] | provenance | |
|
||||
| A.cpp:161:18:161:40 | call to MyList [*next, head] | A.cpp:161:18:161:40 | *new [*next, head] | provenance | |
|
||||
| A.cpp:161:38:161:39 | *l1 [head] | A.cpp:161:18:161:40 | call to MyList [*next, head] | provenance | |
|
||||
| A.cpp:161:38:161:39 | *l1 [head] | A.cpp:181:32:181:35 | *next [head] | provenance | |
|
||||
| A.cpp:162:18:162:40 | call to MyList [*next, *next, head] | A.cpp:165:10:165:11 | *l3 [*next, *next, head] | provenance | |
|
||||
| A.cpp:162:18:162:40 | call to MyList [*next, *next, head] | A.cpp:167:44:167:44 | *l [*next, *next, head] | provenance | |
|
||||
| A.cpp:162:18:162:40 | *new [*next, *next, head] | A.cpp:165:10:165:11 | *l3 [*next, *next, head] | provenance | |
|
||||
| A.cpp:162:18:162:40 | *new [*next, *next, head] | A.cpp:167:22:167:23 | *l3 [*next, *next, head] | provenance | |
|
||||
| A.cpp:162:18:162:40 | call to MyList [*next, *next, head] | A.cpp:162:18:162:40 | *new [*next, *next, head] | provenance | |
|
||||
| A.cpp:162:38:162:39 | *l2 [*next, head] | A.cpp:162:18:162:40 | call to MyList [*next, *next, head] | provenance | |
|
||||
| A.cpp:162:38:162:39 | *l2 [*next, head] | A.cpp:181:32:181:35 | *next [*next, head] | provenance | |
|
||||
| A.cpp:165:10:165:11 | *l3 [*next, *next, head] | A.cpp:165:14:165:17 | *next [*next, head] | provenance | |
|
||||
| A.cpp:165:14:165:17 | *next [*next, head] | A.cpp:165:20:165:23 | *next [head] | provenance | |
|
||||
| A.cpp:165:20:165:23 | *next [head] | A.cpp:165:10:165:29 | head | provenance | |
|
||||
| A.cpp:167:22:167:23 | *l3 [*next, *next, head] | A.cpp:167:44:167:44 | *l [*next, *next, head] | provenance | |
|
||||
| A.cpp:167:40:167:50 | *... = ... [*next, head] | A.cpp:167:44:167:44 | *l [*next, head] | provenance | |
|
||||
| A.cpp:167:40:167:50 | *... = ... [head] | A.cpp:169:12:169:12 | *l [head] | provenance | |
|
||||
| A.cpp:167:44:167:44 | *l [*next, *next, head] | A.cpp:167:47:167:50 | *next [*next, head] | provenance | |
|
||||
| A.cpp:167:44:167:44 | *l [*next, head] | A.cpp:167:47:167:50 | *next [head] | provenance | |
|
||||
| A.cpp:167:47:167:50 | *next [*next, head] | A.cpp:167:44:167:44 | *l [*next, head] | provenance | |
|
||||
| A.cpp:167:47:167:50 | *next [head] | A.cpp:169:12:169:12 | *l [head] | provenance | |
|
||||
| A.cpp:167:47:167:50 | *next [*next, head] | A.cpp:167:40:167:50 | *... = ... [*next, head] | provenance | |
|
||||
| A.cpp:167:47:167:50 | *next [head] | A.cpp:167:40:167:50 | *... = ... [head] | provenance | |
|
||||
| A.cpp:169:12:169:12 | *l [head] | A.cpp:169:12:169:18 | head | provenance | |
|
||||
| A.cpp:173:26:173:26 | *o [c] | A.cpp:173:26:173:26 | *o [c] | provenance | |
|
||||
| A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... | provenance | |
|
||||
@@ -117,20 +141,26 @@ edges
|
||||
| A.cpp:183:7:183:20 | ... = ... | A.cpp:183:7:183:10 | *this [post update] [head] | provenance | |
|
||||
| A.cpp:184:7:184:23 | *... = ... [*next, head] | A.cpp:184:7:184:10 | *this [post update] [*next, *next, head] | provenance | |
|
||||
| A.cpp:184:7:184:23 | *... = ... [head] | A.cpp:184:7:184:10 | *this [post update] [*next, head] | provenance | |
|
||||
| B.cpp:6:15:6:24 | new | B.cpp:6:15:6:24 | new | provenance | |
|
||||
| B.cpp:6:15:6:24 | new | B.cpp:7:25:7:25 | e | provenance | |
|
||||
| B.cpp:7:16:7:35 | call to Box1 [elem1] | B.cpp:8:25:8:26 | *b1 [elem1] | provenance | |
|
||||
| B.cpp:7:16:7:35 | *new [elem1] | B.cpp:8:25:8:26 | *b1 [elem1] | provenance | |
|
||||
| B.cpp:7:16:7:35 | call to Box1 [elem1] | B.cpp:7:16:7:35 | *new [elem1] | provenance | |
|
||||
| B.cpp:7:25:7:25 | e | B.cpp:7:16:7:35 | call to Box1 [elem1] | provenance | |
|
||||
| B.cpp:7:25:7:25 | e | B.cpp:33:16:33:17 | e1 | provenance | |
|
||||
| B.cpp:8:16:8:27 | call to Box2 [*box1, elem1] | B.cpp:9:10:9:11 | *b2 [*box1, elem1] | provenance | |
|
||||
| B.cpp:8:16:8:27 | *new [*box1, elem1] | B.cpp:9:10:9:11 | *b2 [*box1, elem1] | provenance | |
|
||||
| B.cpp:8:16:8:27 | call to Box2 [*box1, elem1] | B.cpp:8:16:8:27 | *new [*box1, elem1] | provenance | |
|
||||
| B.cpp:8:25:8:26 | *b1 [elem1] | B.cpp:8:16:8:27 | call to Box2 [*box1, elem1] | provenance | |
|
||||
| B.cpp:8:25:8:26 | *b1 [elem1] | B.cpp:44:16:44:17 | *b1 [elem1] | provenance | |
|
||||
| B.cpp:9:10:9:11 | *b2 [*box1, elem1] | B.cpp:9:14:9:17 | *box1 [elem1] | provenance | |
|
||||
| B.cpp:9:14:9:17 | *box1 [elem1] | B.cpp:9:10:9:24 | elem1 | provenance | |
|
||||
| B.cpp:15:15:15:27 | new | B.cpp:15:15:15:27 | new | provenance | |
|
||||
| B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e | provenance | |
|
||||
| B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | *b1 [elem2] | provenance | |
|
||||
| B.cpp:16:16:16:38 | *new [elem2] | B.cpp:17:25:17:26 | *b1 [elem2] | provenance | |
|
||||
| B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:16:16:16:38 | *new [elem2] | provenance | |
|
||||
| B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] | provenance | |
|
||||
| B.cpp:16:37:16:37 | e | B.cpp:33:26:33:27 | e2 | provenance | |
|
||||
| B.cpp:17:16:17:27 | call to Box2 [*box1, elem2] | B.cpp:19:10:19:11 | *b2 [*box1, elem2] | provenance | |
|
||||
| B.cpp:17:16:17:27 | *new [*box1, elem2] | B.cpp:19:10:19:11 | *b2 [*box1, elem2] | provenance | |
|
||||
| B.cpp:17:16:17:27 | call to Box2 [*box1, elem2] | B.cpp:17:16:17:27 | *new [*box1, elem2] | provenance | |
|
||||
| B.cpp:17:25:17:26 | *b1 [elem2] | B.cpp:17:16:17:27 | call to Box2 [*box1, elem2] | provenance | |
|
||||
| B.cpp:17:25:17:26 | *b1 [elem2] | B.cpp:44:16:44:17 | *b1 [elem2] | provenance | |
|
||||
| B.cpp:19:10:19:11 | *b2 [*box1, elem2] | B.cpp:19:14:19:17 | *box1 [elem2] | provenance | |
|
||||
@@ -143,8 +173,10 @@ edges
|
||||
| B.cpp:44:16:44:17 | *b1 [elem2] | B.cpp:46:7:46:21 | *... = ... [elem2] | provenance | |
|
||||
| B.cpp:46:7:46:21 | *... = ... [elem1] | B.cpp:46:7:46:10 | *this [post update] [*box1, elem1] | provenance | |
|
||||
| B.cpp:46:7:46:21 | *... = ... [elem2] | B.cpp:46:7:46:10 | *this [post update] [*box1, elem2] | provenance | |
|
||||
| C.cpp:18:12:18:18 | call to C [s1] | C.cpp:19:5:19:5 | *c [s1] | provenance | |
|
||||
| C.cpp:18:12:18:18 | call to C [s3] | C.cpp:19:5:19:5 | *c [s3] | provenance | |
|
||||
| C.cpp:18:12:18:18 | *new [s1] | C.cpp:19:5:19:5 | *c [s1] | provenance | |
|
||||
| C.cpp:18:12:18:18 | *new [s3] | C.cpp:19:5:19:5 | *c [s3] | provenance | |
|
||||
| C.cpp:18:12:18:18 | call to C [s1] | C.cpp:18:12:18:18 | *new [s1] | provenance | |
|
||||
| C.cpp:18:12:18:18 | call to C [s3] | C.cpp:18:12:18:18 | *new [s3] | provenance | |
|
||||
| C.cpp:19:5:19:5 | *c [s1] | C.cpp:27:8:27:11 | *this [s1] | provenance | |
|
||||
| C.cpp:19:5:19:5 | *c [s3] | C.cpp:27:8:27:11 | *this [s3] | provenance | |
|
||||
| C.cpp:22:3:22:3 | *this [post update] [s1] | C.cpp:18:12:18:18 | call to C [s1] | provenance | |
|
||||
@@ -160,38 +192,45 @@ edges
|
||||
| D.cpp:10:11:10:17 | *this [elem] | D.cpp:10:30:10:33 | *this [elem] | provenance | |
|
||||
| D.cpp:10:30:10:33 | *this [elem] | D.cpp:10:30:10:33 | elem | provenance | |
|
||||
| D.cpp:10:30:10:33 | elem | D.cpp:10:11:10:17 | *getElem | provenance | |
|
||||
| D.cpp:10:30:10:33 | elem | D.cpp:10:30:10:33 | elem | provenance | |
|
||||
| D.cpp:11:24:11:24 | e | D.cpp:11:29:11:36 | ... = ... | provenance | |
|
||||
| D.cpp:11:29:11:36 | ... = ... | D.cpp:11:29:11:32 | *this [post update] [elem] | provenance | |
|
||||
| D.cpp:17:11:17:17 | *this [*box, elem] | D.cpp:17:30:17:32 | *this [*box, elem] | provenance | |
|
||||
| D.cpp:17:30:17:32 | *box [elem] | D.cpp:17:11:17:17 | **getBox1 [elem] | provenance | |
|
||||
| D.cpp:17:30:17:32 | *box [elem] | D.cpp:17:30:17:32 | *box [elem] | provenance | |
|
||||
| D.cpp:17:30:17:32 | *this [*box, elem] | D.cpp:17:30:17:32 | *box [elem] | provenance | |
|
||||
| D.cpp:21:30:21:31 | *b2 [*box, elem] | D.cpp:22:10:22:11 | *b2 [*box, elem] | provenance | |
|
||||
| D.cpp:22:10:22:11 | *b2 [*box, elem] | D.cpp:17:11:17:17 | *this [*box, elem] | provenance | |
|
||||
| D.cpp:22:10:22:11 | *b2 [*box, elem] | D.cpp:22:14:22:20 | *call to getBox1 [elem] | provenance | |
|
||||
| D.cpp:22:14:22:20 | *call to getBox1 [elem] | D.cpp:10:11:10:17 | *this [elem] | provenance | |
|
||||
| D.cpp:22:14:22:20 | *call to getBox1 [elem] | D.cpp:22:10:22:33 | call to getElem | provenance | |
|
||||
| D.cpp:28:15:28:24 | new | D.cpp:28:15:28:24 | new | provenance | |
|
||||
| D.cpp:28:15:28:24 | new | D.cpp:30:5:30:20 | ... = ... | provenance | |
|
||||
| D.cpp:30:5:30:5 | *b [post update] [*box, elem] | D.cpp:31:14:31:14 | *b [*box, elem] | provenance | |
|
||||
| D.cpp:30:5:30:20 | ... = ... | D.cpp:30:8:30:10 | *box [post update] [elem] | provenance | |
|
||||
| D.cpp:30:8:30:10 | *box [post update] [elem] | D.cpp:30:5:30:5 | *b [post update] [*box, elem] | provenance | |
|
||||
| D.cpp:31:14:31:14 | *b [*box, elem] | D.cpp:21:30:21:31 | *b2 [*box, elem] | provenance | |
|
||||
| D.cpp:35:15:35:24 | new | D.cpp:35:15:35:24 | new | provenance | |
|
||||
| D.cpp:35:15:35:24 | new | D.cpp:37:21:37:21 | e | provenance | |
|
||||
| D.cpp:37:5:37:5 | *b [post update] [*box, elem] | D.cpp:38:14:38:14 | *b [*box, elem] | provenance | |
|
||||
| D.cpp:37:8:37:10 | setElem output argument [elem] | D.cpp:37:5:37:5 | *b [post update] [*box, elem] | provenance | |
|
||||
| D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e | provenance | |
|
||||
| D.cpp:37:21:37:21 | e | D.cpp:37:8:37:10 | setElem output argument [elem] | provenance | |
|
||||
| D.cpp:38:14:38:14 | *b [*box, elem] | D.cpp:21:30:21:31 | *b2 [*box, elem] | provenance | |
|
||||
| D.cpp:42:15:42:24 | new | D.cpp:42:15:42:24 | new | provenance | |
|
||||
| D.cpp:42:15:42:24 | new | D.cpp:44:5:44:26 | ... = ... | provenance | |
|
||||
| D.cpp:44:5:44:5 | getBox1 output argument [*box, elem] | D.cpp:45:14:45:14 | *b [*box, elem] | provenance | |
|
||||
| D.cpp:44:5:44:26 | ... = ... | D.cpp:44:8:44:14 | *call to getBox1 [post update] [elem] | provenance | |
|
||||
| D.cpp:44:8:44:14 | *call to getBox1 [post update] [elem] | D.cpp:44:5:44:5 | getBox1 output argument [*box, elem] | provenance | |
|
||||
| D.cpp:45:14:45:14 | *b [*box, elem] | D.cpp:21:30:21:31 | *b2 [*box, elem] | provenance | |
|
||||
| D.cpp:49:15:49:24 | new | D.cpp:49:15:49:24 | new | provenance | |
|
||||
| D.cpp:49:15:49:24 | new | D.cpp:51:27:51:27 | e | provenance | |
|
||||
| D.cpp:51:5:51:5 | getBox1 output argument [*box, elem] | D.cpp:52:14:52:14 | *b [*box, elem] | provenance | |
|
||||
| D.cpp:51:8:51:14 | setElem output argument [elem] | D.cpp:51:5:51:5 | getBox1 output argument [*box, elem] | provenance | |
|
||||
| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | provenance | |
|
||||
| D.cpp:51:27:51:27 | e | D.cpp:51:8:51:14 | setElem output argument [elem] | provenance | |
|
||||
| D.cpp:52:14:52:14 | *b [*box, elem] | D.cpp:21:30:21:31 | *b2 [*box, elem] | provenance | |
|
||||
| D.cpp:56:15:56:24 | new | D.cpp:56:15:56:24 | new | provenance | |
|
||||
| D.cpp:56:15:56:24 | new | D.cpp:58:5:58:27 | ... = ... | provenance | |
|
||||
| D.cpp:58:5:58:12 | *boxfield [post update] [*box, elem] | D.cpp:58:5:58:12 | *this [post update] [*boxfield, *box, elem] | provenance | |
|
||||
| D.cpp:58:5:58:12 | *this [post update] [*boxfield, *box, elem] | D.cpp:59:5:59:7 | *this [*boxfield, *box, elem] | provenance | |
|
||||
@@ -227,9 +266,10 @@ edges
|
||||
| aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | aliasing.cpp:30:8:30:9 | *s2 [m1] | provenance | |
|
||||
| aliasing.cpp:29:8:29:9 | *s1 [m1] | aliasing.cpp:29:11:29:12 | m1 | provenance | |
|
||||
| aliasing.cpp:30:8:30:9 | *s2 [m1] | aliasing.cpp:30:11:30:12 | m1 | provenance | |
|
||||
| aliasing.cpp:60:3:60:4 | *s2 [post update] [m1] | aliasing.cpp:62:8:62:12 | *copy2 [m1] | provenance | |
|
||||
| aliasing.cpp:60:3:60:4 | *s2 [post update] [m1] | aliasing.cpp:61:13:61:14 | s2 [m1] | provenance | |
|
||||
| aliasing.cpp:60:3:60:22 | ... = ... | aliasing.cpp:60:3:60:4 | *s2 [post update] [m1] | provenance | |
|
||||
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | ... = ... | provenance | |
|
||||
| aliasing.cpp:61:13:61:14 | s2 [m1] | aliasing.cpp:62:8:62:12 | *copy2 [m1] | provenance | |
|
||||
| aliasing.cpp:62:8:62:12 | *copy2 [m1] | aliasing.cpp:62:14:62:15 | m1 | provenance | |
|
||||
| aliasing.cpp:92:3:92:3 | *w [post update] [s, m1] | aliasing.cpp:93:8:93:8 | *w [s, m1] | provenance | |
|
||||
| aliasing.cpp:92:3:92:23 | ... = ... | aliasing.cpp:92:5:92:5 | *s [post update] [m1] | provenance | |
|
||||
@@ -237,9 +277,11 @@ edges
|
||||
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... | provenance | |
|
||||
| aliasing.cpp:93:8:93:8 | *w [s, m1] | aliasing.cpp:93:10:93:10 | *s [m1] | provenance | |
|
||||
| aliasing.cpp:93:10:93:10 | *s [m1] | aliasing.cpp:93:12:93:13 | m1 | provenance | |
|
||||
| aliasing.cpp:98:3:98:3 | *s [post update] [m1] | aliasing.cpp:101:14:101:19 | *s_copy [m1] | provenance | |
|
||||
| aliasing.cpp:98:3:98:3 | *s [post update] [m1] | aliasing.cpp:100:14:100:14 | s [m1] | provenance | |
|
||||
| aliasing.cpp:98:3:98:21 | ... = ... | aliasing.cpp:98:3:98:3 | *s [post update] [m1] | provenance | |
|
||||
| aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:98:3:98:21 | ... = ... | provenance | |
|
||||
| aliasing.cpp:100:14:100:14 | s [m1] | aliasing.cpp:101:14:101:19 | *s_copy [m1] | provenance | |
|
||||
| aliasing.cpp:101:13:101:22 | *& ... | aliasing.cpp:101:13:101:22 | *& ... | provenance | |
|
||||
| aliasing.cpp:101:13:101:22 | *& ... | aliasing.cpp:102:8:102:10 | * ... | provenance | |
|
||||
| aliasing.cpp:101:14:101:19 | *s_copy [m1] | aliasing.cpp:101:13:101:22 | *& ... | provenance | |
|
||||
| aliasing.cpp:105:23:105:24 | *pa | aliasing.cpp:121:15:121:16 | taint_a_ptr output argument | provenance | |
|
||||
@@ -252,7 +294,8 @@ edges
|
||||
| aliasing.cpp:105:23:105:24 | *pa | aliasing.cpp:175:15:175:22 | taint_a_ptr output argument | provenance | |
|
||||
| aliasing.cpp:105:23:105:24 | *pa | aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | provenance | |
|
||||
| aliasing.cpp:105:23:105:24 | *pa | aliasing.cpp:200:15:200:24 | taint_a_ptr output argument | provenance | |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:105:23:105:24 | *pa | provenance | |
|
||||
| aliasing.cpp:106:3:106:20 | ... = ... | aliasing.cpp:105:23:105:24 | *pa | provenance | |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:106:3:106:20 | ... = ... | provenance | |
|
||||
| aliasing.cpp:121:15:121:16 | taint_a_ptr output argument | aliasing.cpp:122:8:122:12 | access to array | provenance | |
|
||||
| aliasing.cpp:126:15:126:20 | taint_a_ptr output argument | aliasing.cpp:127:8:127:16 | * ... | provenance | |
|
||||
| aliasing.cpp:131:15:131:16 | taint_a_ptr output argument | aliasing.cpp:132:8:132:14 | * ... | provenance | |
|
||||
@@ -274,8 +317,9 @@ edges
|
||||
| aliasing.cpp:176:8:176:9 | *s2 [s, m1] | aliasing.cpp:176:11:176:11 | *s [m1] | provenance | |
|
||||
| aliasing.cpp:176:11:176:11 | *s [m1] | aliasing.cpp:176:13:176:14 | m1 | provenance | |
|
||||
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | aliasing.cpp:187:19:187:19 | *s [post update] [m1] | provenance | |
|
||||
| aliasing.cpp:187:16:187:17 | *s2 [post update] [s, m1] | aliasing.cpp:189:8:189:11 | *s2_2 [s, m1] | provenance | |
|
||||
| aliasing.cpp:187:16:187:17 | *s2 [post update] [s, m1] | aliasing.cpp:188:13:188:14 | s2 [s, m1] | provenance | |
|
||||
| aliasing.cpp:187:19:187:19 | *s [post update] [m1] | aliasing.cpp:187:16:187:17 | *s2 [post update] [s, m1] | provenance | |
|
||||
| aliasing.cpp:188:13:188:14 | s2 [s, m1] | aliasing.cpp:189:8:189:11 | *s2_2 [s, m1] | provenance | |
|
||||
| aliasing.cpp:189:8:189:11 | *s2_2 [s, m1] | aliasing.cpp:189:13:189:13 | *s [m1] | provenance | |
|
||||
| aliasing.cpp:189:13:189:13 | *s [m1] | aliasing.cpp:189:15:189:16 | m1 | provenance | |
|
||||
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument | aliasing.cpp:200:21:200:21 | *s [post update] [m1] | provenance | |
|
||||
@@ -283,12 +327,14 @@ edges
|
||||
| aliasing.cpp:200:21:200:21 | *s [post update] [m1] | aliasing.cpp:200:16:200:18 | *ps2 [post update] [s, m1] | provenance | |
|
||||
| aliasing.cpp:201:8:201:10 | *ps2 [s, m1] | aliasing.cpp:201:13:201:13 | *s [m1] | provenance | |
|
||||
| aliasing.cpp:201:13:201:13 | *s [m1] | aliasing.cpp:201:15:201:16 | m1 | provenance | |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array | provenance | |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array | provenance | |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... | provenance | |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... | provenance | |
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array | provenance | |
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:17:8:17:13 | access to array | provenance | |
|
||||
| arrays.cpp:6:3:6:23 | ... = ... | arrays.cpp:7:8:7:13 | access to array | provenance | |
|
||||
| arrays.cpp:6:3:6:23 | ... = ... | arrays.cpp:8:8:8:13 | access to array | provenance | |
|
||||
| arrays.cpp:6:3:6:23 | ... = ... | arrays.cpp:9:8:9:11 | * ... | provenance | |
|
||||
| arrays.cpp:6:3:6:23 | ... = ... | arrays.cpp:10:8:10:15 | * ... | provenance | |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:6:3:6:23 | ... = ... | provenance | |
|
||||
| arrays.cpp:15:3:15:25 | ... = ... | arrays.cpp:16:8:16:13 | access to array | provenance | |
|
||||
| arrays.cpp:15:3:15:25 | ... = ... | arrays.cpp:17:8:17:13 | access to array | provenance | |
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:15:3:15:25 | ... = ... | provenance | |
|
||||
| arrays.cpp:36:3:36:3 | *o [post update] [nested, arr, data] | arrays.cpp:37:8:37:8 | *o [nested, arr, data] | provenance | |
|
||||
| arrays.cpp:36:3:36:3 | *o [post update] [nested, arr, data] | arrays.cpp:38:8:38:8 | *o [nested, arr, data] | provenance | |
|
||||
| arrays.cpp:36:3:36:17 | *access to array [post update] [data] | arrays.cpp:36:5:36:10 | *nested [post update] [arr, data] | provenance | |
|
||||
@@ -343,15 +389,19 @@ edges
|
||||
| by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:32:12:32:12 | *s [a] | provenance | |
|
||||
| by_reference.cpp:32:12:32:12 | *s [a] | by_reference.cpp:32:15:32:15 | a | provenance | |
|
||||
| by_reference.cpp:32:15:32:15 | a | by_reference.cpp:31:16:31:28 | *nonMemberGetA | provenance | |
|
||||
| by_reference.cpp:32:15:32:15 | a | by_reference.cpp:32:15:32:15 | a | provenance | |
|
||||
| by_reference.cpp:35:9:35:19 | *this [a] | by_reference.cpp:36:12:36:15 | *this [a] | provenance | |
|
||||
| by_reference.cpp:36:12:36:15 | *this [a] | by_reference.cpp:36:18:36:18 | a | provenance | |
|
||||
| by_reference.cpp:36:18:36:18 | a | by_reference.cpp:35:9:35:19 | *getDirectly | provenance | |
|
||||
| by_reference.cpp:36:18:36:18 | a | by_reference.cpp:36:18:36:18 | a | provenance | |
|
||||
| by_reference.cpp:39:9:39:21 | *this [a] | by_reference.cpp:40:12:40:15 | *this [a] | provenance | |
|
||||
| by_reference.cpp:40:12:40:15 | *this [a] | by_reference.cpp:35:9:35:19 | *this [a] | provenance | |
|
||||
| by_reference.cpp:40:12:40:15 | *this [a] | by_reference.cpp:40:18:40:28 | call to getDirectly | provenance | |
|
||||
| by_reference.cpp:40:18:40:28 | call to getDirectly | by_reference.cpp:39:9:39:21 | *getIndirectly | provenance | |
|
||||
| by_reference.cpp:40:18:40:28 | call to getDirectly | by_reference.cpp:40:18:40:28 | call to getDirectly | provenance | |
|
||||
| by_reference.cpp:43:9:43:27 | *this [a] | by_reference.cpp:44:26:44:29 | *this [a] | provenance | |
|
||||
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | by_reference.cpp:43:9:43:27 | *getThroughNonMember | provenance | |
|
||||
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | provenance | |
|
||||
| by_reference.cpp:44:26:44:29 | *this [a] | by_reference.cpp:31:46:31:46 | *s [a] | provenance | |
|
||||
| by_reference.cpp:44:26:44:29 | *this [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | provenance | |
|
||||
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | by_reference.cpp:51:8:51:8 | *s [a] | provenance | |
|
||||
@@ -398,10 +448,12 @@ edges
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | ... = ... | provenance | |
|
||||
| by_reference.cpp:91:25:91:26 | *pa | by_reference.cpp:104:15:104:22 | taint_a_ptr output argument | provenance | |
|
||||
| by_reference.cpp:91:25:91:26 | *pa | by_reference.cpp:108:15:108:24 | taint_a_ptr output argument | provenance | |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:91:25:91:26 | *pa | provenance | |
|
||||
| by_reference.cpp:92:3:92:20 | ... = ... | by_reference.cpp:91:25:91:26 | *pa | provenance | |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:92:3:92:20 | ... = ... | provenance | |
|
||||
| by_reference.cpp:95:25:95:26 | *pa | by_reference.cpp:124:15:124:21 | taint_a_ref output argument | provenance | |
|
||||
| by_reference.cpp:95:25:95:26 | *pa | by_reference.cpp:128:15:128:23 | taint_a_ref output argument | provenance | |
|
||||
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:95:25:95:26 | *pa | provenance | |
|
||||
| by_reference.cpp:96:3:96:19 | ... = ... | by_reference.cpp:95:25:95:26 | *pa | provenance | |
|
||||
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:96:3:96:19 | ... = ... | provenance | |
|
||||
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | by_reference.cpp:102:22:102:26 | *outer [post update] [inner_nested, a] | provenance | |
|
||||
| by_reference.cpp:102:22:102:26 | *outer [post update] [inner_nested, a] | by_reference.cpp:110:8:110:12 | *outer [inner_nested, a] | provenance | |
|
||||
| by_reference.cpp:103:21:103:25 | *outer [post update] [*inner_ptr, a] | by_reference.cpp:111:8:111:12 | *outer [*inner_ptr, a] | provenance | |
|
||||
@@ -541,9 +593,11 @@ edges
|
||||
| complex.cpp:9:7:9:7 | *this [a_] | complex.cpp:9:20:9:21 | *this [a_] | provenance | |
|
||||
| complex.cpp:9:20:9:21 | *this [a_] | complex.cpp:9:20:9:21 | a_ | provenance | |
|
||||
| complex.cpp:9:20:9:21 | a_ | complex.cpp:9:7:9:7 | *a | provenance | |
|
||||
| complex.cpp:9:20:9:21 | a_ | complex.cpp:9:20:9:21 | a_ | provenance | |
|
||||
| complex.cpp:10:7:10:7 | *this [b_] | complex.cpp:10:20:10:21 | *this [b_] | provenance | |
|
||||
| complex.cpp:10:20:10:21 | *this [b_] | complex.cpp:10:20:10:21 | b_ | provenance | |
|
||||
| complex.cpp:10:20:10:21 | b_ | complex.cpp:10:7:10:7 | *b | provenance | |
|
||||
| complex.cpp:10:20:10:21 | b_ | complex.cpp:10:20:10:21 | b_ | provenance | |
|
||||
| complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | ... = ... | provenance | |
|
||||
| complex.cpp:11:22:11:27 | ... = ... | complex.cpp:11:22:11:23 | *this [post update] [a_] | provenance | |
|
||||
| complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | ... = ... | provenance | |
|
||||
@@ -610,9 +664,11 @@ edges
|
||||
| constructors.cpp:18:9:18:9 | *this [a_] | constructors.cpp:18:22:18:23 | *this [a_] | provenance | |
|
||||
| constructors.cpp:18:22:18:23 | *this [a_] | constructors.cpp:18:22:18:23 | a_ | provenance | |
|
||||
| constructors.cpp:18:22:18:23 | a_ | constructors.cpp:18:9:18:9 | *a | provenance | |
|
||||
| constructors.cpp:18:22:18:23 | a_ | constructors.cpp:18:22:18:23 | a_ | provenance | |
|
||||
| constructors.cpp:19:9:19:9 | *this [b_] | constructors.cpp:19:22:19:23 | *this [b_] | provenance | |
|
||||
| constructors.cpp:19:22:19:23 | *this [b_] | constructors.cpp:19:22:19:23 | b_ | provenance | |
|
||||
| constructors.cpp:19:22:19:23 | b_ | constructors.cpp:19:9:19:9 | *b | provenance | |
|
||||
| constructors.cpp:19:22:19:23 | b_ | constructors.cpp:19:22:19:23 | b_ | provenance | |
|
||||
| constructors.cpp:23:13:23:13 | a | constructors.cpp:23:28:23:28 | a | provenance | |
|
||||
| constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | b | provenance | |
|
||||
| constructors.cpp:23:28:23:28 | a | constructors.cpp:23:5:23:7 | *this [post update] [a_] | provenance | |
|
||||
@@ -696,9 +752,11 @@ edges
|
||||
| simple.cpp:18:9:18:9 | *this [a_] | simple.cpp:18:22:18:23 | *this [a_] | provenance | |
|
||||
| simple.cpp:18:22:18:23 | *this [a_] | simple.cpp:18:22:18:23 | a_ | provenance | |
|
||||
| simple.cpp:18:22:18:23 | a_ | simple.cpp:18:9:18:9 | *a | provenance | |
|
||||
| simple.cpp:18:22:18:23 | a_ | simple.cpp:18:22:18:23 | a_ | provenance | |
|
||||
| simple.cpp:19:9:19:9 | *this [b_] | simple.cpp:19:22:19:23 | *this [b_] | provenance | |
|
||||
| simple.cpp:19:22:19:23 | *this [b_] | simple.cpp:19:22:19:23 | b_ | provenance | |
|
||||
| simple.cpp:19:22:19:23 | b_ | simple.cpp:19:9:19:9 | *b | provenance | |
|
||||
| simple.cpp:19:22:19:23 | b_ | simple.cpp:19:22:19:23 | b_ | provenance | |
|
||||
| simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | ... = ... | provenance | |
|
||||
| simple.cpp:20:24:20:29 | ... = ... | simple.cpp:20:24:20:25 | *this [post update] [a_] | provenance | |
|
||||
| simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | ... = ... | provenance | |
|
||||
@@ -725,25 +783,29 @@ edges
|
||||
| simple.cpp:48:9:48:9 | *g [b_] | simple.cpp:26:15:26:15 | *f [b_] | provenance | |
|
||||
| simple.cpp:51:9:51:9 | *h [a_] | simple.cpp:26:15:26:15 | *f [a_] | provenance | |
|
||||
| simple.cpp:51:9:51:9 | *h [b_] | simple.cpp:26:15:26:15 | *f [b_] | provenance | |
|
||||
| simple.cpp:65:5:65:5 | *a [post update] [i] | simple.cpp:67:10:67:11 | *a2 [i] | provenance | |
|
||||
| simple.cpp:65:5:65:5 | *a [post update] [i] | simple.cpp:66:12:66:12 | a [i] | provenance | |
|
||||
| simple.cpp:65:5:65:22 | ... = ... | simple.cpp:65:5:65:5 | *a [post update] [i] | provenance | |
|
||||
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | ... = ... | provenance | |
|
||||
| simple.cpp:66:12:66:12 | a [i] | simple.cpp:67:10:67:11 | *a2 [i] | provenance | |
|
||||
| simple.cpp:67:10:67:11 | *a2 [i] | simple.cpp:67:13:67:13 | i | provenance | |
|
||||
| simple.cpp:78:9:78:15 | *this [f2, f1] | simple.cpp:79:16:79:17 | *this [f2, f1] | provenance | |
|
||||
| simple.cpp:79:16:79:17 | *f2 [f1] | simple.cpp:79:19:79:20 | f1 | provenance | |
|
||||
| simple.cpp:79:16:79:17 | *this [f2, f1] | simple.cpp:79:16:79:17 | *f2 [f1] | provenance | |
|
||||
| simple.cpp:79:19:79:20 | f1 | simple.cpp:78:9:78:15 | *getf2f1 | provenance | |
|
||||
| simple.cpp:79:19:79:20 | f1 | simple.cpp:79:19:79:20 | f1 | provenance | |
|
||||
| simple.cpp:83:9:83:10 | *f2 [post update] [f1] | simple.cpp:83:9:83:10 | *this [post update] [f2, f1] | provenance | |
|
||||
| simple.cpp:83:9:83:10 | *this [post update] [f2, f1] | simple.cpp:84:14:84:20 | *this [f2, f1] | provenance | |
|
||||
| simple.cpp:83:9:83:28 | ... = ... | simple.cpp:83:9:83:10 | *f2 [post update] [f1] | provenance | |
|
||||
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | ... = ... | provenance | |
|
||||
| simple.cpp:84:14:84:20 | *this [f2, f1] | simple.cpp:78:9:78:15 | *this [f2, f1] | provenance | |
|
||||
| simple.cpp:84:14:84:20 | *this [f2, f1] | simple.cpp:84:14:84:20 | call to getf2f1 | provenance | |
|
||||
| simple.cpp:92:5:92:5 | *a [post update] [i] | simple.cpp:94:10:94:11 | *a2 [i] | provenance | |
|
||||
| simple.cpp:92:5:92:5 | *a [post update] [i] | simple.cpp:93:20:93:20 | a [i] | provenance | |
|
||||
| simple.cpp:92:5:92:22 | ... = ... | simple.cpp:92:5:92:5 | *a [post update] [i] | provenance | |
|
||||
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | ... = ... | provenance | |
|
||||
| simple.cpp:93:20:93:20 | a [i] | simple.cpp:94:10:94:11 | *a2 [i] | provenance | |
|
||||
| simple.cpp:94:10:94:11 | *a2 [i] | simple.cpp:94:13:94:13 | i | provenance | |
|
||||
| simple.cpp:103:24:103:24 | x | simple.cpp:104:14:104:14 | x | provenance | |
|
||||
| simple.cpp:108:17:108:26 | call to user_input | simple.cpp:108:17:108:26 | call to user_input | provenance | |
|
||||
| simple.cpp:108:17:108:26 | call to user_input | simple.cpp:109:43:109:43 | x | provenance | |
|
||||
| simple.cpp:109:43:109:43 | x | simple.cpp:103:24:103:24 | x | provenance | |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | *ab [a] | provenance | |
|
||||
@@ -792,14 +854,18 @@ nodes
|
||||
| A.cpp:28:8:28:10 | *this [c] | semmle.label | *this [c] |
|
||||
| A.cpp:28:23:28:26 | *this [c] | semmle.label | *this [c] |
|
||||
| A.cpp:28:29:28:29 | c | semmle.label | c |
|
||||
| A.cpp:28:29:28:29 | c | semmle.label | c |
|
||||
| A.cpp:29:15:29:18 | **make [c] | semmle.label | **make [c] |
|
||||
| A.cpp:29:23:29:23 | c | semmle.label | c |
|
||||
| A.cpp:31:14:31:21 | *new [c] | semmle.label | *new [c] |
|
||||
| A.cpp:31:14:31:21 | call to B [c] | semmle.label | call to B [c] |
|
||||
| A.cpp:31:20:31:20 | c | semmle.label | c |
|
||||
| A.cpp:41:5:41:6 | insert output argument | semmle.label | insert output argument |
|
||||
| A.cpp:41:15:41:21 | new | semmle.label | new |
|
||||
| A.cpp:43:10:43:12 | *& ... | semmle.label | *& ... |
|
||||
| A.cpp:47:12:47:18 | new | semmle.label | new |
|
||||
| A.cpp:47:12:47:18 | new | semmle.label | new |
|
||||
| A.cpp:48:12:48:18 | *call to make [c] | semmle.label | *call to make [c] |
|
||||
| A.cpp:48:12:48:18 | *call to make [c] | semmle.label | *call to make [c] |
|
||||
| A.cpp:48:20:48:20 | c | semmle.label | c |
|
||||
| A.cpp:49:10:49:10 | *b [c] | semmle.label | *b [c] |
|
||||
@@ -813,29 +879,39 @@ nodes
|
||||
| A.cpp:57:11:57:24 | call to B [c] | semmle.label | call to B [c] |
|
||||
| A.cpp:57:17:57:23 | new | semmle.label | new |
|
||||
| A.cpp:57:17:57:23 | new | semmle.label | new |
|
||||
| A.cpp:64:5:64:29 | *... = ... [c] | semmle.label | *... = ... [c] |
|
||||
| A.cpp:64:10:64:15 | *call to setOnB [c] | semmle.label | *call to setOnB [c] |
|
||||
| A.cpp:64:21:64:28 | new | semmle.label | new |
|
||||
| A.cpp:66:10:66:11 | *b2 [c] | semmle.label | *b2 [c] |
|
||||
| A.cpp:66:10:66:14 | c | semmle.label | c |
|
||||
| A.cpp:73:5:73:33 | *... = ... [c] | semmle.label | *... = ... [c] |
|
||||
| A.cpp:73:10:73:19 | *call to setOnBWrap [c] | semmle.label | *call to setOnBWrap [c] |
|
||||
| A.cpp:73:25:73:32 | new | semmle.label | new |
|
||||
| A.cpp:75:10:75:11 | *b2 [c] | semmle.label | *b2 [c] |
|
||||
| A.cpp:75:10:75:14 | c | semmle.label | c |
|
||||
| A.cpp:78:6:78:15 | **setOnBWrap [c] | semmle.label | **setOnBWrap [c] |
|
||||
| A.cpp:78:27:78:27 | c | semmle.label | c |
|
||||
| A.cpp:81:5:81:22 | *... = ... [c] | semmle.label | *... = ... [c] |
|
||||
| A.cpp:81:10:81:15 | *call to setOnB [c] | semmle.label | *call to setOnB [c] |
|
||||
| A.cpp:81:21:81:21 | c | semmle.label | c |
|
||||
| A.cpp:82:12:82:24 | *... ? ... : ... [c] | semmle.label | *... ? ... : ... [c] |
|
||||
| A.cpp:85:9:85:14 | **setOnB [c] | semmle.label | **setOnB [c] |
|
||||
| A.cpp:85:26:85:26 | c | semmle.label | c |
|
||||
| A.cpp:90:7:90:8 | set output argument [c] | semmle.label | set output argument [c] |
|
||||
| A.cpp:90:15:90:15 | c | semmle.label | c |
|
||||
| A.cpp:91:14:91:15 | *b2 [c] | semmle.label | *b2 [c] |
|
||||
| A.cpp:98:12:98:18 | new | semmle.label | new |
|
||||
| A.cpp:98:12:98:18 | new | semmle.label | new |
|
||||
| A.cpp:100:5:100:6 | *c1 [post update] [a] | semmle.label | *c1 [post update] [a] |
|
||||
| A.cpp:100:5:100:13 | ... = ... | semmle.label | ... = ... |
|
||||
| A.cpp:101:8:101:9 | *c1 [a] | semmle.label | *c1 [a] |
|
||||
| A.cpp:103:14:103:14 | *c [a] | semmle.label | *c [a] |
|
||||
| A.cpp:105:18:105:38 | *c [a] | semmle.label | *c [a] |
|
||||
| A.cpp:107:12:107:13 | *c1 [a] | semmle.label | *c1 [a] |
|
||||
| A.cpp:107:12:107:16 | a | semmle.label | a |
|
||||
| A.cpp:110:18:110:38 | *c [a] | semmle.label | *c [a] |
|
||||
| A.cpp:112:7:112:13 | *... = ... [a] | semmle.label | *... = ... [a] |
|
||||
| A.cpp:118:18:118:39 | *cc [a] | semmle.label | *cc [a] |
|
||||
| A.cpp:120:12:120:13 | *c1 [a] | semmle.label | *c1 [a] |
|
||||
| A.cpp:120:12:120:16 | a | semmle.label | a |
|
||||
| A.cpp:124:14:124:14 | *b [c] | semmle.label | *b [c] |
|
||||
@@ -858,6 +934,9 @@ nodes
|
||||
| A.cpp:143:7:143:31 | ... = ... | semmle.label | ... = ... |
|
||||
| A.cpp:143:25:143:31 | new | semmle.label | new |
|
||||
| A.cpp:150:12:150:18 | new | semmle.label | new |
|
||||
| A.cpp:150:12:150:18 | new | semmle.label | new |
|
||||
| A.cpp:151:12:151:24 | *new [*b, c] | semmle.label | *new [*b, c] |
|
||||
| A.cpp:151:12:151:24 | *new [b] | semmle.label | *new [b] |
|
||||
| A.cpp:151:12:151:24 | call to D [*b, c] | semmle.label | call to D [*b, c] |
|
||||
| A.cpp:151:12:151:24 | call to D [b] | semmle.label | call to D [b] |
|
||||
| A.cpp:151:18:151:18 | D output argument [c] | semmle.label | D output argument [c] |
|
||||
@@ -875,16 +954,23 @@ nodes
|
||||
| A.cpp:154:10:154:10 | *b [c] | semmle.label | *b [c] |
|
||||
| A.cpp:154:10:154:13 | c | semmle.label | c |
|
||||
| A.cpp:159:12:159:18 | new | semmle.label | new |
|
||||
| A.cpp:159:12:159:18 | new | semmle.label | new |
|
||||
| A.cpp:160:18:160:60 | *new [head] | semmle.label | *new [head] |
|
||||
| A.cpp:160:18:160:60 | call to MyList [head] | semmle.label | call to MyList [head] |
|
||||
| A.cpp:160:29:160:29 | b | semmle.label | b |
|
||||
| A.cpp:161:18:161:40 | *new [*next, head] | semmle.label | *new [*next, head] |
|
||||
| A.cpp:161:18:161:40 | call to MyList [*next, head] | semmle.label | call to MyList [*next, head] |
|
||||
| A.cpp:161:38:161:39 | *l1 [head] | semmle.label | *l1 [head] |
|
||||
| A.cpp:162:18:162:40 | *new [*next, *next, head] | semmle.label | *new [*next, *next, head] |
|
||||
| A.cpp:162:18:162:40 | call to MyList [*next, *next, head] | semmle.label | call to MyList [*next, *next, head] |
|
||||
| A.cpp:162:38:162:39 | *l2 [*next, head] | semmle.label | *l2 [*next, head] |
|
||||
| A.cpp:165:10:165:11 | *l3 [*next, *next, head] | semmle.label | *l3 [*next, *next, head] |
|
||||
| A.cpp:165:10:165:29 | head | semmle.label | head |
|
||||
| A.cpp:165:14:165:17 | *next [*next, head] | semmle.label | *next [*next, head] |
|
||||
| A.cpp:165:20:165:23 | *next [head] | semmle.label | *next [head] |
|
||||
| A.cpp:167:22:167:23 | *l3 [*next, *next, head] | semmle.label | *l3 [*next, *next, head] |
|
||||
| A.cpp:167:40:167:50 | *... = ... [*next, head] | semmle.label | *... = ... [*next, head] |
|
||||
| A.cpp:167:40:167:50 | *... = ... [head] | semmle.label | *... = ... [head] |
|
||||
| A.cpp:167:44:167:44 | *l [*next, *next, head] | semmle.label | *l [*next, *next, head] |
|
||||
| A.cpp:167:44:167:44 | *l [*next, head] | semmle.label | *l [*next, head] |
|
||||
| A.cpp:167:47:167:50 | *next [*next, head] | semmle.label | *next [*next, head] |
|
||||
@@ -903,16 +989,22 @@ nodes
|
||||
| A.cpp:184:7:184:23 | *... = ... [*next, head] | semmle.label | *... = ... [*next, head] |
|
||||
| A.cpp:184:7:184:23 | *... = ... [head] | semmle.label | *... = ... [head] |
|
||||
| B.cpp:6:15:6:24 | new | semmle.label | new |
|
||||
| B.cpp:6:15:6:24 | new | semmle.label | new |
|
||||
| B.cpp:7:16:7:35 | *new [elem1] | semmle.label | *new [elem1] |
|
||||
| B.cpp:7:16:7:35 | call to Box1 [elem1] | semmle.label | call to Box1 [elem1] |
|
||||
| B.cpp:7:25:7:25 | e | semmle.label | e |
|
||||
| B.cpp:8:16:8:27 | *new [*box1, elem1] | semmle.label | *new [*box1, elem1] |
|
||||
| B.cpp:8:16:8:27 | call to Box2 [*box1, elem1] | semmle.label | call to Box2 [*box1, elem1] |
|
||||
| B.cpp:8:25:8:26 | *b1 [elem1] | semmle.label | *b1 [elem1] |
|
||||
| B.cpp:9:10:9:11 | *b2 [*box1, elem1] | semmle.label | *b2 [*box1, elem1] |
|
||||
| B.cpp:9:10:9:24 | elem1 | semmle.label | elem1 |
|
||||
| B.cpp:9:14:9:17 | *box1 [elem1] | semmle.label | *box1 [elem1] |
|
||||
| B.cpp:15:15:15:27 | new | semmle.label | new |
|
||||
| B.cpp:15:15:15:27 | new | semmle.label | new |
|
||||
| B.cpp:16:16:16:38 | *new [elem2] | semmle.label | *new [elem2] |
|
||||
| B.cpp:16:16:16:38 | call to Box1 [elem2] | semmle.label | call to Box1 [elem2] |
|
||||
| B.cpp:16:37:16:37 | e | semmle.label | e |
|
||||
| B.cpp:17:16:17:27 | *new [*box1, elem2] | semmle.label | *new [*box1, elem2] |
|
||||
| B.cpp:17:16:17:27 | call to Box2 [*box1, elem2] | semmle.label | call to Box2 [*box1, elem2] |
|
||||
| B.cpp:17:25:17:26 | *b1 [elem2] | semmle.label | *b1 [elem2] |
|
||||
| B.cpp:19:10:19:11 | *b2 [*box1, elem2] | semmle.label | *b2 [*box1, elem2] |
|
||||
@@ -930,6 +1022,8 @@ nodes
|
||||
| B.cpp:46:7:46:10 | *this [post update] [*box1, elem2] | semmle.label | *this [post update] [*box1, elem2] |
|
||||
| B.cpp:46:7:46:21 | *... = ... [elem1] | semmle.label | *... = ... [elem1] |
|
||||
| B.cpp:46:7:46:21 | *... = ... [elem2] | semmle.label | *... = ... [elem2] |
|
||||
| C.cpp:18:12:18:18 | *new [s1] | semmle.label | *new [s1] |
|
||||
| C.cpp:18:12:18:18 | *new [s3] | semmle.label | *new [s3] |
|
||||
| C.cpp:18:12:18:18 | call to C [s1] | semmle.label | call to C [s1] |
|
||||
| C.cpp:18:12:18:18 | call to C [s3] | semmle.label | call to C [s3] |
|
||||
| C.cpp:19:5:19:5 | *c [s1] | semmle.label | *c [s1] |
|
||||
@@ -950,38 +1044,45 @@ nodes
|
||||
| D.cpp:10:11:10:17 | *this [elem] | semmle.label | *this [elem] |
|
||||
| D.cpp:10:30:10:33 | *this [elem] | semmle.label | *this [elem] |
|
||||
| D.cpp:10:30:10:33 | elem | semmle.label | elem |
|
||||
| D.cpp:10:30:10:33 | elem | semmle.label | elem |
|
||||
| D.cpp:11:24:11:24 | e | semmle.label | e |
|
||||
| D.cpp:11:29:11:32 | *this [post update] [elem] | semmle.label | *this [post update] [elem] |
|
||||
| D.cpp:11:29:11:36 | ... = ... | semmle.label | ... = ... |
|
||||
| D.cpp:17:11:17:17 | **getBox1 [elem] | semmle.label | **getBox1 [elem] |
|
||||
| D.cpp:17:11:17:17 | *this [*box, elem] | semmle.label | *this [*box, elem] |
|
||||
| D.cpp:17:30:17:32 | *box [elem] | semmle.label | *box [elem] |
|
||||
| D.cpp:17:30:17:32 | *box [elem] | semmle.label | *box [elem] |
|
||||
| D.cpp:17:30:17:32 | *this [*box, elem] | semmle.label | *this [*box, elem] |
|
||||
| D.cpp:21:30:21:31 | *b2 [*box, elem] | semmle.label | *b2 [*box, elem] |
|
||||
| D.cpp:22:10:22:11 | *b2 [*box, elem] | semmle.label | *b2 [*box, elem] |
|
||||
| D.cpp:22:10:22:33 | call to getElem | semmle.label | call to getElem |
|
||||
| D.cpp:22:14:22:20 | *call to getBox1 [elem] | semmle.label | *call to getBox1 [elem] |
|
||||
| D.cpp:28:15:28:24 | new | semmle.label | new |
|
||||
| D.cpp:28:15:28:24 | new | semmle.label | new |
|
||||
| D.cpp:30:5:30:5 | *b [post update] [*box, elem] | semmle.label | *b [post update] [*box, elem] |
|
||||
| D.cpp:30:5:30:20 | ... = ... | semmle.label | ... = ... |
|
||||
| D.cpp:30:8:30:10 | *box [post update] [elem] | semmle.label | *box [post update] [elem] |
|
||||
| D.cpp:31:14:31:14 | *b [*box, elem] | semmle.label | *b [*box, elem] |
|
||||
| D.cpp:35:15:35:24 | new | semmle.label | new |
|
||||
| D.cpp:35:15:35:24 | new | semmle.label | new |
|
||||
| D.cpp:37:5:37:5 | *b [post update] [*box, elem] | semmle.label | *b [post update] [*box, elem] |
|
||||
| D.cpp:37:8:37:10 | setElem output argument [elem] | semmle.label | setElem output argument [elem] |
|
||||
| D.cpp:37:21:37:21 | e | semmle.label | e |
|
||||
| D.cpp:38:14:38:14 | *b [*box, elem] | semmle.label | *b [*box, elem] |
|
||||
| D.cpp:42:15:42:24 | new | semmle.label | new |
|
||||
| D.cpp:42:15:42:24 | new | semmle.label | new |
|
||||
| D.cpp:44:5:44:5 | getBox1 output argument [*box, elem] | semmle.label | getBox1 output argument [*box, elem] |
|
||||
| D.cpp:44:5:44:26 | ... = ... | semmle.label | ... = ... |
|
||||
| D.cpp:44:8:44:14 | *call to getBox1 [post update] [elem] | semmle.label | *call to getBox1 [post update] [elem] |
|
||||
| D.cpp:45:14:45:14 | *b [*box, elem] | semmle.label | *b [*box, elem] |
|
||||
| D.cpp:49:15:49:24 | new | semmle.label | new |
|
||||
| D.cpp:49:15:49:24 | new | semmle.label | new |
|
||||
| D.cpp:51:5:51:5 | getBox1 output argument [*box, elem] | semmle.label | getBox1 output argument [*box, elem] |
|
||||
| D.cpp:51:8:51:14 | setElem output argument [elem] | semmle.label | setElem output argument [elem] |
|
||||
| D.cpp:51:27:51:27 | e | semmle.label | e |
|
||||
| D.cpp:52:14:52:14 | *b [*box, elem] | semmle.label | *b [*box, elem] |
|
||||
| D.cpp:56:15:56:24 | new | semmle.label | new |
|
||||
| D.cpp:56:15:56:24 | new | semmle.label | new |
|
||||
| D.cpp:58:5:58:12 | *boxfield [post update] [*box, elem] | semmle.label | *boxfield [post update] [*box, elem] |
|
||||
| D.cpp:58:5:58:12 | *this [post update] [*boxfield, *box, elem] | semmle.label | *this [post update] [*boxfield, *box, elem] |
|
||||
| D.cpp:58:5:58:27 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -1023,6 +1124,7 @@ nodes
|
||||
| aliasing.cpp:60:3:60:4 | *s2 [post update] [m1] | semmle.label | *s2 [post update] [m1] |
|
||||
| aliasing.cpp:60:3:60:22 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:61:13:61:14 | s2 [m1] | semmle.label | s2 [m1] |
|
||||
| aliasing.cpp:62:8:62:12 | *copy2 [m1] | semmle.label | *copy2 [m1] |
|
||||
| aliasing.cpp:62:14:62:15 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:92:3:92:3 | *w [post update] [s, m1] | semmle.label | *w [post update] [s, m1] |
|
||||
@@ -1035,10 +1137,13 @@ nodes
|
||||
| aliasing.cpp:98:3:98:3 | *s [post update] [m1] | semmle.label | *s [post update] [m1] |
|
||||
| aliasing.cpp:98:3:98:21 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:98:10:98:19 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:100:14:100:14 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:101:13:101:22 | *& ... | semmle.label | *& ... |
|
||||
| aliasing.cpp:101:13:101:22 | *& ... | semmle.label | *& ... |
|
||||
| aliasing.cpp:101:14:101:19 | *s_copy [m1] | semmle.label | *s_copy [m1] |
|
||||
| aliasing.cpp:102:8:102:10 | * ... | semmle.label | * ... |
|
||||
| aliasing.cpp:105:23:105:24 | *pa | semmle.label | *pa |
|
||||
| aliasing.cpp:106:3:106:20 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:121:15:121:16 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| aliasing.cpp:122:8:122:12 | access to array | semmle.label | access to array |
|
||||
@@ -1070,6 +1175,7 @@ nodes
|
||||
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument |
|
||||
| aliasing.cpp:187:16:187:17 | *s2 [post update] [s, m1] | semmle.label | *s2 [post update] [s, m1] |
|
||||
| aliasing.cpp:187:19:187:19 | *s [post update] [m1] | semmle.label | *s [post update] [m1] |
|
||||
| aliasing.cpp:188:13:188:14 | s2 [s, m1] | semmle.label | s2 [s, m1] |
|
||||
| aliasing.cpp:189:8:189:11 | *s2_2 [s, m1] | semmle.label | *s2_2 [s, m1] |
|
||||
| aliasing.cpp:189:13:189:13 | *s [m1] | semmle.label | *s [m1] |
|
||||
| aliasing.cpp:189:15:189:16 | m1 | semmle.label | m1 |
|
||||
@@ -1079,11 +1185,13 @@ nodes
|
||||
| aliasing.cpp:201:8:201:10 | *ps2 [s, m1] | semmle.label | *ps2 [s, m1] |
|
||||
| aliasing.cpp:201:13:201:13 | *s [m1] | semmle.label | *s [m1] |
|
||||
| aliasing.cpp:201:15:201:16 | m1 | semmle.label | m1 |
|
||||
| arrays.cpp:6:3:6:23 | ... = ... | semmle.label | ... = ... |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:7:8:7:13 | access to array | semmle.label | access to array |
|
||||
| arrays.cpp:8:8:8:13 | access to array | semmle.label | access to array |
|
||||
| arrays.cpp:9:8:9:11 | * ... | semmle.label | * ... |
|
||||
| arrays.cpp:10:8:10:15 | * ... | semmle.label | * ... |
|
||||
| arrays.cpp:15:3:15:25 | ... = ... | semmle.label | ... = ... |
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:16:8:16:13 | access to array | semmle.label | access to array |
|
||||
| arrays.cpp:17:8:17:13 | access to array | semmle.label | access to array |
|
||||
@@ -1145,17 +1253,21 @@ nodes
|
||||
| by_reference.cpp:31:46:31:46 | *s [a] | semmle.label | *s [a] |
|
||||
| by_reference.cpp:32:12:32:12 | *s [a] | semmle.label | *s [a] |
|
||||
| by_reference.cpp:32:15:32:15 | a | semmle.label | a |
|
||||
| by_reference.cpp:32:15:32:15 | a | semmle.label | a |
|
||||
| by_reference.cpp:35:9:35:19 | *getDirectly | semmle.label | *getDirectly |
|
||||
| by_reference.cpp:35:9:35:19 | *this [a] | semmle.label | *this [a] |
|
||||
| by_reference.cpp:36:12:36:15 | *this [a] | semmle.label | *this [a] |
|
||||
| by_reference.cpp:36:18:36:18 | a | semmle.label | a |
|
||||
| by_reference.cpp:36:18:36:18 | a | semmle.label | a |
|
||||
| by_reference.cpp:39:9:39:21 | *getIndirectly | semmle.label | *getIndirectly |
|
||||
| by_reference.cpp:39:9:39:21 | *this [a] | semmle.label | *this [a] |
|
||||
| by_reference.cpp:40:12:40:15 | *this [a] | semmle.label | *this [a] |
|
||||
| by_reference.cpp:40:18:40:28 | call to getDirectly | semmle.label | call to getDirectly |
|
||||
| by_reference.cpp:40:18:40:28 | call to getDirectly | semmle.label | call to getDirectly |
|
||||
| by_reference.cpp:43:9:43:27 | *getThroughNonMember | semmle.label | *getThroughNonMember |
|
||||
| by_reference.cpp:43:9:43:27 | *this [a] | semmle.label | *this [a] |
|
||||
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
|
||||
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
|
||||
| by_reference.cpp:44:26:44:29 | *this [a] | semmle.label | *this [a] |
|
||||
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | semmle.label | setDirectly output argument [a] |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input |
|
||||
@@ -1182,8 +1294,10 @@ nodes
|
||||
| by_reference.cpp:88:3:88:24 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:91:25:91:26 | *pa | semmle.label | *pa |
|
||||
| by_reference.cpp:92:3:92:20 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:95:25:95:26 | *pa | semmle.label | *pa |
|
||||
| by_reference.cpp:96:3:96:19 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:96:8:96:17 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:102:22:102:26 | *outer [post update] [inner_nested, a] | semmle.label | *outer [post update] [inner_nested, a] |
|
||||
@@ -1334,10 +1448,12 @@ nodes
|
||||
| complex.cpp:9:7:9:7 | *this [a_] | semmle.label | *this [a_] |
|
||||
| complex.cpp:9:20:9:21 | *this [a_] | semmle.label | *this [a_] |
|
||||
| complex.cpp:9:20:9:21 | a_ | semmle.label | a_ |
|
||||
| complex.cpp:9:20:9:21 | a_ | semmle.label | a_ |
|
||||
| complex.cpp:10:7:10:7 | *b | semmle.label | *b |
|
||||
| complex.cpp:10:7:10:7 | *this [b_] | semmle.label | *this [b_] |
|
||||
| complex.cpp:10:20:10:21 | *this [b_] | semmle.label | *this [b_] |
|
||||
| complex.cpp:10:20:10:21 | b_ | semmle.label | b_ |
|
||||
| complex.cpp:10:20:10:21 | b_ | semmle.label | b_ |
|
||||
| complex.cpp:11:17:11:17 | a | semmle.label | a |
|
||||
| complex.cpp:11:22:11:23 | *this [post update] [a_] | semmle.label | *this [post update] [a_] |
|
||||
| complex.cpp:11:22:11:27 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -1409,10 +1525,12 @@ nodes
|
||||
| constructors.cpp:18:9:18:9 | *this [a_] | semmle.label | *this [a_] |
|
||||
| constructors.cpp:18:22:18:23 | *this [a_] | semmle.label | *this [a_] |
|
||||
| constructors.cpp:18:22:18:23 | a_ | semmle.label | a_ |
|
||||
| constructors.cpp:18:22:18:23 | a_ | semmle.label | a_ |
|
||||
| constructors.cpp:19:9:19:9 | *b | semmle.label | *b |
|
||||
| constructors.cpp:19:9:19:9 | *this [b_] | semmle.label | *this [b_] |
|
||||
| constructors.cpp:19:22:19:23 | *this [b_] | semmle.label | *this [b_] |
|
||||
| constructors.cpp:19:22:19:23 | b_ | semmle.label | b_ |
|
||||
| constructors.cpp:19:22:19:23 | b_ | semmle.label | b_ |
|
||||
| constructors.cpp:23:5:23:7 | *this [post update] [a_] | semmle.label | *this [post update] [a_] |
|
||||
| constructors.cpp:23:5:23:7 | *this [post update] [b_] | semmle.label | *this [post update] [b_] |
|
||||
| constructors.cpp:23:13:23:13 | a | semmle.label | a |
|
||||
@@ -1502,10 +1620,12 @@ nodes
|
||||
| simple.cpp:18:9:18:9 | *this [a_] | semmle.label | *this [a_] |
|
||||
| simple.cpp:18:22:18:23 | *this [a_] | semmle.label | *this [a_] |
|
||||
| simple.cpp:18:22:18:23 | a_ | semmle.label | a_ |
|
||||
| simple.cpp:18:22:18:23 | a_ | semmle.label | a_ |
|
||||
| simple.cpp:19:9:19:9 | *b | semmle.label | *b |
|
||||
| simple.cpp:19:9:19:9 | *this [b_] | semmle.label | *this [b_] |
|
||||
| simple.cpp:19:22:19:23 | *this [b_] | semmle.label | *this [b_] |
|
||||
| simple.cpp:19:22:19:23 | b_ | semmle.label | b_ |
|
||||
| simple.cpp:19:22:19:23 | b_ | semmle.label | b_ |
|
||||
| simple.cpp:20:19:20:19 | a | semmle.label | a |
|
||||
| simple.cpp:20:24:20:25 | *this [post update] [a_] | semmle.label | *this [post update] [a_] |
|
||||
| simple.cpp:20:24:20:29 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -1533,6 +1653,7 @@ nodes
|
||||
| simple.cpp:65:5:65:5 | *a [post update] [i] | semmle.label | *a [post update] [i] |
|
||||
| simple.cpp:65:5:65:22 | ... = ... | semmle.label | ... = ... |
|
||||
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:66:12:66:12 | a [i] | semmle.label | a [i] |
|
||||
| simple.cpp:67:10:67:11 | *a2 [i] | semmle.label | *a2 [i] |
|
||||
| simple.cpp:67:13:67:13 | i | semmle.label | i |
|
||||
| simple.cpp:78:9:78:15 | *getf2f1 | semmle.label | *getf2f1 |
|
||||
@@ -1540,6 +1661,7 @@ nodes
|
||||
| simple.cpp:79:16:79:17 | *f2 [f1] | semmle.label | *f2 [f1] |
|
||||
| simple.cpp:79:16:79:17 | *this [f2, f1] | semmle.label | *this [f2, f1] |
|
||||
| simple.cpp:79:19:79:20 | f1 | semmle.label | f1 |
|
||||
| simple.cpp:79:19:79:20 | f1 | semmle.label | f1 |
|
||||
| simple.cpp:83:9:83:10 | *f2 [post update] [f1] | semmle.label | *f2 [post update] [f1] |
|
||||
| simple.cpp:83:9:83:10 | *this [post update] [f2, f1] | semmle.label | *this [post update] [f2, f1] |
|
||||
| simple.cpp:83:9:83:28 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -1549,11 +1671,13 @@ nodes
|
||||
| simple.cpp:92:5:92:5 | *a [post update] [i] | semmle.label | *a [post update] [i] |
|
||||
| simple.cpp:92:5:92:22 | ... = ... | semmle.label | ... = ... |
|
||||
| simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:93:20:93:20 | a [i] | semmle.label | a [i] |
|
||||
| simple.cpp:94:10:94:11 | *a2 [i] | semmle.label | *a2 [i] |
|
||||
| simple.cpp:94:13:94:13 | i | semmle.label | i |
|
||||
| simple.cpp:103:24:103:24 | x | semmle.label | x |
|
||||
| simple.cpp:104:14:104:14 | x | semmle.label | x |
|
||||
| simple.cpp:108:17:108:26 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:108:17:108:26 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:109:43:109:43 | x | semmle.label | x |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
| tests.cpp:144:5:144:19 | [summary param] 0 in madArg0ToReturn | ParameterNode | madArg0ToReturn | madArg0ToReturn |
|
||||
| tests.cpp:144:5:144:19 | [summary] to write: ReturnValue in madArg0ToReturn | ReturnNode | madArg0ToReturn | madArg0ToReturn |
|
||||
| tests.cpp:145:6:145:28 | [summary param] 0 in madArg0ToReturnIndirect | ParameterNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
|
||||
| tests.cpp:145:6:145:28 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirect | ReturnNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
|
||||
| tests.cpp:147:5:147:28 | [summary param] 0 in madArg0ToReturnValueFlow | ParameterNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
|
||||
| tests.cpp:147:5:147:28 | [summary] to write: ReturnValue in madArg0ToReturnValueFlow | ReturnNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
|
||||
| tests.cpp:148:5:148:27 | [summary param] 0 indirection in madArg0IndirectToReturn | ParameterNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
|
||||
| tests.cpp:148:5:148:27 | [summary] to write: ReturnValue in madArg0IndirectToReturn | ReturnNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
|
||||
| tests.cpp:149:5:149:33 | [summary param] 0 indirection in madArg0DoubleIndirectToReturn | ParameterNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
|
||||
| tests.cpp:149:5:149:33 | [summary] to write: ReturnValue in madArg0DoubleIndirectToReturn | ReturnNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
|
||||
| tests.cpp:150:5:150:30 | [summary param] 0 in madArg0NotIndirectToReturn | ParameterNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
|
||||
| tests.cpp:150:5:150:30 | [summary] to write: ReturnValue in madArg0NotIndirectToReturn | ReturnNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
|
||||
| tests.cpp:151:6:151:26 | [summary param] 0 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
||||
| tests.cpp:151:6:151:26 | [summary param] 1 indirection in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
||||
| tests.cpp:151:6:151:26 | [summary] to write: Argument[1 indirection] in madArg0ToArg1Indirect | PostUpdateNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
|
||||
| tests.cpp:152:6:152:34 | [summary param] 0 indirection in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
||||
| tests.cpp:152:6:152:34 | [summary param] 1 indirection in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
||||
| tests.cpp:152:6:152:34 | [summary] to write: Argument[1 indirection] in madArg0IndirectToArg1Indirect | PostUpdateNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
|
||||
| tests.cpp:153:5:153:18 | [summary param] 0 indirection in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
||||
| tests.cpp:153:5:153:18 | [summary param] 1 indirection in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
||||
| tests.cpp:153:5:153:18 | [summary param] 2 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
|
||||
| tests.cpp:153:5:153:18 | [summary] to write: ReturnValue in madArgsComplex | ReturnNode | madArgsComplex | madArgsComplex |
|
||||
| tests.cpp:155:5:155:28 | [summary param] 2 in madAndImplementedComplex | ParameterNode | madAndImplementedComplex | madAndImplementedComplex |
|
||||
| tests.cpp:155:5:155:28 | [summary] to write: ReturnValue in madAndImplementedComplex | ReturnNode | madAndImplementedComplex | madAndImplementedComplex |
|
||||
| tests.cpp:160:5:160:24 | [summary param] 0 in madArg0FieldToReturn | ParameterNode | madArg0FieldToReturn | madArg0FieldToReturn |
|
||||
| tests.cpp:160:5:160:24 | [summary] read: Argument[0].Field[value] in madArg0FieldToReturn | | madArg0FieldToReturn | madArg0FieldToReturn |
|
||||
| tests.cpp:160:5:160:24 | [summary] to write: ReturnValue in madArg0FieldToReturn | ReturnNode | madArg0FieldToReturn | madArg0FieldToReturn |
|
||||
| tests.cpp:161:5:161:32 | [summary param] 0 indirection in madArg0IndirectFieldToReturn | ParameterNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
||||
| tests.cpp:161:5:161:32 | [summary] read: Argument[0 indirection].Field[value] in madArg0IndirectFieldToReturn | | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
||||
| tests.cpp:161:5:161:32 | [summary] to write: ReturnValue in madArg0IndirectFieldToReturn | ReturnNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
|
||||
| tests.cpp:162:5:162:32 | [summary param] 0 in madArg0FieldIndirectToReturn | ParameterNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
||||
| tests.cpp:162:5:162:32 | [summary] read: Argument[0].Field[*ptr] in madArg0FieldIndirectToReturn | | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
||||
| tests.cpp:162:5:162:32 | [summary] to write: ReturnValue in madArg0FieldIndirectToReturn | ReturnNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
|
||||
| tests.cpp:163:13:163:32 | [summary param] 0 in madArg0ToReturnField | ParameterNode | madArg0ToReturnField | madArg0ToReturnField |
|
||||
| tests.cpp:163:13:163:32 | [summary] to write: ReturnValue in madArg0ToReturnField | ReturnNode | madArg0ToReturnField | madArg0ToReturnField |
|
||||
| tests.cpp:163:13:163:32 | [summary] to write: ReturnValue.Field[value] in madArg0ToReturnField | | madArg0ToReturnField | madArg0ToReturnField |
|
||||
| tests.cpp:164:14:164:41 | [summary param] 0 in madArg0ToReturnIndirectField | ParameterNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
||||
| tests.cpp:164:14:164:41 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirectField | ReturnNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
||||
| tests.cpp:164:14:164:41 | [summary] to write: ReturnValue[*].Field[value] in madArg0ToReturnIndirectField | | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
|
||||
| tests.cpp:165:13:165:40 | [summary param] 0 in madArg0ToReturnFieldIndirect | ParameterNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
||||
| tests.cpp:165:13:165:40 | [summary] to write: ReturnValue in madArg0ToReturnFieldIndirect | ReturnNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
||||
| tests.cpp:165:13:165:40 | [summary] to write: ReturnValue.Field[*ptr] in madArg0ToReturnFieldIndirect | | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
|
||||
| tests.cpp:284:7:284:19 | [summary param] 0 in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
|
||||
| tests.cpp:284:7:284:19 | [summary param] this indirection in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
|
||||
| tests.cpp:284:7:284:19 | [summary] to write: Argument[this indirection] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |
|
||||
| tests.cpp:285:6:285:20 | [summary param] this indirection in madSelfToReturn | ParameterNode | madSelfToReturn | madSelfToReturn |
|
||||
| tests.cpp:285:6:285:20 | [summary] to write: ReturnValue in madSelfToReturn | ReturnNode | madSelfToReturn | madSelfToReturn |
|
||||
| tests.cpp:287:7:287:20 | [summary param] 0 in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
|
||||
| tests.cpp:287:7:287:20 | [summary param] this indirection in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
|
||||
| tests.cpp:287:7:287:20 | [summary] to write: Argument[this indirection] in madArg0ToField | PostUpdateNode | madArg0ToField | madArg0ToField |
|
||||
| tests.cpp:287:7:287:20 | [summary] to write: Argument[this indirection].Field[val] in madArg0ToField | | madArg0ToField | madArg0ToField |
|
||||
| tests.cpp:288:6:288:21 | [summary param] this indirection in madFieldToReturn | ParameterNode | madFieldToReturn | madFieldToReturn |
|
||||
| tests.cpp:288:6:288:21 | [summary] read: Argument[this indirection].Field[val] in madFieldToReturn | | madFieldToReturn | madFieldToReturn |
|
||||
| tests.cpp:288:6:288:21 | [summary] to write: ReturnValue in madFieldToReturn | ReturnNode | madFieldToReturn | madFieldToReturn |
|
||||
| tests.cpp:313:7:313:30 | [summary param] this indirection in namespaceMadSelfToReturn | ParameterNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
|
||||
| tests.cpp:313:7:313:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | ReturnNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
|
||||
| tests.cpp:434:5:434:29 | [summary param] 0 in madCallArg0ReturnToReturn | ParameterNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||
| tests.cpp:434:5:434:29 | [summary] read: Argument[0].Parameter[this] in madCallArg0ReturnToReturn | PostUpdateNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||
| tests.cpp:434:5:434:29 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturn | OutNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||
| tests.cpp:434:5:434:29 | [summary] to write: Argument[0].Parameter[this] in madCallArg0ReturnToReturn | ArgumentNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||
| tests.cpp:434:5:434:29 | [summary] to write: ReturnValue in madCallArg0ReturnToReturn | ReturnNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
|
||||
| tests.cpp:435:9:435:38 | [summary param] 0 in madCallArg0ReturnToReturnFirst | ParameterNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||
| tests.cpp:435:9:435:38 | [summary] read: Argument[0].Parameter[this] in madCallArg0ReturnToReturnFirst | PostUpdateNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||
| tests.cpp:435:9:435:38 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturnFirst | OutNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||
| tests.cpp:435:9:435:38 | [summary] to write: Argument[0].Parameter[this] in madCallArg0ReturnToReturnFirst | ArgumentNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||
| tests.cpp:435:9:435:38 | [summary] to write: ReturnValue in madCallArg0ReturnToReturnFirst | ReturnNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||
| tests.cpp:435:9:435:38 | [summary] to write: ReturnValue.Field[first] in madCallArg0ReturnToReturnFirst | | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
|
||||
| tests.cpp:436:6:436:25 | [summary param] 0 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||
| tests.cpp:436:6:436:25 | [summary param] 1 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||
| tests.cpp:436:6:436:25 | [summary] read: Argument[0].Parameter[0] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||
| tests.cpp:436:6:436:25 | [summary] read: Argument[0].Parameter[this] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||
| tests.cpp:436:6:436:25 | [summary] to write: Argument[0].Parameter[0] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||
| tests.cpp:436:6:436:25 | [summary] to write: Argument[0].Parameter[this] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||
| tests.cpp:436:6:436:25 | [summary] to write: Argument[1] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
|
||||
| tests.cpp:437:5:437:36 | [summary param] 1 in madCallReturnValueIgnoreFunction | ParameterNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
|
||||
| tests.cpp:437:5:437:36 | [summary] to write: ReturnValue in madCallReturnValueIgnoreFunction | ReturnNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
|
||||
@@ -0,0 +1,19 @@
|
||||
import testModels
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
|
||||
string describe(DataFlow::Node n) {
|
||||
n instanceof ParameterNode and result = "ParameterNode"
|
||||
or
|
||||
n instanceof PostUpdateNode and result = "PostUpdateNode"
|
||||
or
|
||||
n instanceof ArgumentNode and result = "ArgumentNode"
|
||||
or
|
||||
n instanceof ReturnNode and result = "ReturnNode"
|
||||
or
|
||||
n instanceof OutNode and result = "OutNode"
|
||||
}
|
||||
|
||||
from FlowSummaryNode n
|
||||
select n, concat(describe(n), ", "), concat(n.getSummarizedCallable().toString(), ", "),
|
||||
concat(n.getEnclosingCallable().toString(), ", ")
|
||||
@@ -0,0 +1,220 @@
|
||||
summaryCalls
|
||||
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturn in madCallArg0ReturnToReturn |
|
||||
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturnFirst in madCallArg0ReturnToReturnFirst |
|
||||
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0WithValue in madCallArg0WithValue |
|
||||
summarizedCallables
|
||||
| tests.cpp:144:5:144:19 | madArg0ToReturn |
|
||||
| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
|
||||
| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
|
||||
| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
|
||||
| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
|
||||
| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
|
||||
| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
|
||||
| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
|
||||
| tests.cpp:153:5:153:18 | madArgsComplex |
|
||||
| tests.cpp:154:5:154:14 | madArgsAny |
|
||||
| tests.cpp:155:5:155:28 | madAndImplementedComplex |
|
||||
| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
|
||||
| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
|
||||
| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
|
||||
| tests.cpp:163:13:163:32 | madArg0ToReturnField |
|
||||
| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
|
||||
| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
|
||||
| tests.cpp:284:7:284:19 | madArg0ToSelf |
|
||||
| tests.cpp:285:6:285:20 | madSelfToReturn |
|
||||
| tests.cpp:287:7:287:20 | madArg0ToField |
|
||||
| tests.cpp:288:6:288:21 | madFieldToReturn |
|
||||
| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
|
||||
| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
|
||||
| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
|
||||
| tests.cpp:436:6:436:25 | madCallArg0WithValue |
|
||||
| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
|
||||
sourceCallables
|
||||
| tests.cpp:3:5:3:10 | source |
|
||||
| tests.cpp:4:6:4:14 | sourcePtr |
|
||||
| tests.cpp:5:6:5:19 | sourceIndirect |
|
||||
| tests.cpp:6:6:6:9 | sink |
|
||||
| tests.cpp:6:15:6:17 | val |
|
||||
| tests.cpp:7:6:7:9 | sink |
|
||||
| tests.cpp:7:16:7:18 | ptr |
|
||||
| tests.cpp:11:5:11:18 | localMadSource |
|
||||
| tests.cpp:12:5:12:19 | remoteMadSource |
|
||||
| tests.cpp:13:5:13:14 | notASource |
|
||||
| tests.cpp:14:5:14:22 | localMadSourceVoid |
|
||||
| tests.cpp:15:5:15:25 | localMadSourceHasBody |
|
||||
| tests.cpp:16:6:16:28 | remoteMadSourceIndirect |
|
||||
| tests.cpp:17:7:17:35 | remoteMadSourceDoubleIndirect |
|
||||
| tests.cpp:18:6:18:32 | remoteMadSourceIndirectArg0 |
|
||||
| tests.cpp:18:39:18:39 | x |
|
||||
| tests.cpp:18:47:18:47 | y |
|
||||
| tests.cpp:19:6:19:32 | remoteMadSourceIndirectArg1 |
|
||||
| tests.cpp:19:39:19:39 | x |
|
||||
| tests.cpp:19:47:19:47 | y |
|
||||
| tests.cpp:20:5:20:22 | remoteMadSourceVar |
|
||||
| tests.cpp:21:6:21:31 | remoteMadSourceVarIndirect |
|
||||
| tests.cpp:24:6:24:28 | namespaceLocalMadSource |
|
||||
| tests.cpp:25:6:25:31 | namespaceLocalMadSourceVar |
|
||||
| tests.cpp:28:7:28:30 | namespace2LocalMadSource |
|
||||
| tests.cpp:31:6:31:19 | localMadSource |
|
||||
| tests.cpp:33:5:33:27 | namespaceLocalMadSource |
|
||||
| tests.cpp:35:6:35:17 | test_sources |
|
||||
| tests.cpp:50:6:50:6 | v |
|
||||
| tests.cpp:51:7:51:16 | v_indirect |
|
||||
| tests.cpp:52:6:52:13 | v_direct |
|
||||
| tests.cpp:63:6:63:6 | a |
|
||||
| tests.cpp:63:9:63:9 | b |
|
||||
| tests.cpp:63:12:63:12 | c |
|
||||
| tests.cpp:63:15:63:15 | d |
|
||||
| tests.cpp:75:6:75:6 | e |
|
||||
| tests.cpp:85:6:85:26 | remoteMadSourceParam0 |
|
||||
| tests.cpp:85:32:85:32 | x |
|
||||
| tests.cpp:92:6:92:16 | madSinkArg0 |
|
||||
| tests.cpp:92:22:92:22 | x |
|
||||
| tests.cpp:93:6:93:13 | notASink |
|
||||
| tests.cpp:93:19:93:19 | x |
|
||||
| tests.cpp:94:6:94:16 | madSinkArg1 |
|
||||
| tests.cpp:94:22:94:22 | x |
|
||||
| tests.cpp:94:29:94:29 | y |
|
||||
| tests.cpp:95:6:95:17 | madSinkArg01 |
|
||||
| tests.cpp:95:23:95:23 | x |
|
||||
| tests.cpp:95:30:95:30 | y |
|
||||
| tests.cpp:95:37:95:37 | z |
|
||||
| tests.cpp:96:6:96:17 | madSinkArg02 |
|
||||
| tests.cpp:96:23:96:23 | x |
|
||||
| tests.cpp:96:30:96:30 | y |
|
||||
| tests.cpp:96:37:96:37 | z |
|
||||
| tests.cpp:97:6:97:24 | madSinkIndirectArg0 |
|
||||
| tests.cpp:97:31:97:31 | x |
|
||||
| tests.cpp:98:6:98:30 | madSinkDoubleIndirectArg0 |
|
||||
| tests.cpp:98:38:98:38 | x |
|
||||
| tests.cpp:99:5:99:14 | madSinkVar |
|
||||
| tests.cpp:100:6:100:23 | madSinkVarIndirect |
|
||||
| tests.cpp:102:6:102:15 | test_sinks |
|
||||
| tests.cpp:116:6:116:6 | a |
|
||||
| tests.cpp:117:7:117:11 | a_ptr |
|
||||
| tests.cpp:132:6:132:18 | madSinkParam0 |
|
||||
| tests.cpp:132:24:132:24 | x |
|
||||
| tests.cpp:138:8:138:8 | operator= |
|
||||
| tests.cpp:138:8:138:8 | operator= |
|
||||
| tests.cpp:138:8:138:18 | MyContainer |
|
||||
| tests.cpp:139:6:139:10 | value |
|
||||
| tests.cpp:140:6:140:11 | value2 |
|
||||
| tests.cpp:141:7:141:9 | ptr |
|
||||
| tests.cpp:144:25:144:25 | x |
|
||||
| tests.cpp:145:34:145:34 | x |
|
||||
| tests.cpp:146:5:146:15 | notASummary |
|
||||
| tests.cpp:146:21:146:21 | x |
|
||||
| tests.cpp:147:34:147:34 | x |
|
||||
| tests.cpp:148:34:148:34 | x |
|
||||
| tests.cpp:149:41:149:41 | x |
|
||||
| tests.cpp:150:37:150:37 | x |
|
||||
| tests.cpp:151:32:151:32 | x |
|
||||
| tests.cpp:151:40:151:40 | y |
|
||||
| tests.cpp:152:47:152:47 | x |
|
||||
| tests.cpp:152:55:152:55 | y |
|
||||
| tests.cpp:153:25:153:25 | a |
|
||||
| tests.cpp:153:33:153:33 | b |
|
||||
| tests.cpp:153:40:153:40 | c |
|
||||
| tests.cpp:153:47:153:47 | d |
|
||||
| tests.cpp:154:20:154:20 | a |
|
||||
| tests.cpp:154:28:154:28 | b |
|
||||
| tests.cpp:155:34:155:34 | a |
|
||||
| tests.cpp:155:41:155:41 | b |
|
||||
| tests.cpp:155:48:155:48 | c |
|
||||
| tests.cpp:160:38:160:39 | mc |
|
||||
| tests.cpp:161:47:161:48 | mc |
|
||||
| tests.cpp:162:46:162:47 | mc |
|
||||
| tests.cpp:163:38:163:38 | x |
|
||||
| tests.cpp:164:47:164:47 | x |
|
||||
| tests.cpp:165:46:165:46 | x |
|
||||
| tests.cpp:167:13:167:30 | madFieldToFieldVar |
|
||||
| tests.cpp:168:13:168:38 | madFieldToIndirectFieldVar |
|
||||
| tests.cpp:169:14:169:39 | madIndirectFieldToFieldVar |
|
||||
| tests.cpp:171:6:171:19 | test_summaries |
|
||||
| tests.cpp:174:6:174:6 | a |
|
||||
| tests.cpp:174:9:174:9 | b |
|
||||
| tests.cpp:174:12:174:12 | c |
|
||||
| tests.cpp:174:15:174:15 | d |
|
||||
| tests.cpp:174:18:174:18 | e |
|
||||
| tests.cpp:175:7:175:11 | a_ptr |
|
||||
| tests.cpp:218:14:218:16 | mc1 |
|
||||
| tests.cpp:218:19:218:21 | mc2 |
|
||||
| tests.cpp:237:15:237:18 | rtn1 |
|
||||
| tests.cpp:240:14:240:17 | rtn2 |
|
||||
| tests.cpp:241:7:241:14 | rtn2_ptr |
|
||||
| tests.cpp:267:7:267:7 | operator= |
|
||||
| tests.cpp:267:7:267:7 | operator= |
|
||||
| tests.cpp:267:7:267:13 | MyClass |
|
||||
| tests.cpp:270:6:270:26 | memberRemoteMadSource |
|
||||
| tests.cpp:271:7:271:39 | memberRemoteMadSourceIndirectArg0 |
|
||||
| tests.cpp:271:46:271:46 | x |
|
||||
| tests.cpp:272:6:272:29 | memberRemoteMadSourceVar |
|
||||
| tests.cpp:273:7:273:21 | qualifierSource |
|
||||
| tests.cpp:274:7:274:26 | qualifierFieldSource |
|
||||
| tests.cpp:277:7:277:23 | memberMadSinkArg0 |
|
||||
| tests.cpp:277:29:277:29 | x |
|
||||
| tests.cpp:278:6:278:21 | memberMadSinkVar |
|
||||
| tests.cpp:279:7:279:19 | qualifierSink |
|
||||
| tests.cpp:280:7:280:23 | qualifierArg0Sink |
|
||||
| tests.cpp:280:29:280:29 | x |
|
||||
| tests.cpp:281:7:281:24 | qualifierFieldSink |
|
||||
| tests.cpp:284:25:284:25 | x |
|
||||
| tests.cpp:286:6:286:16 | notASummary |
|
||||
| tests.cpp:287:26:287:26 | x |
|
||||
| tests.cpp:290:6:290:8 | val |
|
||||
| tests.cpp:293:7:293:7 | MyDerivedClass |
|
||||
| tests.cpp:293:7:293:7 | operator= |
|
||||
| tests.cpp:293:7:293:7 | operator= |
|
||||
| tests.cpp:293:7:293:20 | MyDerivedClass |
|
||||
| tests.cpp:295:6:295:28 | subtypeRemoteMadSource1 |
|
||||
| tests.cpp:296:6:296:21 | subtypeNonSource |
|
||||
| tests.cpp:297:6:297:28 | subtypeRemoteMadSource2 |
|
||||
| tests.cpp:300:9:300:15 | source2 |
|
||||
| tests.cpp:301:6:301:9 | sink |
|
||||
| tests.cpp:301:19:301:20 | mc |
|
||||
| tests.cpp:304:8:304:8 | operator= |
|
||||
| tests.cpp:304:8:304:8 | operator= |
|
||||
| tests.cpp:304:8:304:14 | MyClass |
|
||||
| tests.cpp:307:8:307:33 | namespaceMemberMadSinkArg0 |
|
||||
| tests.cpp:307:39:307:39 | x |
|
||||
| tests.cpp:308:15:308:46 | namespaceStaticMemberMadSinkArg0 |
|
||||
| tests.cpp:308:52:308:52 | x |
|
||||
| tests.cpp:309:7:309:31 | namespaceMemberMadSinkVar |
|
||||
| tests.cpp:310:14:310:44 | namespaceStaticMemberMadSinkVar |
|
||||
| tests.cpp:317:22:317:28 | source3 |
|
||||
| tests.cpp:319:6:319:23 | test_class_members |
|
||||
| tests.cpp:320:10:320:11 | mc |
|
||||
| tests.cpp:320:14:320:16 | mc2 |
|
||||
| tests.cpp:320:19:320:21 | mc3 |
|
||||
| tests.cpp:320:24:320:26 | mc4 |
|
||||
| tests.cpp:320:29:320:31 | mc5 |
|
||||
| tests.cpp:320:34:320:36 | mc6 |
|
||||
| tests.cpp:320:39:320:41 | mc7 |
|
||||
| tests.cpp:320:44:320:46 | mc8 |
|
||||
| tests.cpp:320:49:320:51 | mc9 |
|
||||
| tests.cpp:320:54:320:57 | mc10 |
|
||||
| tests.cpp:320:60:320:63 | mc11 |
|
||||
| tests.cpp:321:11:321:13 | ptr |
|
||||
| tests.cpp:321:17:321:23 | mc4_ptr |
|
||||
| tests.cpp:322:17:322:19 | mdc |
|
||||
| tests.cpp:323:23:323:25 | mnc |
|
||||
| tests.cpp:323:28:323:31 | mnc2 |
|
||||
| tests.cpp:324:24:324:31 | mnc2_ptr |
|
||||
| tests.cpp:330:6:330:6 | a |
|
||||
| tests.cpp:429:8:429:8 | operator= |
|
||||
| tests.cpp:429:8:429:8 | operator= |
|
||||
| tests.cpp:429:8:429:14 | intPair |
|
||||
| tests.cpp:430:6:430:10 | first |
|
||||
| tests.cpp:431:6:431:11 | second |
|
||||
| tests.cpp:434:37:434:43 | fun_ptr |
|
||||
| tests.cpp:435:46:435:52 | fun_ptr |
|
||||
| tests.cpp:436:34:436:40 | fun_ptr |
|
||||
| tests.cpp:436:53:436:57 | value |
|
||||
| tests.cpp:437:45:437:51 | fun_ptr |
|
||||
| tests.cpp:437:64:437:68 | value |
|
||||
| tests.cpp:439:5:439:14 | getTainted |
|
||||
| tests.cpp:440:6:440:13 | useValue |
|
||||
| tests.cpp:440:19:440:19 | x |
|
||||
| tests.cpp:441:6:441:17 | dontUseValue |
|
||||
| tests.cpp:441:23:441:23 | x |
|
||||
| tests.cpp:443:6:443:27 | test_function_pointers |
|
||||
@@ -0,0 +1,9 @@
|
||||
import testModels
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
|
||||
query predicate summaryCalls(SummaryCall c) { any() }
|
||||
|
||||
query predicate summarizedCallables(SummarizedCallable c) { any() }
|
||||
|
||||
query predicate sourceCallables(SourceCallable c) { c.getLocation().getFile().toString() != "" }
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
@@ -0,0 +1,18 @@
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import testModels
|
||||
|
||||
module InterpretElementTest implements TestSig {
|
||||
string getARelevantTag() { result = "interpretElement" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(Element e |
|
||||
e = interpretElement(_, _, _, _, _, _) and
|
||||
location = e.getLocation() and
|
||||
element = e.toString() and
|
||||
tag = "interpretElement" and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<InterpretElementTest>
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
32
cpp/ql/test/library-tests/dataflow/models-as-data/taint.ql
Normal file
32
cpp/ql/test/library-tests/dataflow/models-as-data/taint.ql
Normal file
@@ -0,0 +1,32 @@
|
||||
import TestUtilities.dataflow.FlowTestCommon
|
||||
import testModels
|
||||
|
||||
module IRTest {
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
|
||||
/** Common data flow configuration to be used by tests. */
|
||||
module TestAllocationConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source instanceof FlowSource
|
||||
or
|
||||
source.asExpr().(FunctionCall).getTarget().getName() =
|
||||
["source", "source2", "source3", "sourcePtr"]
|
||||
or
|
||||
source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "sourceIndirect"
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sinkNode(sink, "test-sink")
|
||||
or
|
||||
exists(FunctionCall call |
|
||||
call.getTarget().getName() = "sink" and
|
||||
sink.asExpr() = call.getAnArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module IRFlow = TaintTracking::Global<TestAllocationConfig>;
|
||||
}
|
||||
|
||||
import MakeTest<IRFlowTest<IRTest::IRFlow>>
|
||||
103
cpp/ql/test/library-tests/dataflow/models-as-data/testModels.qll
Normal file
103
cpp/ql/test/library-tests/dataflow/models-as-data/testModels.qll
Normal file
@@ -0,0 +1,103 @@
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
|
||||
/**
|
||||
* Models-as-data source models for this test.
|
||||
*/
|
||||
private class TestSources extends SourceModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;localMadSource;;;ReturnValue;local",
|
||||
";;false;remoteMadSource;;;ReturnValue;remote",
|
||||
";;false;localMadSourceVoid;;;ReturnValue;local",
|
||||
";;false;localMadSourceHasBody;;;ReturnValue;local",
|
||||
";;false;remoteMadSourceIndirect;;;ReturnValue[*];remote",
|
||||
";;false;remoteMadSourceDoubleIndirect;;;ReturnValue[**];remote",
|
||||
";;false;remoteMadSourceIndirectArg0;;;Argument[*0];remote",
|
||||
";;false;remoteMadSourceIndirectArg1;;;Argument[*1];remote",
|
||||
";;false;remoteMadSourceVar;;;;remote",
|
||||
";;false;remoteMadSourceVarIndirect;;;*;remote", // not correctly expressed
|
||||
";;false;remoteMadSourceParam0;;;Parameter[0];remote",
|
||||
"MyNamespace;;false;namespaceLocalMadSource;;;ReturnValue;local",
|
||||
"MyNamespace;;false;namespaceLocalMadSourceVar;;;;local",
|
||||
"MyNamespace::MyNamespace2;;false;namespace2LocalMadSource;;;ReturnValue;local",
|
||||
";MyClass;true;memberRemoteMadSource;;;ReturnValue;remote",
|
||||
";MyClass;true;memberRemoteMadSourceIndirectArg0;;;Argument[*0];remote",
|
||||
";MyClass;true;memberRemoteMadSourceVar;;;;remote",
|
||||
";MyClass;true;subtypeRemoteMadSource1;;;ReturnValue;remote",
|
||||
";MyClass;false;subtypeNonSource;;;ReturnValue;remote", // the tests define this in MyDerivedClass, so it should *not* be recongized as a source
|
||||
";MyClass;true;qualifierSource;;;Argument[-1];remote",
|
||||
";MyClass;true;qualifierFieldSource;;;Argument[-1].val;remote",
|
||||
";MyDerivedClass;false;subtypeRemoteMadSource2;;;ReturnValue;remote",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Models-as-data sink models for this test.
|
||||
*/
|
||||
private class TestSinks extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;madSinkArg0;;;Argument[0];test-sink",
|
||||
";;false;madSinkArg1;;;Argument[1];test-sink",
|
||||
";;false;madSinkArg01;;;Argument[0..1];test-sink",
|
||||
";;false;madSinkArg02;;;Argument[0,2];test-sink",
|
||||
";;false;madSinkIndirectArg0;;;Argument[*0];test-sink",
|
||||
";;false;madSinkDoubleIndirectArg0;;;Argument[**0];test-sink",
|
||||
";;false;madSinkVar;;;;test-sink",
|
||||
";;false;madSinkVarIndirect;;;*;test-sink", // not correctly expressed
|
||||
";;false;madSinkParam0;;;Parameter[0];test-sink",
|
||||
";MyClass;true;memberMadSinkArg0;;;Argument[0];test-sink",
|
||||
";MyClass;true;memberMadSinkVar;;;;test-sink",
|
||||
";MyClass;true;qualifierSink;;;Argument[-1];test-sink",
|
||||
";MyClass;true;qualifierArg0Sink;;;Argument[-1..0];test-sink",
|
||||
";MyClass;true;qualifierFieldSink;;;Argument[-1].val;test-sink",
|
||||
"MyNamespace;MyClass;true;namespaceMemberMadSinkArg0;;;Argument[0];test-sink",
|
||||
"MyNamespace;MyClass;true;namespaceStaticMemberMadSinkArg0;;;Argument[0];test-sink",
|
||||
"MyNamespace;MyClass;true;namespaceMemberMadSinkVar;;;;test-sink",
|
||||
"MyNamespace;MyClass;true;namespaceStaticMemberMadSinkVar;;;;test-sink",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Models-as-data summary models for this test.
|
||||
*/
|
||||
private class TestSummaries extends SummaryModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
";;false;madArg0ToReturn;;;Argument[0];ReturnValue;taint",
|
||||
";;false;madArg0ToReturnIndirect;;;Argument[0];ReturnValue[*];taint",
|
||||
";;false;madArg0ToReturnValueFlow;;;Argument[0];ReturnValue;value",
|
||||
";;false;madArg0IndirectToReturn;;;Argument[*0];ReturnValue;taint",
|
||||
";;false;madArg0DoubleIndirectToReturn;;;Argument[**0];ReturnValue;taint",
|
||||
";;false;madArg0NotIndirectToReturn;;;Argument[0];ReturnValue;taint",
|
||||
";;false;madArg0ToArg1Indirect;;;Argument[0];Argument[*1];taint",
|
||||
";;false;madArg0IndirectToArg1Indirect;;;Argument[*0];Argument[*1];taint",
|
||||
";;false;madArgsComplex;;;Argument[*0..1,2];ReturnValue;taint",
|
||||
";;false;madAndImplementedComplex;;;Argument[2];ReturnValue;taint",
|
||||
";;false;madArgsAny;;;Argument;ReturnValue;taint", // (syntax not supported)
|
||||
";;false;madArg0FieldToReturn;;;Argument[0].value;ReturnValue;taint",
|
||||
";;false;madArg0IndirectFieldToReturn;;;Argument[*0].value;ReturnValue;taint",
|
||||
";;false;madArg0FieldIndirectToReturn;;;Argument[0].ptr[*];ReturnValue;taint",
|
||||
";;false;madArg0ToReturnField;;;Argument[0];ReturnValue.value;taint",
|
||||
";;false;madArg0ToReturnIndirectField;;;Argument[0];ReturnValue[*].value;taint",
|
||||
";;false;madArg0ToReturnFieldIndirect;;;Argument[0];ReturnValue.ptr[*];taint",
|
||||
";;false;madFieldToFieldVar;;;value;value2;taint",
|
||||
";;false;madFieldToIndirectFieldVar;;;value;ptr[*];taint",
|
||||
";;false;madIndirectFieldToFieldVar;;;;value;value2;taint", // not correctly expressed
|
||||
";MyClass;true;madArg0ToSelf;;;Argument[0];Argument[-1];taint",
|
||||
";MyClass;true;madSelfToReturn;;;Argument[-1];ReturnValue;taint",
|
||||
";MyClass;true;madArg0ToField;;;Argument[0];Argument[-1].val;taint",
|
||||
";MyClass;true;madFieldToReturn;;;Argument[-1].val;ReturnValue;taint",
|
||||
"MyNamespace;MyClass;true;namespaceMadSelfToReturn;;;Argument[-1];ReturnValue;taint",
|
||||
";;false;madCallArg0ReturnToReturn;;;Argument[0].ReturnValue;ReturnValue;value",
|
||||
";;false;madCallArg0ReturnToReturnFirst;;;Argument[0].ReturnValue;ReturnValue.first;value",
|
||||
";;false;madCallArg0WithValue;;;Argument[1];Argument[0].Parameter[0];value",
|
||||
";;false;madCallReturnValueIgnoreFunction;;;Argument[1];ReturnValue;value",
|
||||
]
|
||||
}
|
||||
}
|
||||
454
cpp/ql/test/library-tests/dataflow/models-as-data/tests.cpp
Normal file
454
cpp/ql/test/library-tests/dataflow/models-as-data/tests.cpp
Normal file
@@ -0,0 +1,454 @@
|
||||
|
||||
// non-MAD sources / sinks
|
||||
int source();
|
||||
int *sourcePtr();
|
||||
int *sourceIndirect();
|
||||
void sink(int val);
|
||||
void sink(int *ptr);
|
||||
|
||||
// --- global MAD sources ---
|
||||
|
||||
int localMadSource(); // $ interpretElement
|
||||
int remoteMadSource(); // $ interpretElement
|
||||
int notASource();
|
||||
int localMadSourceVoid(void); // $ interpretElement
|
||||
int localMadSourceHasBody() { return 0; } // $ interpretElement
|
||||
int *remoteMadSourceIndirect(); // $ interpretElement
|
||||
int **remoteMadSourceDoubleIndirect(); // $ interpretElement
|
||||
void remoteMadSourceIndirectArg0(int *x, int *y); // $ interpretElement
|
||||
void remoteMadSourceIndirectArg1(int &x, int &y); // $ interpretElement
|
||||
int remoteMadSourceVar; // $ interpretElement
|
||||
int *remoteMadSourceVarIndirect; // $ interpretElement
|
||||
|
||||
namespace MyNamespace {
|
||||
int namespaceLocalMadSource(); // $ interpretElement
|
||||
int namespaceLocalMadSourceVar; // $ interpretElement
|
||||
|
||||
namespace MyNamespace2 {
|
||||
int namespace2LocalMadSource(); // $ interpretElement
|
||||
}
|
||||
|
||||
int localMadSource(); // (not a source)
|
||||
}
|
||||
int namespaceLocalMadSource(); // (not a source)
|
||||
|
||||
void test_sources() {
|
||||
sink(0);
|
||||
sink(source()); // $ ir
|
||||
|
||||
// test sources
|
||||
|
||||
sink(localMadSource()); // $ ir
|
||||
sink(remoteMadSource()); // $ ir
|
||||
sink(notASource());
|
||||
sink(localMadSourceVoid()); // $ ir
|
||||
sink(localMadSourceHasBody()); // $ ir
|
||||
|
||||
sink(sourceIndirect());
|
||||
sink(*sourceIndirect()); // $ ir
|
||||
|
||||
int v = localMadSource();
|
||||
int *v_indirect = &v;
|
||||
int v_direct = *v_indirect;
|
||||
sink(v); // $ ir
|
||||
sink(v_indirect);
|
||||
sink(*v_indirect); // $ ir
|
||||
sink(v_direct); // $ ir
|
||||
|
||||
sink(remoteMadSourceIndirect());
|
||||
sink(*remoteMadSourceIndirect()); // $ MISSING: ir
|
||||
sink(*remoteMadSourceDoubleIndirect());
|
||||
sink(**remoteMadSourceDoubleIndirect()); // $ MISSING: ir
|
||||
|
||||
int a, b, c, d;
|
||||
|
||||
remoteMadSourceIndirectArg0(&a, &b);
|
||||
sink(a); // $ ir
|
||||
sink(b);
|
||||
remoteMadSourceIndirectArg1(c, d);
|
||||
sink(c);
|
||||
sink(d); // $ ir
|
||||
|
||||
sink(remoteMadSourceVar); // $ ir
|
||||
sink(*remoteMadSourceVarIndirect); // $ MISSING: ir
|
||||
|
||||
int e = localMadSource();
|
||||
sink(e); // $ ir
|
||||
|
||||
sink(MyNamespace::namespaceLocalMadSource()); // $: ir
|
||||
sink(MyNamespace::namespaceLocalMadSourceVar); // $ ir
|
||||
sink(MyNamespace::MyNamespace2::namespace2LocalMadSource()); // $ ir
|
||||
sink(MyNamespace::localMadSource()); // $ (the MyNamespace version of this function is not a source)
|
||||
sink(namespaceLocalMadSource()); // (the global namespace version of this function is not a source)
|
||||
}
|
||||
|
||||
void remoteMadSourceParam0(int x) // $ interpretElement
|
||||
{
|
||||
sink(x); // $ ir
|
||||
}
|
||||
|
||||
// --- global MAD sinks ---
|
||||
|
||||
void madSinkArg0(int x); // $ interpretElement
|
||||
void notASink(int x);
|
||||
void madSinkArg1(int x, int y); // $ interpretElement
|
||||
void madSinkArg01(int x, int y, int z); // $ interpretElement
|
||||
void madSinkArg02(int x, int y, int z); // $ interpretElement
|
||||
void madSinkIndirectArg0(int *x); // $ interpretElement
|
||||
void madSinkDoubleIndirectArg0(int **x); // $ interpretElement
|
||||
int madSinkVar; // $ interpretElement
|
||||
int *madSinkVarIndirect; // $ interpretElement
|
||||
|
||||
void test_sinks() {
|
||||
// test sinks
|
||||
|
||||
madSinkArg0(source()); // $ ir
|
||||
notASink(source());
|
||||
madSinkArg1(source(), 0);
|
||||
madSinkArg1(0, source()); // $ ir
|
||||
madSinkArg01(source(), 0, 0); // $ ir
|
||||
madSinkArg01(0, source(), 0); // $ ir
|
||||
madSinkArg01(0, 0, source());
|
||||
madSinkArg02(source(), 0, 0); // $ ir
|
||||
madSinkArg02(0, source(), 0);
|
||||
madSinkArg02(0, 0, source()); // $ ir
|
||||
|
||||
int a = source();
|
||||
int *a_ptr = &a;
|
||||
madSinkIndirectArg0(&a); // $ ir
|
||||
madSinkIndirectArg0(a_ptr); // $ ir
|
||||
madSinkDoubleIndirectArg0(&a_ptr); // $ ir
|
||||
|
||||
madSinkVar = source(); // $ ir
|
||||
|
||||
// test sources + sinks together
|
||||
|
||||
madSinkArg0(localMadSource()); // $ ir
|
||||
madSinkIndirectArg0(remoteMadSourceIndirect()); // $ MISSING: ir
|
||||
madSinkVar = remoteMadSourceVar; // $ ir
|
||||
*madSinkVarIndirect = remoteMadSourceVar; // $ MISSING: ir
|
||||
}
|
||||
|
||||
void madSinkParam0(int x) { // $ interpretElement
|
||||
x = source(); // $ MISSING: ir
|
||||
}
|
||||
|
||||
// --- global MAD summaries ---
|
||||
|
||||
struct MyContainer {
|
||||
int value;
|
||||
int value2;
|
||||
int *ptr;
|
||||
};
|
||||
|
||||
int madArg0ToReturn(int x); // $ interpretElement
|
||||
int *madArg0ToReturnIndirect(int x); // $ interpretElement
|
||||
int notASummary(int x);
|
||||
int madArg0ToReturnValueFlow(int x); // $ interpretElement
|
||||
int madArg0IndirectToReturn(int *x); // $ interpretElement
|
||||
int madArg0DoubleIndirectToReturn(int **x); // $ interpretElement
|
||||
int madArg0NotIndirectToReturn(int *x); // $ interpretElement
|
||||
void madArg0ToArg1Indirect(int x, int &y); // $ interpretElement
|
||||
void madArg0IndirectToArg1Indirect(const int *x, int *y); // $ interpretElement
|
||||
int madArgsComplex(int *a, int *b, int c, int d); // $ interpretElement
|
||||
int madArgsAny(int a, int *b); // $ interpretElement
|
||||
int madAndImplementedComplex(int a, int b, int c) { // $ interpretElement
|
||||
// (`b` can be seen to flow to the return value in code, `c` via the MAD model)
|
||||
return b;
|
||||
}
|
||||
|
||||
int madArg0FieldToReturn(MyContainer mc); // $ interpretElement
|
||||
int madArg0IndirectFieldToReturn(MyContainer *mc); // $ interpretElement
|
||||
int madArg0FieldIndirectToReturn(MyContainer mc); // $ interpretElement
|
||||
MyContainer madArg0ToReturnField(int x); // $ interpretElement
|
||||
MyContainer *madArg0ToReturnIndirectField(int x); // $ interpretElement
|
||||
MyContainer madArg0ToReturnFieldIndirect(int x); // $ interpretElement
|
||||
|
||||
MyContainer madFieldToFieldVar; // $ interpretElement
|
||||
MyContainer madFieldToIndirectFieldVar; // $ interpretElement
|
||||
MyContainer *madIndirectFieldToFieldVar; // $ interpretElement
|
||||
|
||||
void test_summaries() {
|
||||
// test summaries
|
||||
|
||||
int a, b, c, d, e;
|
||||
int *a_ptr;
|
||||
|
||||
sink(madArg0ToReturn(0));
|
||||
sink(madArg0ToReturn(source())); // $ ir
|
||||
sink(*madArg0ToReturnIndirect(0));
|
||||
sink(*madArg0ToReturnIndirect(source())); // $ ir
|
||||
sink(notASummary(source()));
|
||||
sink(madArg0ToReturnValueFlow(0));
|
||||
sink(madArg0ToReturnValueFlow(source())); // $ ir
|
||||
|
||||
a = source();
|
||||
a_ptr = &a;
|
||||
sink(madArg0IndirectToReturn(&a)); // $ ir
|
||||
sink(madArg0IndirectToReturn(a_ptr)); // $ ir
|
||||
sink(madArg0DoubleIndirectToReturn(&a_ptr)); // $ ir
|
||||
sink(madArg0NotIndirectToReturn(a_ptr));
|
||||
sink(madArg0NotIndirectToReturn(sourcePtr())); // $ ir
|
||||
sink(madArg0NotIndirectToReturn(sourceIndirect()));
|
||||
|
||||
madArg0ToArg1Indirect(source(), b);
|
||||
sink(b); // $ ir
|
||||
|
||||
madArg0IndirectToArg1Indirect(&a, &c);
|
||||
sink(c); // $ ir
|
||||
|
||||
sink(madArgsComplex(0, 0, 0, 0));
|
||||
sink(madArgsComplex(sourceIndirect(), 0, 0, 0)); // $ ir
|
||||
sink(madArgsComplex(0, sourceIndirect(), 0, 0)); // $ ir
|
||||
sink(madArgsComplex(0, 0, source(), 0)); // $ ir
|
||||
sink(madArgsComplex(0, 0, 0, source()));
|
||||
|
||||
sink(madAndImplementedComplex(0, 0, 0));
|
||||
sink(madAndImplementedComplex(source(), 0, 0));
|
||||
sink(madAndImplementedComplex(0, source(), 0)); // $ ir
|
||||
sink(madAndImplementedComplex(0, 0, source())); // $ ir
|
||||
|
||||
sink(madArgsAny(0, 0));
|
||||
sink(madArgsAny(source(), 0)); // (syntax not supported)
|
||||
sink(madArgsAny(0, sourcePtr())); // (syntax not supported)
|
||||
sink(madArgsAny(0, sourceIndirect())); // (syntax not supported)
|
||||
|
||||
// test summaries involving structs / fields
|
||||
|
||||
MyContainer mc1, mc2;
|
||||
|
||||
d = 0;
|
||||
mc1.value = 0;
|
||||
mc1.ptr = &d;
|
||||
sink(madArg0FieldToReturn(mc1));
|
||||
sink(madArg0IndirectFieldToReturn(&mc1));
|
||||
sink(madArg0FieldIndirectToReturn(mc1));
|
||||
|
||||
e = source();
|
||||
mc2.value = source();
|
||||
mc2.ptr = &e;
|
||||
sink(madArg0FieldToReturn(mc2)); // $ ir
|
||||
sink(madArg0IndirectFieldToReturn(&mc2)); // $ ir
|
||||
sink(madArg0FieldIndirectToReturn(mc2)); // $ ir
|
||||
|
||||
sink(madArg0ToReturnField(0).value);
|
||||
sink(madArg0ToReturnField(source()).value); // $ ir
|
||||
|
||||
MyContainer *rtn1 = madArg0ToReturnIndirectField(source());
|
||||
sink(rtn1->value); // $ ir
|
||||
|
||||
MyContainer rtn2 = madArg0ToReturnFieldIndirect(source());
|
||||
int *rtn2_ptr = rtn2.ptr;
|
||||
sink(*rtn2_ptr); // $ ir
|
||||
|
||||
// test global variable summaries
|
||||
|
||||
madFieldToFieldVar.value = source();
|
||||
sink(madFieldToFieldVar.value2); // $ MISSING: ir
|
||||
|
||||
madFieldToIndirectFieldVar.value = source();
|
||||
sink(madFieldToIndirectFieldVar.ptr);
|
||||
sink(*(madFieldToIndirectFieldVar.ptr)); // $ MISSING: ir
|
||||
|
||||
madIndirectFieldToFieldVar->value = source();
|
||||
sink((*madIndirectFieldToFieldVar).value2); // $ MISSING: ir
|
||||
sink(madIndirectFieldToFieldVar->value2); // $ MISSING: ir
|
||||
|
||||
// test source + sinks + summaries together
|
||||
|
||||
madSinkArg0(madArg0ToReturn(remoteMadSource())); // $ ir
|
||||
madSinkArg0(madArg0ToReturnValueFlow(remoteMadSource())); // $ ir
|
||||
madSinkArg0(madArg0IndirectToReturn(sourcePtr()));
|
||||
madSinkArg0(madArg0IndirectToReturn(sourceIndirect())); // $ ir
|
||||
}
|
||||
|
||||
// --- MAD class members ---
|
||||
|
||||
class MyClass {
|
||||
public:
|
||||
// sources
|
||||
int memberRemoteMadSource(); // $ interpretElement
|
||||
void memberRemoteMadSourceIndirectArg0(int *x); // $ interpretElement
|
||||
int memberRemoteMadSourceVar; // $ interpretElement
|
||||
void qualifierSource(); // $ interpretElement
|
||||
void qualifierFieldSource(); // $ interpretElement
|
||||
|
||||
// sinks
|
||||
void memberMadSinkArg0(int x); // $ interpretElement
|
||||
int memberMadSinkVar; // $ interpretElement
|
||||
void qualifierSink(); // $ interpretElement
|
||||
void qualifierArg0Sink(int x); // $ interpretElement
|
||||
void qualifierFieldSink(); // $ interpretElement
|
||||
|
||||
// summaries
|
||||
void madArg0ToSelf(int x); // $ interpretElement
|
||||
int madSelfToReturn(); // $ interpretElement
|
||||
int notASummary();
|
||||
void madArg0ToField(int x); // $ interpretElement
|
||||
int madFieldToReturn(); // $ interpretElement
|
||||
|
||||
int val;
|
||||
};
|
||||
|
||||
class MyDerivedClass : public MyClass {
|
||||
public:
|
||||
int subtypeRemoteMadSource1(); // $ interpretElement
|
||||
int subtypeNonSource();
|
||||
int subtypeRemoteMadSource2(); // $ interpretElement
|
||||
};
|
||||
|
||||
MyClass source2();
|
||||
void sink(MyClass mc);
|
||||
|
||||
namespace MyNamespace {
|
||||
class MyClass {
|
||||
public:
|
||||
// sinks
|
||||
void namespaceMemberMadSinkArg0(int x); // $ interpretElement
|
||||
static void namespaceStaticMemberMadSinkArg0(int x); // $ interpretElement
|
||||
int namespaceMemberMadSinkVar; // $ interpretElement
|
||||
static int namespaceStaticMemberMadSinkVar; // $ interpretElement
|
||||
|
||||
// summaries
|
||||
int namespaceMadSelfToReturn(); // $ interpretElement
|
||||
};
|
||||
}
|
||||
|
||||
MyNamespace::MyClass source3();
|
||||
|
||||
void test_class_members() {
|
||||
MyClass mc, mc2, mc3, mc4, mc5, mc6, mc7, mc8, mc9, mc10, mc11;
|
||||
MyClass *ptr, *mc4_ptr;
|
||||
MyDerivedClass mdc;
|
||||
MyNamespace::MyClass mnc, mnc2;
|
||||
MyNamespace::MyClass *mnc2_ptr;
|
||||
|
||||
// test class member sources
|
||||
|
||||
sink(mc.memberRemoteMadSource()); // $ ir
|
||||
|
||||
int a;
|
||||
mc.memberRemoteMadSourceIndirectArg0(&a);
|
||||
sink(a); // $ ir
|
||||
|
||||
sink(mc.memberRemoteMadSourceVar); // $ ir
|
||||
|
||||
// test subtype sources
|
||||
|
||||
sink(mdc.memberRemoteMadSource()); // $ ir
|
||||
sink(mdc.subtypeRemoteMadSource1()); // $ ir
|
||||
sink(mdc.subtypeNonSource());
|
||||
sink(mdc.subtypeRemoteMadSource2()); // $ ir
|
||||
|
||||
// test class member sinks
|
||||
|
||||
mc.memberMadSinkArg0(source()); // $ ir
|
||||
|
||||
mc.memberMadSinkVar = source(); // $ ir
|
||||
|
||||
mnc.namespaceMemberMadSinkArg0(source()); // $ ir
|
||||
MyNamespace::MyClass::namespaceStaticMemberMadSinkArg0(source()); // $ ir
|
||||
mnc.namespaceMemberMadSinkVar = source(); // $ ir
|
||||
MyNamespace::MyClass::namespaceStaticMemberMadSinkVar = source(); // $ ir
|
||||
|
||||
// test class member summaries
|
||||
|
||||
sink(mc2);
|
||||
mc2.madArg0ToSelf(0);
|
||||
sink(mc2);
|
||||
mc2.madArg0ToSelf(source());
|
||||
sink(mc2); // $ ir
|
||||
|
||||
ptr = new MyClass();
|
||||
sink(*ptr);
|
||||
ptr->madArg0ToSelf(0);
|
||||
sink(*ptr);
|
||||
ptr->madArg0ToSelf(source());
|
||||
sink(*ptr); // $ ir
|
||||
|
||||
mc3.madArg0ToField(source());
|
||||
sink(mc3.val); // $ ir
|
||||
|
||||
mc4 = source2();
|
||||
mc4_ptr = &mc4;
|
||||
sink(mc4); // $ ir
|
||||
sink(mc4.madSelfToReturn()); // $ ir
|
||||
sink(mc4.notASummary());
|
||||
sink(mc4_ptr->madSelfToReturn()); // $ ir
|
||||
sink(mc4_ptr->notASummary());
|
||||
sink(source2().madSelfToReturn()); // $ ir
|
||||
sink(source2().notASummary());
|
||||
|
||||
mc5.val = source();
|
||||
sink(mc5.madFieldToReturn()); // $ ir
|
||||
|
||||
mnc2 = source3();
|
||||
mnc2_ptr = &mnc2;
|
||||
sink(mnc2.namespaceMadSelfToReturn()); // $ ir
|
||||
sink(mnc2_ptr->namespaceMadSelfToReturn()); // $ ir
|
||||
sink(source3().namespaceMadSelfToReturn()); // $ ir
|
||||
|
||||
// test class member sources + sinks + summaries together
|
||||
|
||||
mc.memberMadSinkArg0(mc.memberRemoteMadSource()); // $ ir
|
||||
|
||||
mc6.madArg0ToSelf(source());
|
||||
sink(mc6.madSelfToReturn()); // $ ir
|
||||
|
||||
mc7.madArg0ToField(source());
|
||||
sink(mc7.madFieldToReturn()); // $ ir
|
||||
|
||||
// test taint involving qualifier
|
||||
|
||||
sink(mc8);
|
||||
mc8.qualifierArg0Sink(0);
|
||||
mc8.qualifierArg0Sink(source()); // $ ir
|
||||
|
||||
mc9 = source2();
|
||||
mc9.qualifierSink(); // $ ir
|
||||
mc9.qualifierArg0Sink(0); // $ ir
|
||||
|
||||
mc8.qualifierSource();
|
||||
sink(mc8); // $ ir
|
||||
mc8.qualifierSink(); // $ ir
|
||||
mc9.qualifierArg0Sink(0); // $ ir
|
||||
|
||||
// test taint involving qualifier field
|
||||
|
||||
sink(mc10.val);
|
||||
mc10.qualifierFieldSource();
|
||||
sink(mc10.val); // $ MISSING: ir
|
||||
|
||||
mc11.val = source();
|
||||
sink(mc11.val); // $ ir
|
||||
mc11.qualifierFieldSink(); // $ MISSING: ir
|
||||
}
|
||||
|
||||
// --- MAD cases involving function pointers ---
|
||||
|
||||
struct intPair {
|
||||
int first;
|
||||
int second;
|
||||
};
|
||||
|
||||
int madCallArg0ReturnToReturn(int (*fun_ptr)()); // $ interpretElement
|
||||
intPair madCallArg0ReturnToReturnFirst(int (*fun_ptr)()); // $ interpretElement
|
||||
void madCallArg0WithValue(void (*fun_ptr)(int), int value); // $ interpretElement
|
||||
int madCallReturnValueIgnoreFunction(void (*fun_ptr)(int), int value); // $ interpretElement
|
||||
|
||||
int getTainted() { return source(); }
|
||||
void useValue(int x) { sink(x); } // $ ir
|
||||
void dontUseValue(int x) { }
|
||||
|
||||
void test_function_pointers() {
|
||||
sink(madCallArg0ReturnToReturn(¬ASource));
|
||||
sink(madCallArg0ReturnToReturn(&getTainted)); // $ ir
|
||||
sink(madCallArg0ReturnToReturn(&source)); // $ MISSING: ir
|
||||
sink(madCallArg0ReturnToReturnFirst(&getTainted).first); // $ ir
|
||||
sink(madCallArg0ReturnToReturnFirst(&getTainted).second);
|
||||
|
||||
madCallArg0WithValue(&useValue, source());
|
||||
madCallArg0WithValue(&sink, source()); // $ MISSING: ir
|
||||
madCallReturnValueIgnoreFunction(&sink, source());
|
||||
sink(madCallReturnValueIgnoreFunction(&dontUseValue, source())); // $ ir
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
void sink(int); // $ ir
|
||||
void indirect_sink(int*); // $ ir
|
||||
int source();
|
||||
|
||||
void test() {
|
||||
int x = source();
|
||||
sink(x);
|
||||
|
||||
int* p = &x;
|
||||
indirect_sink(p);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
import TestUtilities.dataflow.FlowTestCommon
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
module ParamConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr().(Call).getTarget().hasName("source") }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink.asParameter().getFunction().hasName("sink")
|
||||
or
|
||||
sink.asParameter(1).getFunction().hasName("indirect_sink")
|
||||
}
|
||||
}
|
||||
|
||||
module IRFlow = DataFlow::Global<ParamConfig>;
|
||||
|
||||
import MakeTest<IRFlowTest<IRFlow>>
|
||||
@@ -1,2 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -50,3 +50,68 @@ void test_inet(char *hostname, char *servname, struct addrinfo *hints) {
|
||||
addrinfo *res;
|
||||
int ret = getaddrinfo(hostname, servname, hints, &res); // $ remote_source
|
||||
}
|
||||
|
||||
typedef unsigned int wint_t;
|
||||
|
||||
// getc variants
|
||||
int getc(FILE *stream);
|
||||
wint_t getwc(FILE *stream);
|
||||
int _getc_nolock(FILE *stream);
|
||||
wint_t _getwc_nolock(FILE *stream);
|
||||
|
||||
int getch(void);
|
||||
int _getch(void);
|
||||
wint_t _getwch(void);
|
||||
int _getch_nolock(void);
|
||||
wint_t _getwch_nolock(void);
|
||||
int getchar(void);
|
||||
wint_t getwchar();
|
||||
int _getchar_nolock(void);
|
||||
wint_t _getwchar_nolock(void);
|
||||
|
||||
void test_getchar(FILE *stream) {
|
||||
int a = getc(stream); // $ remote_source
|
||||
wint_t b = getwc(stream); // $ remote_source
|
||||
int c = _getc_nolock(stream); // $ remote_source
|
||||
wint_t d = _getwc_nolock(stream); // $ remote_source
|
||||
|
||||
int e = getch(); // $ local_source
|
||||
int f = _getch(); // $ local_source
|
||||
wint_t g = _getwch(); // $ local_source
|
||||
int h = _getch_nolock(); // $ local_source
|
||||
wint_t i = _getwch_nolock(); // $ local_source
|
||||
int j = getchar(); // $ local_source
|
||||
wint_t k = getwchar(); // $ local_source
|
||||
int l = _getchar_nolock(); // $ local_source
|
||||
wint_t m = _getwchar_nolock(); // $ local_source
|
||||
}
|
||||
|
||||
// ZMC networking library
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
struct zmq_msg_t {
|
||||
};
|
||||
int zmq_msg_init(zmq_msg_t *msg);
|
||||
int zmq_msg_recv(zmq_msg_t *msg, void *socket, int flags);
|
||||
int zmq_recvmsg(void *socket, zmq_msg_t *msg, int flags); // deprecated
|
||||
int zmq_recv(void *socket, void *buf, size_t len, int flags);
|
||||
|
||||
void test_zmc(void *socket) {
|
||||
zmq_msg_t msg1, msg2;
|
||||
char buffer[1024];
|
||||
|
||||
if (zmq_recv(socket, buffer, sizeof(buffer), 0) >= 0) { // $ remote_source
|
||||
// ...
|
||||
}
|
||||
|
||||
zmq_msg_init(&msg1);
|
||||
if (zmq_msg_recv(&msg1, socket, 0) >= 0) { // $ remote_source
|
||||
// ...
|
||||
}
|
||||
|
||||
zmq_msg_init(&msg2);
|
||||
if (zmq_recvmsg(socket, &msg2, 0) >= 0) { // $ remote_source
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8223,3 +8223,50 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future (
|
||||
| vector.cpp:531:9:531:10 | it | vector.cpp:531:8:531:8 | call to operator* | TAINT |
|
||||
| vector.cpp:532:8:532:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
|
||||
| vector.cpp:532:8:532:9 | vs | vector.cpp:532:10:532:10 | call to operator[] | TAINT |
|
||||
| zmq.cpp:17:21:17:26 | socket | zmq.cpp:17:21:17:26 | socket | |
|
||||
| zmq.cpp:17:35:17:46 | message_data | zmq.cpp:17:35:17:46 | message_data | |
|
||||
| zmq.cpp:17:35:17:46 | message_data | zmq.cpp:20:35:20:46 | message_data | |
|
||||
| zmq.cpp:17:35:17:46 | message_data | zmq.cpp:25:3:25:14 | message_data | |
|
||||
| zmq.cpp:17:35:17:46 | message_data | zmq.cpp:26:8:26:19 | message_data | |
|
||||
| zmq.cpp:17:35:17:46 | message_data | zmq.cpp:28:35:28:46 | message_data | |
|
||||
| zmq.cpp:17:56:17:66 | message_len | zmq.cpp:20:49:20:59 | message_len | |
|
||||
| zmq.cpp:17:56:17:66 | message_len | zmq.cpp:28:49:28:59 | message_len | |
|
||||
| zmq.cpp:18:13:18:19 | message | zmq.cpp:20:26:20:32 | message | |
|
||||
| zmq.cpp:18:13:18:19 | message | zmq.cpp:21:10:21:16 | message | |
|
||||
| zmq.cpp:18:13:18:19 | message | zmq.cpp:22:24:22:30 | message | |
|
||||
| zmq.cpp:18:13:18:19 | message | zmq.cpp:28:26:28:32 | message | |
|
||||
| zmq.cpp:18:13:18:19 | message | zmq.cpp:29:10:29:16 | message | |
|
||||
| zmq.cpp:18:13:18:19 | message | zmq.cpp:30:24:30:30 | message | |
|
||||
| zmq.cpp:20:25:20:32 | ref arg & ... | zmq.cpp:20:26:20:32 | message [inner post update] | |
|
||||
| zmq.cpp:20:25:20:32 | ref arg & ... | zmq.cpp:21:10:21:16 | message | |
|
||||
| zmq.cpp:20:25:20:32 | ref arg & ... | zmq.cpp:22:24:22:30 | message | |
|
||||
| zmq.cpp:20:25:20:32 | ref arg & ... | zmq.cpp:28:26:28:32 | message | |
|
||||
| zmq.cpp:20:25:20:32 | ref arg & ... | zmq.cpp:29:10:29:16 | message | |
|
||||
| zmq.cpp:20:25:20:32 | ref arg & ... | zmq.cpp:30:24:30:30 | message | |
|
||||
| zmq.cpp:20:26:20:32 | message | zmq.cpp:20:25:20:32 | & ... | |
|
||||
| zmq.cpp:20:35:20:46 | ref arg message_data | zmq.cpp:17:35:17:46 | message_data | |
|
||||
| zmq.cpp:20:35:20:46 | ref arg message_data | zmq.cpp:25:3:25:14 | message_data | |
|
||||
| zmq.cpp:20:35:20:46 | ref arg message_data | zmq.cpp:26:8:26:19 | message_data | |
|
||||
| zmq.cpp:20:35:20:46 | ref arg message_data | zmq.cpp:28:35:28:46 | message_data | |
|
||||
| zmq.cpp:22:23:22:30 | ref arg & ... | zmq.cpp:22:24:22:30 | message [inner post update] | |
|
||||
| zmq.cpp:22:23:22:30 | ref arg & ... | zmq.cpp:28:26:28:32 | message | |
|
||||
| zmq.cpp:22:23:22:30 | ref arg & ... | zmq.cpp:29:10:29:16 | message | |
|
||||
| zmq.cpp:22:23:22:30 | ref arg & ... | zmq.cpp:30:24:30:30 | message | |
|
||||
| zmq.cpp:22:24:22:30 | message | zmq.cpp:22:23:22:30 | & ... | |
|
||||
| zmq.cpp:25:3:25:14 | message_data | zmq.cpp:25:3:25:17 | access to array | TAINT |
|
||||
| zmq.cpp:25:3:25:17 | access to array [post update] | zmq.cpp:17:35:17:46 | message_data | |
|
||||
| zmq.cpp:25:3:25:17 | access to array [post update] | zmq.cpp:25:3:25:14 | message_data [inner post update] | |
|
||||
| zmq.cpp:25:3:25:17 | access to array [post update] | zmq.cpp:26:8:26:19 | message_data | |
|
||||
| zmq.cpp:25:3:25:17 | access to array [post update] | zmq.cpp:28:35:28:46 | message_data | |
|
||||
| zmq.cpp:25:3:25:28 | ... = ... | zmq.cpp:25:3:25:17 | access to array [post update] | |
|
||||
| zmq.cpp:25:16:25:16 | 0 | zmq.cpp:25:3:25:17 | access to array | TAINT |
|
||||
| zmq.cpp:25:21:25:26 | call to source | zmq.cpp:25:3:25:28 | ... = ... | |
|
||||
| zmq.cpp:26:8:26:19 | ref arg message_data | zmq.cpp:17:35:17:46 | message_data | |
|
||||
| zmq.cpp:26:8:26:19 | ref arg message_data | zmq.cpp:28:35:28:46 | message_data | |
|
||||
| zmq.cpp:28:25:28:32 | ref arg & ... | zmq.cpp:28:26:28:32 | message [inner post update] | |
|
||||
| zmq.cpp:28:25:28:32 | ref arg & ... | zmq.cpp:29:10:29:16 | message | |
|
||||
| zmq.cpp:28:25:28:32 | ref arg & ... | zmq.cpp:30:24:30:30 | message | |
|
||||
| zmq.cpp:28:26:28:32 | message | zmq.cpp:28:25:28:32 | & ... | |
|
||||
| zmq.cpp:28:35:28:46 | ref arg message_data | zmq.cpp:17:35:17:46 | message_data | |
|
||||
| zmq.cpp:30:23:30:30 | ref arg & ... | zmq.cpp:30:24:30:30 | message [inner post update] | |
|
||||
| zmq.cpp:30:24:30:30 | message | zmq.cpp:30:23:30:30 | & ... | |
|
||||
|
||||
@@ -354,7 +354,7 @@ void test_vector_output_iterator(int b) {
|
||||
for(std::vector<int>::iterator it = v4.begin(); it != v4.end(); ++it) {
|
||||
taint_vector_output_iterator(it);
|
||||
}
|
||||
sink(v4); // $ ast,ir
|
||||
sink(v4); // $ ast MISSING: ir
|
||||
|
||||
std::vector<int>::iterator i5 = v5.begin();
|
||||
*i5 = source();
|
||||
@@ -389,7 +389,7 @@ void test_vector_output_iterator(int b) {
|
||||
*i9 = source();
|
||||
taint_vector_output_iterator(i9);
|
||||
|
||||
sink(v9); // $ ast=330:10 ir=330:10 ir SPURIOUS: ast=389:8 ir=389:8
|
||||
sink(v9); // $ ast=330:10 MISSING: ir SPURIOUS: ast=389:8
|
||||
|
||||
std::vector<int>::iterator i10 = v10.begin();
|
||||
vector_iterator_assign_wrapper(i10, 10);
|
||||
@@ -397,7 +397,7 @@ void test_vector_output_iterator(int b) {
|
||||
|
||||
std::vector<int>::iterator i11 = v11.begin();
|
||||
vector_iterator_assign_wrapper(i11, source());
|
||||
sink(v11); // $ ast,ir
|
||||
sink(v11); // $ ast MISSING: ir
|
||||
|
||||
std::vector<int>::iterator i12 = v12.begin();
|
||||
*i12++ = 0;
|
||||
|
||||
32
cpp/ql/test/library-tests/dataflow/taint-tests/zmq.cpp
Normal file
32
cpp/ql/test/library-tests/dataflow/taint-tests/zmq.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
int source();
|
||||
void sink(...);
|
||||
|
||||
// --- ZMC networking library ---
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
struct zmq_msg_t {
|
||||
// ...
|
||||
};
|
||||
typedef void (*zmq_free_fn)();
|
||||
|
||||
int zmq_msg_init_data(zmq_msg_t *msg, void *data, size_t size, zmq_free_fn *ffn, void *hint);
|
||||
void *zmq_msg_data(zmq_msg_t *msg);
|
||||
|
||||
void test_zmc(void *socket, char *message_data, size_t message_len) {
|
||||
zmq_msg_t message;
|
||||
|
||||
if (zmq_msg_init_data(&message, message_data, message_len, 0, 0)) {
|
||||
sink(message); // $ SPURIOUS: ast
|
||||
sink(zmq_msg_data(&message));
|
||||
}
|
||||
|
||||
message_data[0] = source();
|
||||
sink(message_data); // $ ast,ir
|
||||
|
||||
if (zmq_msg_init_data(&message, message_data, message_len, 0, 0)) {
|
||||
sink(message); // $ ast,ir
|
||||
sink(zmq_msg_data(&message)); // $ ir MISSING: ast
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,18 @@
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:4:9:4:12 | name | public | CharPointerType | char |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:4:9:4:12 | name | public | PointerOrArrayOrReferenceType | char |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:5:8:5:8 | t | public | Enum | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:6:9:6:9 | s | public | CharPointerType | char |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:6:9:6:9 | s | public | PointerOrArrayOrReferenceType | char |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:7:7:7:7 | i | public | IntType | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:7:7:7:7 | i | public | MicrosoftInt32Type | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:9:7:9:14 | internal | private | IntType | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:9:7:9:14 | internal | private | MicrosoftInt32Type | |
|
||||
| fields.cpp:12:7:12:10 | Name | fields.cpp:13:15:13:15 | s | private | PointerOrArrayOrReferenceType | const char |
|
||||
| fields.cpp:12:7:12:10 | Name | fields.cpp:13:15:13:15 | s | private | PointerType | const char |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:17:9:17:9 | p | private | PointerOrArrayOrReferenceType | Name |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:17:9:17:9 | p | private | PointerType | Name |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:18:7:18:8 | sz | private | IntType | |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:18:7:18:8 | sz | private | MicrosoftInt32Type | |
|
||||
| fields.cpp:26:7:26:10 | Date | fields.cpp:28:16:28:26 | cache_valid | private | BoolType | |
|
||||
| fields.cpp:26:7:26:10 | Date | fields.cpp:30:17:30:21 | cache | public | CharPointerType | char |
|
||||
| fields.cpp:26:7:26:10 | Date | fields.cpp:30:17:30:21 | cache | public | PointerOrArrayOrReferenceType | char |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,12 +6,6 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| coroutines.cpp:87:20:87:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:91:21:91:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:95:20:95:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:99:21:99:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:103:20:103:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:108:21:108:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -6,12 +6,6 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| coroutines.cpp:87:20:87:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:91:21:91:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:95:20:95:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:99:21:99:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:103:20:103:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:108:21:108:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -38,43 +38,21 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| coroutines.cpp:87:20:87:20 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:87:20:87:20 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:87:20:87:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:87:20:88:11 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:87:20:88:11 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:91:21:91:21 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:91:21:91:21 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:91:21:91:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:91:21:92:11 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:91:21:92:11 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:95:20:95:20 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:95:20:95:20 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:95:20:95:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:95:20:96:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:95:20:96:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:96:12:96:12 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:96:13:96:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:99:21:99:21 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:99:21:99:21 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:99:21:99:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:99:21:100:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:99:21:100:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:100:12:100:12 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:100:13:100:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:103:20:103:20 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:103:20:103:20 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:103:20:103:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:103:20:104:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:103:20:104:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:104:12:104:12 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:104:13:104:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:108:21:108:21 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| coroutines.cpp:108:21:108:21 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| coroutines.cpp:108:21:108:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| coroutines.cpp:108:21:109:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| coroutines.cpp:108:21:109:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| coroutines.cpp:109:12:109:12 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| coroutines.cpp:109:13:109:13 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| file://:0:0:0:0 | CopyValue: ... , ... | Instruction 'CopyValue: ... , ...' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| file://:0:0:0:0 | CopyValue: ... , ... | Instruction 'CopyValue: ... , ...' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
@@ -82,11 +60,6 @@ instructionWithoutSuccessor
|
||||
| file://:0:0:0:0 | CopyValue: ... , ... | Instruction 'CopyValue: ... , ...' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| file://:0:0:0:0 | CopyValue: ... , ... | Instruction 'CopyValue: ... , ...' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| file://:0:0:0:0 | CopyValue: ... , ... | Instruction 'CopyValue: ... , ...' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| file://:0:0:0:0 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| file://:0:0:0:0 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| file://:0:0:0:0 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| file://:0:0:0:0 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| file://:0:0:0:0 | IndirectMayWriteSideEffect: (unnamed local variable) | Instruction 'IndirectMayWriteSideEffect: (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| file://:0:0:0:0 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| file://:0:0:0:0 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| file://:0:0:0:0 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
@@ -113,12 +86,6 @@ instructionWithoutSuccessor
|
||||
| file://:0:0:0:0 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| file://:0:0:0:0 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| file://:0:0:0:0 | IndirectReadSideEffect: (const suspend_always)... | Instruction 'IndirectReadSideEffect: (const suspend_always)...' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| file://:0:0:0:0 | NoOp: label ...: | Instruction 'NoOp: label ...:' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| file://:0:0:0:0 | NoOp: label ...: | Instruction 'NoOp: label ...:' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| file://:0:0:0:0 | NoOp: label ...: | Instruction 'NoOp: label ...:' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| file://:0:0:0:0 | NoOp: label ...: | Instruction 'NoOp: label ...:' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| file://:0:0:0:0 | NoOp: label ...: | Instruction 'NoOp: label ...:' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| file://:0:0:0:0 | NoOp: label ...: | Instruction 'NoOp: label ...:' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
| file://:0:0:0:0 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| file://:0:0:0:0 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| file://:0:0:0:0 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,12 +6,6 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| coroutines.cpp:87:20:87:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:91:21:91:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:95:20:95:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:99:21:99:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:103:20:103:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:108:21:108:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -6,12 +6,6 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| coroutines.cpp:87:20:87:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
|
||||
| coroutines.cpp:91:21:91:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
|
||||
| coroutines.cpp:95:20:95:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
|
||||
| coroutines.cpp:99:21:99:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
|
||||
| coroutines.cpp:103:20:103:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
|
||||
| coroutines.cpp:108:21:108:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -9,25 +9,25 @@ struct S {
|
||||
};
|
||||
|
||||
void unique_ptr_init(S s) {
|
||||
unique_ptr<S> p(new S); //$ussa=dynamic{1}
|
||||
int i = (*p).x; //$ussa=dynamic{1}[0..4)<int>
|
||||
*p = s; //$ussa=dynamic{1}[0..4)<S>
|
||||
unique_ptr<S> p(new S); // MISSING: $ussa=dynamic{1}
|
||||
int i = (*p).x; //$ MISSING: ussa=dynamic{1}[0..4)<int>
|
||||
*p = s; //$ MISSING: ussa=dynamic{1}[0..4)<S>
|
||||
unique_ptr<S> q = std::move(p);
|
||||
*(q.get()) = s; //$ussa=dynamic{1}[0..4)<S>
|
||||
*(q.get()) = s; //$ MISSING: ussa=dynamic{1}[0..4)<S>
|
||||
shared_ptr<S> t(std::move(q));
|
||||
t->x = 5; //$ussa=dynamic{1}[0..4)<int>
|
||||
*t = s; //$ussa=dynamic{1}[0..4)<S>
|
||||
*(t.get()) = s; //$ussa=dynamic{1}[0..4)<S>
|
||||
t->x = 5; //$ MISSING: ussa=dynamic{1}[0..4)<int>
|
||||
*t = s; //$ MISSING: ussa=dynamic{1}[0..4)<S>
|
||||
*(t.get()) = s; //$ MISSING: ussa=dynamic{1}[0..4)<S>
|
||||
}
|
||||
|
||||
void shared_ptr_init(S s) {
|
||||
shared_ptr<S> p(new S); //$ussa=dynamic{1}
|
||||
int i = (*p).x; //$ussa=dynamic{1}[0..4)<int>
|
||||
*p = s; //$ussa=dynamic{1}[0..4)<S>
|
||||
shared_ptr<S> p(new S); //$ MISSING: ussa=dynamic{1}
|
||||
int i = (*p).x; //$ MISSING: ussa=dynamic{1}[0..4)<int>
|
||||
*p = s; //$ MISSING: ussa=dynamic{1}[0..4)<S>
|
||||
shared_ptr<S> q = std::move(p);
|
||||
*(q.get()) = s; //$ussa=dynamic{1}[0..4)<S>
|
||||
*(q.get()) = s; //$ MISSING: ussa=dynamic{1}[0..4)<S>
|
||||
shared_ptr<S> t(q);
|
||||
t->x = 5; //$ussa=dynamic{1}[0..4)<int>
|
||||
*t = s; //$ussa=dynamic{1}[0..4)<S>
|
||||
*(t.get()) = s; //$ussa=dynamic{1}[0..4)<S>
|
||||
t->x = 5; //$ MISSING: ussa=dynamic{1}[0..4)<int>
|
||||
*t = s; //$ MISSING: ussa=dynamic{1}[0..4)<S>
|
||||
*(t.get()) = s; //$ MISSING: ussa=dynamic{1}[0..4)<S>
|
||||
}
|
||||
|
||||
@@ -499,6 +499,7 @@ ssa.cpp:
|
||||
# 95| m95_4(unknown) = Chi : total:m95_2, partial:m95_3
|
||||
# 95| r95_5(glval<Point>) = VariableAddress[a] :
|
||||
# 95| m95_6(Point) = InitializeParameter[a] : &:r95_5
|
||||
# 95| m95_7(unknown) = Chi : total:m95_4, partial:m95_6
|
||||
# 96| r96_1(glval<Point>) = VariableAddress[b] :
|
||||
# 96| r96_2(glval<Point>) = VariableAddress[a] :
|
||||
# 96| r96_3(Point) = Load[a] : &:r96_2, m95_6
|
||||
@@ -508,15 +509,15 @@ ssa.cpp:
|
||||
# 97| r97_3(Point *) = CopyValue : r97_2
|
||||
# 97| r97_4(void *) = Convert : r97_3
|
||||
# 97| v97_5(void) = Call[Escape] : func:r97_1, 0:r97_4
|
||||
# 97| m97_6(unknown) = ^CallSideEffect : ~m95_4
|
||||
# 97| m97_7(unknown) = Chi : total:m95_4, partial:m97_6
|
||||
# 97| v97_8(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m95_6
|
||||
# 97| m97_6(unknown) = ^CallSideEffect : ~m95_7
|
||||
# 97| m97_7(unknown) = Chi : total:m95_7, partial:m97_6
|
||||
# 97| v97_8(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m97_7
|
||||
# 97| m97_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r97_4
|
||||
# 97| m97_10(Point) = Chi : total:m95_6, partial:m97_9
|
||||
# 97| m97_10(unknown) = Chi : total:m97_7, partial:m97_9
|
||||
# 98| v98_1(void) = NoOp :
|
||||
# 95| v95_7(void) = ReturnVoid :
|
||||
# 95| v95_8(void) = AliasedUse : ~m97_7
|
||||
# 95| v95_9(void) = ExitFunction :
|
||||
# 95| v95_8(void) = ReturnVoid :
|
||||
# 95| v95_9(void) = AliasedUse : ~m97_7
|
||||
# 95| v95_10(void) = ExitFunction :
|
||||
|
||||
# 100| void MustTotallyOverlap(Point)
|
||||
# 100| Block 0
|
||||
@@ -549,6 +550,7 @@ ssa.cpp:
|
||||
# 105| m105_4(unknown) = Chi : total:m105_2, partial:m105_3
|
||||
# 105| r105_5(glval<Point>) = VariableAddress[a] :
|
||||
# 105| m105_6(Point) = InitializeParameter[a] : &:r105_5
|
||||
# 105| m105_7(unknown) = Chi : total:m105_4, partial:m105_6
|
||||
# 106| r106_1(glval<int>) = VariableAddress[x] :
|
||||
# 106| r106_2(glval<Point>) = VariableAddress[a] :
|
||||
# 106| r106_3(glval<int>) = FieldAddress[x] : r106_2
|
||||
@@ -564,15 +566,15 @@ ssa.cpp:
|
||||
# 108| r108_3(Point *) = CopyValue : r108_2
|
||||
# 108| r108_4(void *) = Convert : r108_3
|
||||
# 108| v108_5(void) = Call[Escape] : func:r108_1, 0:r108_4
|
||||
# 108| m108_6(unknown) = ^CallSideEffect : ~m105_4
|
||||
# 108| m108_7(unknown) = Chi : total:m105_4, partial:m108_6
|
||||
# 108| v108_8(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m105_6
|
||||
# 108| m108_6(unknown) = ^CallSideEffect : ~m105_7
|
||||
# 108| m108_7(unknown) = Chi : total:m105_7, partial:m108_6
|
||||
# 108| v108_8(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m108_7
|
||||
# 108| m108_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r108_4
|
||||
# 108| m108_10(Point) = Chi : total:m105_6, partial:m108_9
|
||||
# 108| m108_10(unknown) = Chi : total:m108_7, partial:m108_9
|
||||
# 109| v109_1(void) = NoOp :
|
||||
# 105| v105_7(void) = ReturnVoid :
|
||||
# 105| v105_8(void) = AliasedUse : ~m108_7
|
||||
# 105| v105_9(void) = ExitFunction :
|
||||
# 105| v105_8(void) = ReturnVoid :
|
||||
# 105| v105_9(void) = AliasedUse : ~m108_7
|
||||
# 105| v105_10(void) = ExitFunction :
|
||||
|
||||
# 111| void MayPartiallyOverlap(int, int)
|
||||
# 111| Block 0
|
||||
@@ -617,30 +619,31 @@ ssa.cpp:
|
||||
# 116| m116_8(int) = InitializeParameter[y] : &:r116_7
|
||||
# 117| r117_1(glval<Point>) = VariableAddress[a] :
|
||||
# 117| m117_2(Point) = Uninitialized[a] : &:r117_1
|
||||
# 117| r117_3(glval<int>) = FieldAddress[x] : r117_1
|
||||
# 117| r117_4(glval<int>) = VariableAddress[x] :
|
||||
# 117| r117_5(int) = Load[x] : &:r117_4, m116_6
|
||||
# 117| m117_6(int) = Store[?] : &:r117_3, r117_5
|
||||
# 117| m117_7(Point) = Chi : total:m117_2, partial:m117_6
|
||||
# 117| r117_8(glval<int>) = FieldAddress[y] : r117_1
|
||||
# 117| r117_9(glval<int>) = VariableAddress[y] :
|
||||
# 117| r117_10(int) = Load[y] : &:r117_9, m116_8
|
||||
# 117| m117_11(int) = Store[?] : &:r117_8, r117_10
|
||||
# 117| m117_12(Point) = Chi : total:m117_7, partial:m117_11
|
||||
# 117| m117_3(unknown) = Chi : total:m116_4, partial:m117_2
|
||||
# 117| r117_4(glval<int>) = FieldAddress[x] : r117_1
|
||||
# 117| r117_5(glval<int>) = VariableAddress[x] :
|
||||
# 117| r117_6(int) = Load[x] : &:r117_5, m116_6
|
||||
# 117| m117_7(int) = Store[?] : &:r117_4, r117_6
|
||||
# 117| m117_8(unknown) = Chi : total:m117_3, partial:m117_7
|
||||
# 117| r117_9(glval<int>) = FieldAddress[y] : r117_1
|
||||
# 117| r117_10(glval<int>) = VariableAddress[y] :
|
||||
# 117| r117_11(int) = Load[y] : &:r117_10, m116_8
|
||||
# 117| m117_12(int) = Store[?] : &:r117_9, r117_11
|
||||
# 117| m117_13(unknown) = Chi : total:m117_8, partial:m117_12
|
||||
# 118| r118_1(glval<Point>) = VariableAddress[b] :
|
||||
# 118| r118_2(glval<Point>) = VariableAddress[a] :
|
||||
# 118| r118_3(Point) = Load[a] : &:r118_2, m117_12
|
||||
# 118| r118_3(Point) = Load[a] : &:r118_2, ~m117_13
|
||||
# 118| m118_4(Point) = Store[b] : &:r118_1, r118_3
|
||||
# 119| r119_1(glval<unknown>) = FunctionAddress[Escape] :
|
||||
# 119| r119_2(glval<Point>) = VariableAddress[a] :
|
||||
# 119| r119_3(Point *) = CopyValue : r119_2
|
||||
# 119| r119_4(void *) = Convert : r119_3
|
||||
# 119| v119_5(void) = Call[Escape] : func:r119_1, 0:r119_4
|
||||
# 119| m119_6(unknown) = ^CallSideEffect : ~m116_4
|
||||
# 119| m119_7(unknown) = Chi : total:m116_4, partial:m119_6
|
||||
# 119| v119_8(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m117_12
|
||||
# 119| m119_6(unknown) = ^CallSideEffect : ~m117_13
|
||||
# 119| m119_7(unknown) = Chi : total:m117_13, partial:m119_6
|
||||
# 119| v119_8(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m119_7
|
||||
# 119| m119_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r119_4
|
||||
# 119| m119_10(Point) = Chi : total:m117_12, partial:m119_9
|
||||
# 119| m119_10(unknown) = Chi : total:m119_7, partial:m119_9
|
||||
# 120| v120_1(void) = NoOp :
|
||||
# 116| v116_9(void) = ReturnVoid :
|
||||
# 116| v116_10(void) = AliasedUse : ~m119_7
|
||||
@@ -946,40 +949,42 @@ ssa.cpp:
|
||||
# 184| m184_6(unsigned int &) = InitializeParameter[a] : &:r184_5
|
||||
# 184| r184_7(unsigned int &) = Load[a] : &:r184_5, m184_6
|
||||
# 184| m184_8(unknown) = InitializeIndirection[a] : &:r184_7
|
||||
# 184| r184_9(glval<unsigned int &>) = VariableAddress[b] :
|
||||
# 184| m184_10(unsigned int &) = InitializeParameter[b] : &:r184_9
|
||||
# 184| r184_11(unsigned int &) = Load[b] : &:r184_9, m184_10
|
||||
# 184| m184_12(unknown) = InitializeIndirection[b] : &:r184_11
|
||||
# 184| r184_13(glval<unsigned int &>) = VariableAddress[c] :
|
||||
# 184| m184_14(unsigned int &) = InitializeParameter[c] : &:r184_13
|
||||
# 184| r184_15(unsigned int &) = Load[c] : &:r184_13, m184_14
|
||||
# 184| m184_16(unknown) = InitializeIndirection[c] : &:r184_15
|
||||
# 184| r184_17(glval<unsigned int &>) = VariableAddress[d] :
|
||||
# 184| m184_18(unsigned int &) = InitializeParameter[d] : &:r184_17
|
||||
# 184| r184_19(unsigned int &) = Load[d] : &:r184_17, m184_18
|
||||
# 184| m184_20(unknown) = InitializeIndirection[d] : &:r184_19
|
||||
# 184| m184_9(unknown) = Chi : total:m184_4, partial:m184_8
|
||||
# 184| r184_10(glval<unsigned int &>) = VariableAddress[b] :
|
||||
# 184| m184_11(unsigned int &) = InitializeParameter[b] : &:r184_10
|
||||
# 184| r184_12(unsigned int &) = Load[b] : &:r184_10, m184_11
|
||||
# 184| m184_13(unknown) = InitializeIndirection[b] : &:r184_12
|
||||
# 184| m184_14(unknown) = Chi : total:m184_9, partial:m184_13
|
||||
# 184| r184_15(glval<unsigned int &>) = VariableAddress[c] :
|
||||
# 184| m184_16(unsigned int &) = InitializeParameter[c] : &:r184_15
|
||||
# 184| r184_17(unsigned int &) = Load[c] : &:r184_15, m184_16
|
||||
# 184| m184_18(unknown) = InitializeIndirection[c] : &:r184_17
|
||||
# 184| r184_19(glval<unsigned int &>) = VariableAddress[d] :
|
||||
# 184| m184_20(unsigned int &) = InitializeParameter[d] : &:r184_19
|
||||
# 184| r184_21(unsigned int &) = Load[d] : &:r184_19, m184_20
|
||||
# 184| m184_22(unknown) = InitializeIndirection[d] : &:r184_21
|
||||
# 189| r189_1(glval<unsigned int &>) = VariableAddress[a] :
|
||||
# 189| r189_2(unsigned int &) = Load[a] : &:r189_1, m184_6
|
||||
# 189| r189_3(glval<unsigned int>) = CopyValue : r189_2
|
||||
# 189| r189_4(glval<unsigned int &>) = VariableAddress[b] :
|
||||
# 189| r189_5(unsigned int &) = Load[b] : &:r189_4, m184_10
|
||||
# 189| r189_5(unsigned int &) = Load[b] : &:r189_4, m184_11
|
||||
# 189| r189_6(glval<unsigned int>) = CopyValue : r189_5
|
||||
# 190| r190_1(glval<unsigned int &>) = VariableAddress[c] :
|
||||
# 190| r190_2(unsigned int &) = Load[c] : &:r190_1, m184_14
|
||||
# 190| r190_3(unsigned int) = Load[?] : &:r190_2, ~m184_16
|
||||
# 190| r190_2(unsigned int &) = Load[c] : &:r190_1, m184_16
|
||||
# 190| r190_3(unsigned int) = Load[?] : &:r190_2, ~m184_18
|
||||
# 190| r190_4(glval<unsigned int &>) = VariableAddress[d] :
|
||||
# 190| r190_5(unsigned int &) = Load[d] : &:r190_4, m184_18
|
||||
# 190| r190_6(unsigned int) = Load[?] : &:r190_5, ~m184_20
|
||||
# 186| m186_1(unknown) = InlineAsm : ~m184_4, 0:r189_3, 1:r189_6, 2:r190_3, 3:r190_6
|
||||
# 186| m186_2(unknown) = Chi : total:m184_4, partial:m186_1
|
||||
# 190| r190_5(unsigned int &) = Load[d] : &:r190_4, m184_20
|
||||
# 190| r190_6(unsigned int) = Load[?] : &:r190_5, ~m184_22
|
||||
# 186| m186_1(unknown) = InlineAsm : ~m184_14, 0:r189_3, 1:r189_6, 2:r190_3, 3:r190_6
|
||||
# 186| m186_2(unknown) = Chi : total:m184_14, partial:m186_1
|
||||
# 192| v192_1(void) = NoOp :
|
||||
# 184| v184_21(void) = ReturnIndirection[a] : &:r184_7, m184_8
|
||||
# 184| v184_22(void) = ReturnIndirection[b] : &:r184_11, m184_12
|
||||
# 184| v184_23(void) = ReturnIndirection[c] : &:r184_15, m184_16
|
||||
# 184| v184_24(void) = ReturnIndirection[d] : &:r184_19, m184_20
|
||||
# 184| v184_25(void) = ReturnVoid :
|
||||
# 184| v184_26(void) = AliasedUse : ~m186_2
|
||||
# 184| v184_27(void) = ExitFunction :
|
||||
# 184| v184_23(void) = ReturnIndirection[a] : &:r184_7, ~m186_2
|
||||
# 184| v184_24(void) = ReturnIndirection[b] : &:r184_12, ~m186_2
|
||||
# 184| v184_25(void) = ReturnIndirection[c] : &:r184_17, m184_18
|
||||
# 184| v184_26(void) = ReturnIndirection[d] : &:r184_21, m184_22
|
||||
# 184| v184_27(void) = ReturnVoid :
|
||||
# 184| v184_28(void) = AliasedUse : ~m186_2
|
||||
# 184| v184_29(void) = ExitFunction :
|
||||
|
||||
# 198| int PureFunctions(char*, char*, int)
|
||||
# 198| Block 0
|
||||
@@ -1405,19 +1410,20 @@ ssa.cpp:
|
||||
# 275| m275_10(int) = InitializeParameter[x1] : &:r275_9
|
||||
# 276| r276_1(glval<Point>) = VariableAddress[a] :
|
||||
# 276| m276_2(Point) = Uninitialized[a] : &:r276_1
|
||||
# 276| r276_3(glval<int>) = FieldAddress[x] : r276_1
|
||||
# 276| r276_4(int) = Constant[0] :
|
||||
# 276| m276_5(int) = Store[?] : &:r276_3, r276_4
|
||||
# 276| m276_6(Point) = Chi : total:m276_2, partial:m276_5
|
||||
# 276| r276_7(glval<int>) = FieldAddress[y] : r276_1
|
||||
# 276| r276_8(int) = Constant[0] :
|
||||
# 276| m276_9(int) = Store[?] : &:r276_7, r276_8
|
||||
# 276| m276_10(Point) = Chi : total:m276_6, partial:m276_9
|
||||
# 276| m276_3(unknown) = Chi : total:m275_4, partial:m276_2
|
||||
# 276| r276_4(glval<int>) = FieldAddress[x] : r276_1
|
||||
# 276| r276_5(int) = Constant[0] :
|
||||
# 276| m276_6(int) = Store[?] : &:r276_4, r276_5
|
||||
# 276| m276_7(unknown) = Chi : total:m276_3, partial:m276_6
|
||||
# 276| r276_8(glval<int>) = FieldAddress[y] : r276_1
|
||||
# 276| r276_9(int) = Constant[0] :
|
||||
# 276| m276_10(int) = Store[?] : &:r276_8, r276_9
|
||||
# 276| m276_11(unknown) = Chi : total:m276_7, partial:m276_10
|
||||
# 277| r277_1(glval<Point>) = VariableAddress[a] :
|
||||
# 277| r277_2(Point *) = CopyValue : r277_1
|
||||
# 277| r277_3(glval<Point *>) = VariableAddress[pp] :
|
||||
# 277| m277_4(Point *) = Store[pp] : &:r277_3, r277_2
|
||||
# 277| m277_5(unknown) = Chi : total:m275_4, partial:m277_4
|
||||
# 277| m277_5(unknown) = Chi : total:m276_11, partial:m277_4
|
||||
# 278| r278_1(glval<bool>) = VariableAddress[c] :
|
||||
# 278| r278_2(bool) = Load[c] : &:r278_1, m275_6
|
||||
# 278| v278_3(void) = ConditionalBranch : r278_2
|
||||
@@ -1430,12 +1436,12 @@ ssa.cpp:
|
||||
# 279| r279_3(glval<Point>) = VariableAddress[a] :
|
||||
# 279| r279_4(glval<int>) = FieldAddress[x] : r279_3
|
||||
# 279| m279_5(int) = Store[?] : &:r279_4, r279_2
|
||||
# 279| m279_6(Point) = Chi : total:m276_10, partial:m279_5
|
||||
# 279| m279_6(unknown) = Chi : total:m277_5, partial:m279_5
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 281| Block 2
|
||||
# 281| m281_1(int) = Phi : from 0:m276_5, from 1:m279_5
|
||||
# 281| m281_2(Point) = Phi : from 0:m276_10, from 1:m279_6
|
||||
# 281| m281_1(int) = Phi : from 0:m276_6, from 1:m279_5
|
||||
# 281| m281_2(unknown) = Phi : from 0:~m277_5, from 1:~m279_6
|
||||
# 281| r281_3(glval<int>) = VariableAddress[x] :
|
||||
# 281| r281_4(glval<Point>) = VariableAddress[a] :
|
||||
# 281| r281_5(glval<int>) = FieldAddress[x] : r281_4
|
||||
@@ -1443,7 +1449,7 @@ ssa.cpp:
|
||||
# 281| m281_7(int) = Store[x] : &:r281_3, r281_6
|
||||
# 282| v282_1(void) = NoOp :
|
||||
# 275| v275_11(void) = ReturnVoid :
|
||||
# 275| v275_12(void) = AliasedUse : ~m277_5
|
||||
# 275| v275_12(void) = AliasedUse : ~m281_2
|
||||
# 275| v275_13(void) = ExitFunction :
|
||||
|
||||
# 286| void A::A(int)
|
||||
@@ -1598,40 +1604,41 @@ ssa.cpp:
|
||||
# 301| m301_8(char **) = InitializeParameter[argv] : &:r301_7
|
||||
# 301| r301_9(char **) = Load[argv] : &:r301_7, m301_8
|
||||
# 301| m301_10(unknown) = InitializeIndirection[argv] : &:r301_9
|
||||
# 301| m301_11(unknown) = Chi : total:m301_4, partial:m301_10
|
||||
# 302| r302_1(glval<unknown>) = FunctionAddress[unknownFunction] :
|
||||
# 302| r302_2(glval<int>) = VariableAddress[argc] :
|
||||
# 302| r302_3(int) = Load[argc] : &:r302_2, m301_6
|
||||
# 302| r302_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 302| r302_5(char **) = Load[argv] : &:r302_4, m301_8
|
||||
# 302| v302_6(void) = Call[unknownFunction] : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| m302_7(unknown) = ^CallSideEffect : ~m301_4
|
||||
# 302| m302_8(unknown) = Chi : total:m301_4, partial:m302_7
|
||||
# 302| v302_9(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m301_10
|
||||
# 302| m302_7(unknown) = ^CallSideEffect : ~m301_11
|
||||
# 302| m302_8(unknown) = Chi : total:m301_11, partial:m302_7
|
||||
# 302| v302_9(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m302_8
|
||||
# 302| m302_10(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5
|
||||
# 302| m302_11(unknown) = Chi : total:m301_10, partial:m302_10
|
||||
# 302| m302_11(unknown) = Chi : total:m302_8, partial:m302_10
|
||||
# 303| r303_1(glval<unknown>) = FunctionAddress[unknownFunction] :
|
||||
# 303| r303_2(glval<int>) = VariableAddress[argc] :
|
||||
# 303| r303_3(int) = Load[argc] : &:r303_2, m301_6
|
||||
# 303| r303_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 303| r303_5(char **) = Load[argv] : &:r303_4, m301_8
|
||||
# 303| v303_6(void) = Call[unknownFunction] : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| m303_7(unknown) = ^CallSideEffect : ~m302_8
|
||||
# 303| m303_8(unknown) = Chi : total:m302_8, partial:m303_7
|
||||
# 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m302_11
|
||||
# 303| m303_7(unknown) = ^CallSideEffect : ~m302_11
|
||||
# 303| m303_8(unknown) = Chi : total:m302_11, partial:m303_7
|
||||
# 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m303_8
|
||||
# 303| m303_10(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5
|
||||
# 303| m303_11(unknown) = Chi : total:m302_11, partial:m303_10
|
||||
# 303| m303_11(unknown) = Chi : total:m303_8, partial:m303_10
|
||||
# 304| r304_1(glval<int>) = VariableAddress[#return] :
|
||||
# 304| r304_2(glval<char **>) = VariableAddress[argv] :
|
||||
# 304| r304_3(char **) = Load[argv] : &:r304_2, m301_8
|
||||
# 304| r304_4(char *) = Load[?] : &:r304_3, ~m303_11
|
||||
# 304| r304_5(char) = Load[?] : &:r304_4, ~m303_8
|
||||
# 304| r304_5(char) = Load[?] : &:r304_4, ~m303_11
|
||||
# 304| r304_6(int) = Convert : r304_5
|
||||
# 304| m304_7(int) = Store[#return] : &:r304_1, r304_6
|
||||
# 301| v301_11(void) = ReturnIndirection[argv] : &:r301_9, m303_11
|
||||
# 301| r301_12(glval<int>) = VariableAddress[#return] :
|
||||
# 301| v301_13(void) = ReturnValue : &:r301_12, m304_7
|
||||
# 301| v301_14(void) = AliasedUse : ~m303_8
|
||||
# 301| v301_15(void) = ExitFunction :
|
||||
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_9, ~m303_11
|
||||
# 301| r301_13(glval<int>) = VariableAddress[#return] :
|
||||
# 301| v301_14(void) = ReturnValue : &:r301_13, m304_7
|
||||
# 301| v301_15(void) = AliasedUse : ~m303_11
|
||||
# 301| v301_16(void) = ExitFunction :
|
||||
|
||||
# 310| void ThisAliasTest::setX(int)
|
||||
# 310| Block 0
|
||||
@@ -1670,10 +1677,12 @@ ssa.cpp:
|
||||
# 319| m319_8(unknown) = InitializeIndirection[s] : &:r319_7
|
||||
# 321| r321_1(glval<char[1024]>) = VariableAddress[buffer] :
|
||||
# 321| m321_2(char[1024]) = Uninitialized[buffer] : &:r321_1
|
||||
# 321| m321_3(unknown) = Chi : total:m319_4, partial:m321_2
|
||||
# 322| r322_1(glval<char *>) = VariableAddress[ptr1] :
|
||||
# 322| m322_2(char *) = Uninitialized[ptr1] : &:r322_1
|
||||
# 322| r322_3(glval<char **>) = VariableAddress[ptr2] :
|
||||
# 322| m322_4(char **) = Uninitialized[ptr2] : &:r322_3
|
||||
# 322| m322_3(unknown) = Chi : total:m321_3, partial:m322_2
|
||||
# 322| r322_4(glval<char **>) = VariableAddress[ptr2] :
|
||||
# 322| m322_5(char **) = Uninitialized[ptr2] : &:r322_4
|
||||
# 323| r323_1(glval<char *>) = VariableAddress[ptr3] :
|
||||
# 323| m323_2(char *) = Uninitialized[ptr3] : &:r323_1
|
||||
# 323| r323_3(glval<char **>) = VariableAddress[ptr4] :
|
||||
@@ -1682,6 +1691,7 @@ ssa.cpp:
|
||||
# 325| r325_2(char *) = Convert : r325_1
|
||||
# 325| r325_3(glval<char *>) = VariableAddress[ptr1] :
|
||||
# 325| m325_4(char *) = Store[ptr1] : &:r325_3, r325_2
|
||||
# 325| m325_5(unknown) = Chi : total:m322_3, partial:m325_4
|
||||
# 326| r326_1(glval<char *>) = VariableAddress[ptr1] :
|
||||
# 326| r326_2(char **) = CopyValue : r326_1
|
||||
# 326| r326_3(glval<char **>) = VariableAddress[ptr2] :
|
||||
@@ -1698,22 +1708,22 @@ ssa.cpp:
|
||||
# 327| r327_10(void *) = Call[memcpy] : func:r327_1, 0:r327_5, 1:r327_8, 2:r327_9
|
||||
# 327| v327_11(void) = ^SizedBufferReadSideEffect[1] : &:r327_8, r327_9, ~m319_8
|
||||
# 327| m327_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r327_5, r327_9
|
||||
# 327| m327_13(unknown) = Chi : total:m319_4, partial:m327_12
|
||||
# 327| m327_13(unknown) = Chi : total:m325_5, partial:m327_12
|
||||
# 329| r329_1(glval<unknown>) = FunctionAddress[sink] :
|
||||
# 329| r329_2(glval<char[1024]>) = VariableAddress[buffer] :
|
||||
# 329| r329_3(char *) = Convert : r329_2
|
||||
# 329| v329_4(void) = Call[sink] : func:r329_1, 0:r329_3
|
||||
# 329| m329_5(unknown) = ^CallSideEffect : ~m327_13
|
||||
# 329| m329_6(unknown) = Chi : total:m327_13, partial:m329_5
|
||||
# 329| v329_7(void) = ^BufferReadSideEffect[0] : &:r329_3, ~m321_2
|
||||
# 329| v329_7(void) = ^BufferReadSideEffect[0] : &:r329_3, ~m329_6
|
||||
# 329| m329_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r329_3
|
||||
# 329| m329_9(char[1024]) = Chi : total:m321_2, partial:m329_8
|
||||
# 329| m329_9(unknown) = Chi : total:m329_6, partial:m329_8
|
||||
# 330| r330_1(glval<unknown>) = FunctionAddress[sink] :
|
||||
# 330| r330_2(glval<char *>) = VariableAddress[ptr1] :
|
||||
# 330| r330_3(char *) = Load[ptr1] : &:r330_2, m325_4
|
||||
# 330| r330_3(char *) = Load[ptr1] : &:r330_2, ~m329_6
|
||||
# 330| v330_4(void) = Call[sink] : func:r330_1, 0:r330_3
|
||||
# 330| m330_5(unknown) = ^CallSideEffect : ~m329_6
|
||||
# 330| m330_6(unknown) = Chi : total:m329_6, partial:m330_5
|
||||
# 330| m330_5(unknown) = ^CallSideEffect : ~m329_9
|
||||
# 330| m330_6(unknown) = Chi : total:m329_9, partial:m330_5
|
||||
# 330| v330_7(void) = ^BufferReadSideEffect[0] : &:r330_3, ~m330_6
|
||||
# 330| m330_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r330_3
|
||||
# 330| m330_9(unknown) = Chi : total:m330_6, partial:m330_8
|
||||
@@ -1723,16 +1733,16 @@ ssa.cpp:
|
||||
# 331| v331_4(void) = Call[sink] : func:r331_1, 0:r331_3
|
||||
# 331| m331_5(unknown) = ^CallSideEffect : ~m330_9
|
||||
# 331| m331_6(unknown) = Chi : total:m330_9, partial:m331_5
|
||||
# 331| v331_7(void) = ^BufferReadSideEffect[0] : &:r331_3, ~m325_4
|
||||
# 331| v331_7(void) = ^BufferReadSideEffect[0] : &:r331_3, ~m331_6
|
||||
# 331| m331_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r331_3
|
||||
# 331| m331_9(char *) = Chi : total:m325_4, partial:m331_8
|
||||
# 331| m331_9(unknown) = Chi : total:m331_6, partial:m331_8
|
||||
# 332| r332_1(glval<unknown>) = FunctionAddress[sink] :
|
||||
# 332| r332_2(glval<char **>) = VariableAddress[ptr2] :
|
||||
# 332| r332_3(char **) = Load[ptr2] : &:r332_2, m326_4
|
||||
# 332| r332_4(char *) = Load[?] : &:r332_3, m331_9
|
||||
# 332| r332_4(char *) = Load[?] : &:r332_3, ~m331_9
|
||||
# 332| v332_5(void) = Call[sink] : func:r332_1, 0:r332_4
|
||||
# 332| m332_6(unknown) = ^CallSideEffect : ~m331_6
|
||||
# 332| m332_7(unknown) = Chi : total:m331_6, partial:m332_6
|
||||
# 332| m332_6(unknown) = ^CallSideEffect : ~m331_9
|
||||
# 332| m332_7(unknown) = Chi : total:m331_9, partial:m332_6
|
||||
# 332| v332_8(void) = ^BufferReadSideEffect[0] : &:r332_4, ~m332_7
|
||||
# 332| m332_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r332_4
|
||||
# 332| m332_10(unknown) = Chi : total:m332_7, partial:m332_9
|
||||
@@ -1988,11 +1998,12 @@ ssa.cpp:
|
||||
# 402| v402_5(void) = NoOp :
|
||||
# 403| r403_1(glval<int[][]>) = VariableAddress[c] :
|
||||
# 403| m403_2(int[][]) = Uninitialized[c] : &:r403_1
|
||||
# 403| r403_3(glval<int>) = VariableAddress[n1] :
|
||||
# 403| r403_4(int) = Load[n1] : &:r403_3, m401_6
|
||||
# 403| r403_5(glval<int>) = VariableAddress[n2] :
|
||||
# 403| r403_6(int) = Load[n2] : &:r403_5, m401_8
|
||||
# 403| v403_7(void) = NoOp :
|
||||
# 403| m403_3(unknown) = Chi : total:m401_4, partial:m403_2
|
||||
# 403| r403_4(glval<int>) = VariableAddress[n1] :
|
||||
# 403| r403_5(int) = Load[n1] : &:r403_4, m401_6
|
||||
# 403| r403_6(glval<int>) = VariableAddress[n2] :
|
||||
# 403| r403_7(int) = Load[n2] : &:r403_6, m401_8
|
||||
# 403| v403_8(void) = NoOp :
|
||||
# 405| r405_1(int) = Constant[0] :
|
||||
# 405| r405_2(glval<int[]>) = VariableAddress[b] :
|
||||
# 405| r405_3(int *) = Convert : r405_2
|
||||
@@ -2015,7 +2026,7 @@ ssa.cpp:
|
||||
# 408| r408_7(int *) = Convert : r408_6
|
||||
# 408| r408_8(glval<int>) = CopyValue : r408_7
|
||||
# 408| m408_9(int) = Store[?] : &:r408_8, r408_1
|
||||
# 408| m408_10(unknown) = Chi : total:m401_4, partial:m408_9
|
||||
# 408| m408_10(unknown) = Chi : total:m403_3, partial:m408_9
|
||||
# 410| r410_1(glval<bool>) = VariableAddress[b1] :
|
||||
# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_12
|
||||
# 410| v410_3(void) = ConditionalBranch : r410_2
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| file://:0:0:0:0 | __wchar_t * | IteratorByPointer, PointerType | Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | __wchar_t * | IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | const __wchar_t | SpecifiedType | Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | wchar_t | Wchar_t, WideCharType | |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| file://:0:0:0:0 | wchar_t | Wchar_t, WideCharType | |
|
||||
| file://:0:0:0:0 | wchar_t * | IteratorByPointer, PointerType | CTypedefType, Wchar_t |
|
||||
| file://:0:0:0:0 | wchar_t * | IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | CTypedefType, Wchar_t |
|
||||
| ms.c:2:24:2:30 | wchar_t | CTypedefType, Wchar_t | |
|
||||
|
||||
@@ -27,59 +27,59 @@
|
||||
| __fp16 | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| __int128 | Int128Type | | | | |
|
||||
| __va_list_tag | DirectAccessHolder, MetricClass, Struct, StructLikeClass | | | | |
|
||||
| __va_list_tag & | LValueReferenceType | | __va_list_tag | | |
|
||||
| __va_list_tag && | RValueReferenceType | | __va_list_tag | | |
|
||||
| __va_list_tag & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | __va_list_tag | | |
|
||||
| __va_list_tag && | PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, RValueReferenceType | | __va_list_tag | | |
|
||||
| address | DirectAccessHolder, MetricClass, Struct, StructLikeClass | | | | |
|
||||
| address & | LValueReferenceType | | address | | |
|
||||
| address && | RValueReferenceType | | address | | |
|
||||
| address & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | address | | |
|
||||
| address && | PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, RValueReferenceType | | address | | |
|
||||
| auto | AutoType | | | | |
|
||||
| bool | BoolType | | | | |
|
||||
| char | MicrosoftInt8Type, PlainCharType | | | | |
|
||||
| char8_t | Char8Type | | | | |
|
||||
| char16_t | Char16Type | | | | |
|
||||
| char32_t | Char32Type | | | | |
|
||||
| char * | CharPointerType, IteratorByPointer | | char | | |
|
||||
| char *[3] | ArrayType | char * | char * | | |
|
||||
| char *[32] | ArrayType | char * | char * | | |
|
||||
| char *[] | ArrayType | char * | char * | | |
|
||||
| char[2] | ArrayType | char | char | | |
|
||||
| char[3] | ArrayType | char | char | | |
|
||||
| char[5] | ArrayType | char | char | | |
|
||||
| char[6] | ArrayType | char | char | | |
|
||||
| char[8] | ArrayType | char | char | | |
|
||||
| char[9] | ArrayType | char | char | | |
|
||||
| char[10] | ArrayType | char | char | | |
|
||||
| char[53] | ArrayType | char | char | | |
|
||||
| char[] | ArrayType | char | char | | |
|
||||
| char * | CharPointerType, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | char | | |
|
||||
| char *[3] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | |
|
||||
| char *[32] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | |
|
||||
| char *[] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | |
|
||||
| char[2] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| char[3] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| char[5] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| char[6] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| char[8] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| char[9] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| char[10] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| char[53] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| char[] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | |
|
||||
| const __va_list_tag | SpecifiedType | | __va_list_tag | | |
|
||||
| const __va_list_tag & | LValueReferenceType | | const __va_list_tag | | |
|
||||
| const __va_list_tag & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | const __va_list_tag | | |
|
||||
| const address | SpecifiedType | | address | | |
|
||||
| const address & | LValueReferenceType | | const address | | |
|
||||
| const address & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | const address | | |
|
||||
| const char | SpecifiedType | | char | | |
|
||||
| const char * | IteratorByPointer, PointerType | | const char | | |
|
||||
| const char *[3] | ArrayType | const char * | const char * | | |
|
||||
| const char *[] | ArrayType | const char * | const char * | | |
|
||||
| const char[5] | ArrayType | const char | const char | | |
|
||||
| const char[6] | ArrayType | const char | const char | | |
|
||||
| const char[8] | ArrayType | const char | const char | | |
|
||||
| const char[9] | ArrayType | const char | const char | | |
|
||||
| const char[10] | ArrayType | const char | const char | | |
|
||||
| const char[53] | ArrayType | const char | const char | | |
|
||||
| const char * | IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | | const char | | |
|
||||
| const char *[3] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char * | const char * | | |
|
||||
| const char *[] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char * | const char * | | |
|
||||
| const char[5] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | |
|
||||
| const char[6] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | |
|
||||
| const char[8] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | |
|
||||
| const char[9] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | |
|
||||
| const char[10] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | |
|
||||
| const char[53] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | |
|
||||
| const double | SpecifiedType | | double | | |
|
||||
| const int | SpecifiedType | | int | | |
|
||||
| decltype(nullptr) | NullPointerType | | | | |
|
||||
| double | DoubleType | | | | |
|
||||
| error | ErroneousType | | | | |
|
||||
| float | FloatType | | | | |
|
||||
| float[3] | ArrayType | float | float | | |
|
||||
| float[3] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | float | float | | |
|
||||
| int | IntType, MicrosoftInt32Type | | | | |
|
||||
| int * | IntPointerType, IteratorByPointer | | int | | |
|
||||
| int[4] | ArrayType | int | int | | |
|
||||
| int[8] | ArrayType | int | int | | |
|
||||
| int[10] | ArrayType | int | int | | |
|
||||
| int[10][20] | ArrayType | int[20] | int[20] | | |
|
||||
| int[20] | ArrayType | int | int | | |
|
||||
| int[] | ArrayType | int | int | | |
|
||||
| int * | IntPointerType, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | int | | |
|
||||
| int[4] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | |
|
||||
| int[8] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | |
|
||||
| int[10] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | |
|
||||
| int[10][20] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int[20] | int[20] | | |
|
||||
| int[20] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | |
|
||||
| int[] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | |
|
||||
| long | LongType | | | | |
|
||||
| long double | LongDoubleType | | | | |
|
||||
| long long | LongLongType, MicrosoftInt64Type | | | | |
|
||||
@@ -99,5 +99,5 @@
|
||||
| unsigned long long | LongLongType | | | | unsigned integral |
|
||||
| unsigned short | ShortType | | | | unsigned integral |
|
||||
| void | VoidType | | | | |
|
||||
| void * | IteratorByPointer, VoidPointerType | | void | | |
|
||||
| void * | IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, VoidPointerType | | void | | |
|
||||
| wchar_t | Wchar_t, WideCharType | | | | |
|
||||
|
||||
@@ -6,64 +6,36 @@
|
||||
| file://:0:0:0:0 | gp_offset | file://:0:0:0:0 | unsigned int | Field | | |
|
||||
| file://:0:0:0:0 | overflow_arg_area | file://:0:0:0:0 | void * | Field | | |
|
||||
| file://:0:0:0:0 | reg_save_area | file://:0:0:0:0 | void * | Field | | |
|
||||
| variables.cpp:1:12:1:12 | i | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:1:12:1:12 | i | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:2:12:2:12 | i | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:2:12:2:12 | i | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:3:12:3:12 | i | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:3:12:3:12 | i | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:5:11:5:11 | c | file://:0:0:0:0 | const int | GlobalVariable | const | static |
|
||||
| variables.cpp:5:11:5:11 | c | file://:0:0:0:0 | const int | StaticStorageDurationVariable | const | static |
|
||||
| variables.cpp:6:14:6:15 | pi | file://:0:0:0:0 | const double | GlobalVariable | const | static |
|
||||
| variables.cpp:6:14:6:15 | pi | file://:0:0:0:0 | const double | StaticStorageDurationVariable | const | static |
|
||||
| variables.cpp:8:10:8:10 | a | file://:0:0:0:0 | unsigned int | GlobalVariable | | |
|
||||
| variables.cpp:8:10:8:10 | a | file://:0:0:0:0 | unsigned int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:10:14:10:14 | b | file://:0:0:0:0 | unsigned int | GlobalVariable | | |
|
||||
| variables.cpp:10:14:10:14 | b | file://:0:0:0:0 | unsigned int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:12:13:12:17 | kings | file://:0:0:0:0 | const char *[] | GlobalVariable | | |
|
||||
| variables.cpp:12:13:12:17 | kings | file://:0:0:0:0 | const char *[] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:14:6:14:6 | p | file://:0:0:0:0 | int * | GlobalVariable | | |
|
||||
| variables.cpp:14:6:14:6 | p | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:14:9:14:9 | q | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:14:9:14:9 | q | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:15:12:15:13 | v1 | file://:0:0:0:0 | int[10] | GlobalVariable | | static |
|
||||
| variables.cpp:15:12:15:13 | v1 | file://:0:0:0:0 | int[10] | StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | GlobalVariable | | static |
|
||||
| variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | GlobalVariable | | |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:19:7:19:8 | v2 | file://:0:0:0:0 | float[3] | GlobalVariable | | |
|
||||
| variables.cpp:19:7:19:8 | v2 | file://:0:0:0:0 | float[3] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:20:7:20:8 | v3 | file://:0:0:0:0 | char *[32] | GlobalVariable | | |
|
||||
| variables.cpp:20:7:20:8 | v3 | file://:0:0:0:0 | char *[32] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:22:5:22:6 | d2 | file://:0:0:0:0 | int[10][20] | GlobalVariable | | |
|
||||
| variables.cpp:22:5:22:6 | d2 | file://:0:0:0:0 | int[10][20] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:24:6:24:7 | v4 | file://:0:0:0:0 | char[3] | GlobalVariable | | |
|
||||
| variables.cpp:24:6:24:7 | v4 | file://:0:0:0:0 | char[3] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:26:5:26:6 | v5 | file://:0:0:0:0 | int[8] | GlobalVariable | | |
|
||||
| variables.cpp:26:5:26:6 | v5 | file://:0:0:0:0 | int[8] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:28:7:28:8 | p2 | file://:0:0:0:0 | char * | GlobalVariable | | |
|
||||
| variables.cpp:28:7:28:8 | p2 | file://:0:0:0:0 | char * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:29:6:29:7 | p3 | file://:0:0:0:0 | char[] | GlobalVariable | | |
|
||||
| variables.cpp:29:6:29:7 | p3 | file://:0:0:0:0 | char[] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:31:6:31:10 | alpha | file://:0:0:0:0 | char[] | GlobalVariable | | |
|
||||
| variables.cpp:31:6:31:10 | alpha | file://:0:0:0:0 | char[] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:34:5:34:6 | av | file://:0:0:0:0 | int[] | GlobalVariable | | |
|
||||
| variables.cpp:34:5:34:6 | av | file://:0:0:0:0 | int[] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:35:6:35:8 | ap1 | file://:0:0:0:0 | int * | GlobalVariable | | |
|
||||
| variables.cpp:35:6:35:8 | ap1 | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:36:6:36:8 | ap2 | file://:0:0:0:0 | int * | GlobalVariable | | |
|
||||
| variables.cpp:36:6:36:8 | ap2 | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:37:6:37:8 | ap3 | file://:0:0:0:0 | int * | GlobalVariable | | |
|
||||
| variables.cpp:37:6:37:8 | ap3 | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:41:7:41:11 | local | file://:0:0:0:0 | char[] | LocalVariable | | |
|
||||
| variables.cpp:41:7:41:11 | local | file://:0:0:0:0 | char[] | SemanticStackVariable | | |
|
||||
| variables.cpp:43:14:43:18 | local | file://:0:0:0:0 | int | StaticLocalVariable | | static |
|
||||
| variables.cpp:1:12:1:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:2:12:2:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:3:12:3:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:5:11:5:11 | c | file://:0:0:0:0 | const int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | const | static |
|
||||
| variables.cpp:6:14:6:15 | pi | file://:0:0:0:0 | const double | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | const | static |
|
||||
| variables.cpp:8:10:8:10 | a | file://:0:0:0:0 | unsigned int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:10:14:10:14 | b | file://:0:0:0:0 | unsigned int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:12:13:12:17 | kings | file://:0:0:0:0 | const char *[] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:14:6:14:6 | p | file://:0:0:0:0 | int * | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:14:9:14:9 | q | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:15:12:15:13 | v1 | file://:0:0:0:0 | int[10] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:19:7:19:8 | v2 | file://:0:0:0:0 | float[3] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:20:7:20:8 | v3 | file://:0:0:0:0 | char *[32] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:22:5:22:6 | d2 | file://:0:0:0:0 | int[10][20] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:24:6:24:7 | v4 | file://:0:0:0:0 | char[3] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:26:5:26:6 | v5 | file://:0:0:0:0 | int[8] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:28:7:28:8 | p2 | file://:0:0:0:0 | char * | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:29:6:29:7 | p3 | file://:0:0:0:0 | char[] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:31:6:31:10 | alpha | file://:0:0:0:0 | char[] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:34:5:34:6 | av | file://:0:0:0:0 | int[] | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:35:6:35:8 | ap1 | file://:0:0:0:0 | int * | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:36:6:36:8 | ap2 | file://:0:0:0:0 | int * | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:37:6:37:8 | ap3 | file://:0:0:0:0 | int * | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:41:7:41:11 | local | file://:0:0:0:0 | char[] | LocalVariable, SemanticStackVariable | | |
|
||||
| variables.cpp:43:14:43:18 | local | file://:0:0:0:0 | int | GlobalLikeVariable, StaticLocalVariable | | static |
|
||||
| variables.cpp:48:9:48:12 | name | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:49:12:49:17 | number | file://:0:0:0:0 | long | Field | | |
|
||||
| variables.cpp:50:9:50:14 | street | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:51:9:51:12 | town | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:52:16:52:22 | country | file://:0:0:0:0 | char * | MemberVariable | | static |
|
||||
| variables.cpp:52:16:52:22 | country | file://:0:0:0:0 | char * | StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:56:14:56:29 | externInFunction | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:56:14:56:29 | externInFunction | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:52:16:52:22 | country | file://:0:0:0:0 | char * | MemberVariable, StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:56:14:56:29 | externInFunction | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import cpp
|
||||
|
||||
from Variable v, Type t, string qlClass, string const, string static
|
||||
string interestingQlClass(Variable v) {
|
||||
result = v.getAQlClass() and
|
||||
(
|
||||
result.matches("%Variable%")
|
||||
or
|
||||
result.matches("%Field%")
|
||||
)
|
||||
}
|
||||
|
||||
from Variable v, Type t, string const, string static
|
||||
where
|
||||
t = v.getType() and
|
||||
qlClass = v.getAQlClass() and
|
||||
(qlClass.matches("%Variable%") or qlClass.matches("%Field%")) and
|
||||
(if v.isConst() then const = "const" else const = "") and
|
||||
if v.isStatic() then static = "static" else static = ""
|
||||
select v, t, qlClass, const, static
|
||||
select v, t, concat(interestingQlClass(v), ", "), const, static
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| test.cpp:27:5:27:6 | f1 | The variable $@ is used in this function but may not be initialized when it is called. | test.cpp:14:5:14:5 | b | b |
|
||||
@@ -0,0 +1 @@
|
||||
Critical/GlobalUseBeforeInit.ql
|
||||
@@ -0,0 +1,38 @@
|
||||
typedef __builtin_va_list va_list;
|
||||
typedef struct {} FILE;
|
||||
|
||||
extern FILE * stdin;
|
||||
extern FILE * stdout;
|
||||
extern FILE * stderr;
|
||||
|
||||
#define va_start(args, fmt) __builtin_va_start(args,fmt)
|
||||
#define va_end(args) __builtin_va_end(args);
|
||||
|
||||
int vfprintf (FILE *, const char *, va_list);
|
||||
|
||||
int a = 1;
|
||||
int b;
|
||||
|
||||
int my_printf(const char * fmt, ...)
|
||||
{
|
||||
va_list vl;
|
||||
int ret;
|
||||
va_start(vl, fmt);
|
||||
ret = vfprintf(stdout, fmt, vl);
|
||||
ret = vfprintf(stderr, fmt, vl);
|
||||
va_end(vl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int f1()
|
||||
{
|
||||
my_printf("%d\n", a + 2);
|
||||
my_printf("%d\n", b + 2); // BAD
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int b = f1();
|
||||
return 0;
|
||||
}
|
||||
@@ -9,8 +9,11 @@ edges
|
||||
| test_free.cpp:95:10:95:10 | pointer to free output argument | test_free.cpp:96:9:96:9 | a | provenance | |
|
||||
| test_free.cpp:101:10:101:10 | pointer to free output argument | test_free.cpp:102:23:102:23 | a | provenance | |
|
||||
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:153:5:153:5 | a | provenance | |
|
||||
| test_free.cpp:233:14:233:15 | pointer to free output argument | test_free.cpp:236:9:236:10 | * ... | provenance | |
|
||||
| test_free.cpp:239:14:239:15 | pointer to free output argument | test_free.cpp:241:9:241:10 | * ... | provenance | |
|
||||
| test_free.cpp:233:14:233:15 | pointer to free output argument | test_free.cpp:234:9:234:11 | *... ++ | provenance | |
|
||||
| test_free.cpp:234:9:234:11 | *... ++ | test_free.cpp:236:9:236:10 | * ... | provenance | |
|
||||
| test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:238:15:238:17 | *... ++ | provenance | |
|
||||
| test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:241:9:241:10 | * ... | provenance | |
|
||||
| test_free.cpp:239:14:239:15 | pointer to free output argument | test_free.cpp:238:15:238:17 | *... ++ | provenance | |
|
||||
| test_free.cpp:245:10:245:11 | pointer to free output argument | test_free.cpp:246:9:246:10 | * ... | provenance | |
|
||||
| test_free.cpp:277:8:277:8 | *s [post update] [buf] | test_free.cpp:278:12:278:12 | *s [buf] | provenance | |
|
||||
| test_free.cpp:277:8:277:13 | pointer to free output argument | test_free.cpp:277:8:277:8 | *s [post update] [buf] | provenance | |
|
||||
@@ -43,7 +46,9 @@ nodes
|
||||
| test_free.cpp:152:27:152:27 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test_free.cpp:153:5:153:5 | a | semmle.label | a |
|
||||
| test_free.cpp:233:14:233:15 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test_free.cpp:234:9:234:11 | *... ++ | semmle.label | *... ++ |
|
||||
| test_free.cpp:236:9:236:10 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:238:15:238:17 | *... ++ | semmle.label | *... ++ |
|
||||
| test_free.cpp:239:14:239:15 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test_free.cpp:241:9:241:10 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:245:10:245:11 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
|
||||
@@ -7,19 +7,32 @@ edges
|
||||
| nested.cpp:34:37:34:39 | *fmt | nested.cpp:35:19:35:21 | *fmt | provenance | |
|
||||
| nested.cpp:35:19:35:21 | *fmt | nested.cpp:27:32:27:34 | *fmt | provenance | |
|
||||
| nested.cpp:42:24:42:34 | *call to ext_fmt_str | nested.cpp:34:37:34:39 | *fmt | provenance | |
|
||||
| nested.cpp:86:19:86:46 | *call to __builtin_alloca | nested.cpp:86:19:86:46 | *call to __builtin_alloca | provenance | |
|
||||
| nested.cpp:86:19:86:46 | *call to __builtin_alloca | nested.cpp:87:18:87:20 | *fmt | provenance | |
|
||||
| test.cpp:46:27:46:30 | **argv | test.cpp:130:20:130:26 | *access to array | provenance | |
|
||||
| test.cpp:167:31:167:34 | *data | test.cpp:170:12:170:14 | *res | provenance | DataFlowFunction |
|
||||
| test.cpp:193:32:193:34 | *str | test.cpp:195:31:195:33 | *str | provenance | |
|
||||
| test.cpp:193:32:193:34 | *str | test.cpp:197:11:197:14 | *wstr | provenance | TaintFunction |
|
||||
| test.cpp:204:25:204:36 | *call to get_string | test.cpp:204:25:204:36 | *call to get_string | provenance | |
|
||||
| test.cpp:204:25:204:36 | *call to get_string | test.cpp:205:12:205:20 | *... + ... | provenance | |
|
||||
| test.cpp:204:25:204:36 | *call to get_string | test.cpp:206:12:206:16 | *hello | provenance | |
|
||||
| test.cpp:209:25:209:36 | *call to get_string | test.cpp:211:12:211:16 | *hello | provenance | |
|
||||
| test.cpp:215:25:215:36 | *call to get_string | test.cpp:217:12:217:16 | *hello | provenance | |
|
||||
| test.cpp:221:25:221:36 | *call to get_string | test.cpp:223:12:223:16 | *hello | provenance | |
|
||||
| test.cpp:209:25:209:36 | *call to get_string | test.cpp:209:25:209:36 | *call to get_string | provenance | |
|
||||
| test.cpp:209:25:209:36 | *call to get_string | test.cpp:210:5:210:14 | *... += ... | provenance | |
|
||||
| test.cpp:210:5:210:14 | *... += ... | test.cpp:211:12:211:16 | *hello | provenance | |
|
||||
| test.cpp:215:25:215:36 | *call to get_string | test.cpp:215:25:215:36 | *call to get_string | provenance | |
|
||||
| test.cpp:215:25:215:36 | *call to get_string | test.cpp:216:5:216:21 | *... = ... | provenance | |
|
||||
| test.cpp:216:5:216:21 | *... = ... | test.cpp:217:12:217:16 | *hello | provenance | |
|
||||
| test.cpp:221:25:221:36 | *call to get_string | test.cpp:221:25:221:36 | *call to get_string | provenance | |
|
||||
| test.cpp:221:25:221:36 | *call to get_string | test.cpp:222:5:222:11 | *... ++ | provenance | |
|
||||
| test.cpp:222:5:222:11 | *... ++ | test.cpp:223:12:223:16 | *hello | provenance | |
|
||||
| test.cpp:227:25:227:36 | *call to get_string | test.cpp:227:25:227:36 | *call to get_string | provenance | |
|
||||
| test.cpp:227:25:227:36 | *call to get_string | test.cpp:228:12:228:18 | *++ ... | provenance | |
|
||||
| test.cpp:228:12:228:18 | *++ ... | test.cpp:228:12:228:18 | *++ ... | provenance | |
|
||||
| test.cpp:232:25:232:36 | *call to get_string | test.cpp:232:25:232:36 | *call to get_string | provenance | |
|
||||
| test.cpp:232:25:232:36 | *call to get_string | test.cpp:235:12:235:16 | *hello | provenance | |
|
||||
| test.cpp:239:25:239:36 | *call to get_string | test.cpp:239:25:239:36 | *call to get_string | provenance | |
|
||||
| test.cpp:239:25:239:36 | *call to get_string | test.cpp:242:12:242:16 | *hello | provenance | |
|
||||
| test.cpp:245:25:245:36 | *call to get_string | test.cpp:245:25:245:36 | *call to get_string | provenance | |
|
||||
| test.cpp:245:25:245:36 | *call to get_string | test.cpp:247:12:247:16 | *hello | provenance | |
|
||||
nodes
|
||||
| NonConstantFormat.c:28:27:28:30 | **argv | semmle.label | **argv |
|
||||
@@ -36,6 +49,7 @@ nodes
|
||||
| nested.cpp:42:24:42:34 | *call to ext_fmt_str | semmle.label | *call to ext_fmt_str |
|
||||
| nested.cpp:79:32:79:38 | *call to get_fmt | semmle.label | *call to get_fmt |
|
||||
| nested.cpp:86:19:86:46 | *call to __builtin_alloca | semmle.label | *call to __builtin_alloca |
|
||||
| nested.cpp:86:19:86:46 | *call to __builtin_alloca | semmle.label | *call to __builtin_alloca |
|
||||
| nested.cpp:87:18:87:20 | *fmt | semmle.label | *fmt |
|
||||
| test.cpp:46:27:46:30 | **argv | semmle.label | **argv |
|
||||
| test.cpp:130:20:130:26 | *access to array | semmle.label | *access to array |
|
||||
@@ -45,21 +59,33 @@ nodes
|
||||
| test.cpp:195:31:195:33 | *str | semmle.label | *str |
|
||||
| test.cpp:197:11:197:14 | *wstr | semmle.label | *wstr |
|
||||
| test.cpp:204:25:204:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:204:25:204:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:205:12:205:20 | *... + ... | semmle.label | *... + ... |
|
||||
| test.cpp:206:12:206:16 | *hello | semmle.label | *hello |
|
||||
| test.cpp:209:25:209:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:209:25:209:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:210:5:210:14 | *... += ... | semmle.label | *... += ... |
|
||||
| test.cpp:211:12:211:16 | *hello | semmle.label | *hello |
|
||||
| test.cpp:215:25:215:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:215:25:215:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:216:5:216:21 | *... = ... | semmle.label | *... = ... |
|
||||
| test.cpp:217:12:217:16 | *hello | semmle.label | *hello |
|
||||
| test.cpp:221:25:221:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:221:25:221:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:222:5:222:11 | *... ++ | semmle.label | *... ++ |
|
||||
| test.cpp:223:12:223:16 | *hello | semmle.label | *hello |
|
||||
| test.cpp:227:25:227:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:227:25:227:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:228:12:228:18 | *++ ... | semmle.label | *++ ... |
|
||||
| test.cpp:228:12:228:18 | *++ ... | semmle.label | *++ ... |
|
||||
| test.cpp:232:25:232:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:232:25:232:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:235:12:235:16 | *hello | semmle.label | *hello |
|
||||
| test.cpp:239:25:239:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:239:25:239:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:242:12:242:16 | *hello | semmle.label | *hello |
|
||||
| test.cpp:245:25:245:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:245:25:245:36 | *call to get_string | semmle.label | *call to get_string |
|
||||
| test.cpp:247:12:247:16 | *hello | semmle.label | *hello |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
edges
|
||||
| test.c:8:27:8:30 | **argv | test.c:17:11:17:18 | *fileName | provenance | TaintFunction |
|
||||
| test.c:8:27:8:30 | **argv | test.c:32:11:32:18 | *fileName | provenance | |
|
||||
| test.c:8:27:8:30 | **argv | test.c:9:23:9:29 | *access to array | provenance | |
|
||||
| test.c:8:27:8:30 | **argv | test.c:31:22:31:28 | *access to array | provenance | |
|
||||
| test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array | provenance | |
|
||||
| test.c:9:23:9:29 | *access to array | test.c:17:11:17:18 | *fileName | provenance | TaintFunction |
|
||||
| test.c:31:22:31:28 | *access to array | test.c:32:11:32:18 | *fileName | provenance | |
|
||||
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName | provenance | |
|
||||
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | provenance | |
|
||||
nodes
|
||||
| test.c:8:27:8:30 | **argv | semmle.label | **argv |
|
||||
| test.c:9:23:9:29 | *access to array | semmle.label | *access to array |
|
||||
| test.c:17:11:17:18 | *fileName | semmle.label | *fileName |
|
||||
| test.c:31:22:31:28 | *access to array | semmle.label | *access to array |
|
||||
| test.c:32:11:32:18 | *fileName | semmle.label | *fileName |
|
||||
| test.c:37:17:37:24 | scanf output argument | semmle.label | scanf output argument |
|
||||
| test.c:38:11:38:18 | *fileName | semmle.label | *fileName |
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
edges
|
||||
| tests.cpp:26:15:26:23 | **badSource | tests.cpp:51:12:51:20 | *call to badSource | provenance | |
|
||||
| tests.cpp:33:34:33:39 | *call to getenv | tests.cpp:33:34:33:39 | *call to getenv | provenance | |
|
||||
| tests.cpp:33:34:33:39 | *call to getenv | tests.cpp:38:39:38:49 | *environment | provenance | |
|
||||
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:26:15:26:23 | **badSource | provenance | |
|
||||
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:42:12:42:15 | *data | provenance | |
|
||||
| tests.cpp:38:39:38:49 | *environment | tests.cpp:38:25:38:36 | strncat output argument | provenance | |
|
||||
| tests.cpp:51:12:51:20 | *call to badSource | tests.cpp:53:16:53:19 | *data | provenance | |
|
||||
| tests.cpp:42:12:42:15 | *data | tests.cpp:26:15:26:23 | **badSource | provenance | |
|
||||
| tests.cpp:51:5:51:26 | *... = ... | tests.cpp:53:16:53:19 | *data | provenance | |
|
||||
| tests.cpp:51:12:51:20 | *call to badSource | tests.cpp:51:5:51:26 | *... = ... | provenance | |
|
||||
nodes
|
||||
| tests.cpp:26:15:26:23 | **badSource | semmle.label | **badSource |
|
||||
| tests.cpp:33:34:33:39 | *call to getenv | semmle.label | *call to getenv |
|
||||
| tests.cpp:33:34:33:39 | *call to getenv | semmle.label | *call to getenv |
|
||||
| tests.cpp:38:25:38:36 | strncat output argument | semmle.label | strncat output argument |
|
||||
| tests.cpp:38:39:38:49 | *environment | semmle.label | *environment |
|
||||
| tests.cpp:42:12:42:15 | *data | semmle.label | *data |
|
||||
| tests.cpp:51:5:51:26 | *... = ... | semmle.label | *... = ... |
|
||||
| tests.cpp:51:12:51:20 | *call to badSource | semmle.label | *call to badSource |
|
||||
| tests.cpp:53:16:53:19 | *data | semmle.label | *data |
|
||||
subpaths
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
edges
|
||||
| test.cpp:15:27:15:30 | **argv | test.cpp:22:45:22:52 | *userName | provenance | |
|
||||
| test.cpp:15:27:15:30 | **argv | test.cpp:16:20:16:26 | *access to array | provenance | |
|
||||
| test.cpp:16:20:16:26 | *access to array | test.cpp:22:45:22:52 | *userName | provenance | |
|
||||
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | *command1 | provenance | |
|
||||
| test.cpp:22:45:22:52 | *userName | test.cpp:22:13:22:20 | sprintf output argument | provenance | |
|
||||
| test.cpp:47:21:47:26 | *call to getenv | test.cpp:47:21:47:26 | *call to getenv | provenance | |
|
||||
| test.cpp:47:21:47:26 | *call to getenv | test.cpp:50:35:50:43 | *envCflags | provenance | |
|
||||
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | *command | provenance | |
|
||||
| test.cpp:50:35:50:43 | *envCflags | test.cpp:50:11:50:17 | sprintf output argument | provenance | |
|
||||
@@ -15,6 +17,7 @@ edges
|
||||
| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | *path | provenance | |
|
||||
| test.cpp:93:17:93:24 | *filename | test.cpp:93:11:93:14 | strncat output argument | provenance | |
|
||||
| test.cpp:106:20:106:38 | *call to getenv | test.cpp:107:33:107:36 | *path | provenance | TaintFunction |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | test.cpp:107:31:107:31 | call to operator+ | provenance | |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | *call to c_str | provenance | TaintFunction |
|
||||
| test.cpp:107:33:107:36 | *path | test.cpp:107:31:107:31 | call to operator+ | provenance | |
|
||||
| test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:19:114:22 | *path | provenance | TaintFunction |
|
||||
@@ -66,10 +69,12 @@ edges
|
||||
| test.cpp:220:19:220:26 | *filename | test.cpp:220:19:220:26 | *filename | provenance | |
|
||||
nodes
|
||||
| test.cpp:15:27:15:30 | **argv | semmle.label | **argv |
|
||||
| test.cpp:16:20:16:26 | *access to array | semmle.label | *access to array |
|
||||
| test.cpp:22:13:22:20 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:22:45:22:52 | *userName | semmle.label | *userName |
|
||||
| test.cpp:23:12:23:19 | *command1 | semmle.label | *command1 |
|
||||
| test.cpp:47:21:47:26 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:47:21:47:26 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:50:11:50:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:50:35:50:43 | *envCflags | semmle.label | *envCflags |
|
||||
| test.cpp:51:10:51:16 | *command | semmle.label | *command |
|
||||
@@ -87,6 +92,7 @@ nodes
|
||||
| test.cpp:94:45:94:48 | *path | semmle.label | *path |
|
||||
| test.cpp:106:20:106:38 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:107:33:107:36 | *path | semmle.label | *path |
|
||||
| test.cpp:108:18:108:22 | *call to c_str | semmle.label | *call to c_str |
|
||||
| test.cpp:113:20:113:38 | *call to getenv | semmle.label | *call to getenv |
|
||||
|
||||
@@ -2,6 +2,7 @@ edges
|
||||
| search.c:14:24:14:28 | *query | search.c:17:8:17:12 | *query | provenance | |
|
||||
| search.c:22:24:22:28 | *query | search.c:23:39:23:43 | *query | provenance | |
|
||||
| search.c:55:24:55:28 | *query | search.c:62:8:62:17 | *query_text | provenance | TaintFunction |
|
||||
| search.c:67:21:67:26 | *call to getenv | search.c:67:21:67:26 | *call to getenv | provenance | |
|
||||
| search.c:67:21:67:26 | *call to getenv | search.c:71:17:71:25 | *raw_query | provenance | |
|
||||
| search.c:67:21:67:26 | *call to getenv | search.c:73:17:73:25 | *raw_query | provenance | |
|
||||
| search.c:67:21:67:26 | *call to getenv | search.c:77:17:77:25 | *raw_query | provenance | |
|
||||
@@ -16,6 +17,7 @@ nodes
|
||||
| search.c:55:24:55:28 | *query | semmle.label | *query |
|
||||
| search.c:62:8:62:17 | *query_text | semmle.label | *query_text |
|
||||
| search.c:67:21:67:26 | *call to getenv | semmle.label | *call to getenv |
|
||||
| search.c:67:21:67:26 | *call to getenv | semmle.label | *call to getenv |
|
||||
| search.c:71:17:71:25 | *raw_query | semmle.label | *raw_query |
|
||||
| search.c:73:17:73:25 | *raw_query | semmle.label | *raw_query |
|
||||
| search.c:77:17:77:25 | *raw_query | semmle.label | *raw_query |
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
edges
|
||||
| test.c:14:27:14:30 | **argv | test.c:21:18:21:23 | *query1 | provenance | TaintFunction |
|
||||
| test.c:14:27:14:30 | **argv | test.c:35:16:35:23 | *userName | provenance | |
|
||||
| test.c:14:27:14:30 | **argv | test.c:15:20:15:26 | *access to array | provenance | |
|
||||
| test.c:15:20:15:26 | *access to array | test.c:21:18:21:23 | *query1 | provenance | TaintFunction |
|
||||
| test.c:15:20:15:26 | *access to array | test.c:35:16:35:23 | *userName | provenance | |
|
||||
| test.c:35:16:35:23 | *userName | test.c:40:25:40:32 | *username | provenance | |
|
||||
| test.c:38:7:38:20 | **globalUsername | test.c:51:18:51:23 | *query1 | provenance | TaintFunction |
|
||||
| test.c:40:25:40:32 | *username | test.c:38:7:38:20 | **globalUsername | provenance | |
|
||||
| test.c:38:7:38:20 | **globalUsername | test.c:48:20:48:33 | *globalUsername | provenance | |
|
||||
| test.c:40:25:40:32 | *username | test.c:41:3:41:27 | *... = ... | provenance | |
|
||||
| test.c:41:3:41:27 | *... = ... | test.c:38:7:38:20 | **globalUsername | provenance | |
|
||||
| test.c:48:20:48:33 | *globalUsername | test.c:51:18:51:23 | *query1 | provenance | TaintFunction |
|
||||
| test.c:75:8:75:16 | gets output argument | test.c:76:17:76:25 | *userInput | provenance | |
|
||||
| test.c:75:8:75:16 | gets output argument | test.c:77:20:77:28 | *userInput | provenance | |
|
||||
| test.cpp:39:27:39:30 | **argv | test.cpp:43:27:43:33 | *access to array | provenance | |
|
||||
nodes
|
||||
| test.c:14:27:14:30 | **argv | semmle.label | **argv |
|
||||
| test.c:15:20:15:26 | *access to array | semmle.label | *access to array |
|
||||
| test.c:21:18:21:23 | *query1 | semmle.label | *query1 |
|
||||
| test.c:35:16:35:23 | *userName | semmle.label | *userName |
|
||||
| test.c:38:7:38:20 | **globalUsername | semmle.label | **globalUsername |
|
||||
| test.c:40:25:40:32 | *username | semmle.label | *username |
|
||||
| test.c:41:3:41:27 | *... = ... | semmle.label | *... = ... |
|
||||
| test.c:48:20:48:33 | *globalUsername | semmle.label | *globalUsername |
|
||||
| test.c:51:18:51:23 | *query1 | semmle.label | *query1 |
|
||||
| test.c:75:8:75:16 | gets output argument | semmle.label | gets output argument |
|
||||
| test.c:76:17:76:25 | *userInput | semmle.label | *userInput |
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
edges
|
||||
| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | *data | provenance | |
|
||||
| test.cpp:64:30:64:35 | *call to getenv | test.cpp:64:30:64:35 | *call to getenv | provenance | |
|
||||
| test.cpp:64:30:64:35 | *call to getenv | test.cpp:73:24:73:27 | *data | provenance | TaintFunction |
|
||||
| test.cpp:73:24:73:27 | *data | test.cpp:37:73:37:76 | *data | provenance | |
|
||||
nodes
|
||||
| test.cpp:37:73:37:76 | *data | semmle.label | *data |
|
||||
| test.cpp:43:32:43:35 | *data | semmle.label | *data |
|
||||
| test.cpp:64:30:64:35 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:64:30:64:35 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:73:24:73:27 | *data | semmle.label | *data |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -3,14 +3,18 @@ edges
|
||||
| test.cpp:29:30:29:36 | *command | test.cpp:31:10:31:16 | *command | provenance | |
|
||||
| test.cpp:42:18:42:34 | *call to getenv | test.cpp:24:30:24:36 | *command | provenance | |
|
||||
| test.cpp:43:18:43:34 | *call to getenv | test.cpp:29:30:29:36 | *command | provenance | |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:58:16:58:21 | *buffer | provenance | |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | *buffer | provenance | |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | *data | provenance | |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | *dataref | provenance | |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | *data2 | provenance | |
|
||||
| test.cpp:58:16:58:21 | *buffer | test.cpp:59:20:59:23 | **data | provenance | |
|
||||
| test.cpp:58:16:58:21 | *buffer | test.cpp:63:10:63:13 | *data | provenance | |
|
||||
| test.cpp:59:20:59:23 | **data | test.cpp:60:17:60:23 | *dataref | provenance | |
|
||||
| test.cpp:59:20:59:23 | **data | test.cpp:64:10:64:16 | *dataref | provenance | |
|
||||
| test.cpp:60:17:60:23 | *dataref | test.cpp:65:10:65:14 | *data2 | provenance | |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | *buffer | provenance | |
|
||||
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | *buffer | provenance | |
|
||||
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | *buffer | provenance | |
|
||||
| test.cpp:113:8:113:12 | *call to fgets | test.cpp:114:9:114:11 | *ptr | provenance | |
|
||||
| test.cpp:113:2:113:44 | *... = ... | test.cpp:114:9:114:11 | *ptr | provenance | |
|
||||
| test.cpp:113:8:113:12 | *call to fgets | test.cpp:113:2:113:44 | *... = ... | provenance | |
|
||||
nodes
|
||||
| test.cpp:24:30:24:36 | *command | semmle.label | *command |
|
||||
| test.cpp:26:10:26:16 | *command | semmle.label | *command |
|
||||
@@ -19,6 +23,9 @@ nodes
|
||||
| test.cpp:42:18:42:34 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:43:18:43:34 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | semmle.label | fgets output argument |
|
||||
| test.cpp:58:16:58:21 | *buffer | semmle.label | *buffer |
|
||||
| test.cpp:59:20:59:23 | **data | semmle.label | **data |
|
||||
| test.cpp:60:17:60:23 | *dataref | semmle.label | *dataref |
|
||||
| test.cpp:62:10:62:15 | *buffer | semmle.label | *buffer |
|
||||
| test.cpp:63:10:63:13 | *data | semmle.label | *data |
|
||||
| test.cpp:64:10:64:16 | *dataref | semmle.label | *dataref |
|
||||
@@ -29,6 +36,7 @@ nodes
|
||||
| test.cpp:99:15:99:20 | *buffer | semmle.label | *buffer |
|
||||
| test.cpp:106:17:106:22 | recv output argument | semmle.label | recv output argument |
|
||||
| test.cpp:107:15:107:20 | *buffer | semmle.label | *buffer |
|
||||
| test.cpp:113:2:113:44 | *... = ... | semmle.label | *... = ... |
|
||||
| test.cpp:113:8:113:12 | *call to fgets | semmle.label | *call to fgets |
|
||||
| test.cpp:114:9:114:11 | *ptr | semmle.label | *ptr |
|
||||
subpaths
|
||||
|
||||
@@ -3,7 +3,9 @@ edges
|
||||
| test.cpp:18:5:18:7 | *str [post update] [string] | test.cpp:19:5:19:7 | *str [string] | provenance | |
|
||||
| test.cpp:18:5:18:30 | ... = ... | test.cpp:18:5:18:7 | *str [post update] [string] | provenance | |
|
||||
| test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... | provenance | |
|
||||
| test.cpp:19:5:19:7 | *str [string] | test.cpp:16:11:16:21 | **mk_string_t [string] | provenance | |
|
||||
| test.cpp:19:5:19:7 | *str [string] | test.cpp:20:12:20:14 | *str [string] | provenance | |
|
||||
| test.cpp:20:12:20:14 | *str [string] | test.cpp:16:11:16:21 | **mk_string_t [string] | provenance | |
|
||||
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:39:21:39:31 | *call to mk_string_t [string] | provenance | |
|
||||
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:42:13:42:15 | *str [string] | provenance | |
|
||||
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:72:17:72:19 | *str [string] | provenance | |
|
||||
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:80:17:80:19 | *str [string] | provenance | |
|
||||
@@ -14,7 +16,9 @@ edges
|
||||
| test.cpp:90:5:90:7 | *str [post update] [string] | test.cpp:91:5:91:7 | *str [string] | provenance | |
|
||||
| test.cpp:90:5:90:34 | ... = ... | test.cpp:90:5:90:7 | *str [post update] [string] | provenance | |
|
||||
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... | provenance | |
|
||||
| test.cpp:91:5:91:7 | *str [string] | test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | provenance | |
|
||||
| test.cpp:91:5:91:7 | *str [string] | test.cpp:92:12:92:14 | *str [string] | provenance | |
|
||||
| test.cpp:92:12:92:14 | *str [string] | test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | provenance | |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | provenance | |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:99:13:99:15 | *str [string] | provenance | |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:129:17:129:19 | *str [string] | provenance | |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:137:17:137:19 | *str [string] | provenance | |
|
||||
@@ -43,27 +47,36 @@ edges
|
||||
| test.cpp:203:17:203:19 | *str [string] | test.cpp:203:22:203:27 | string | provenance | |
|
||||
| test.cpp:207:17:207:19 | *str [string] | test.cpp:207:22:207:27 | string | provenance | |
|
||||
| test.cpp:214:24:214:24 | p | test.cpp:216:10:216:10 | p | provenance | |
|
||||
| test.cpp:220:27:220:54 | call to malloc | test.cpp:220:27:220:54 | call to malloc | provenance | |
|
||||
| test.cpp:220:27:220:54 | call to malloc | test.cpp:222:15:222:20 | buffer | provenance | |
|
||||
| test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p | provenance | |
|
||||
| test.cpp:228:27:228:54 | call to malloc | test.cpp:228:27:228:54 | call to malloc | provenance | |
|
||||
| test.cpp:228:27:228:54 | call to malloc | test.cpp:232:10:232:15 | buffer | provenance | |
|
||||
| test.cpp:235:40:235:45 | buffer | test.cpp:236:5:236:26 | ... = ... | provenance | |
|
||||
| test.cpp:236:5:236:9 | *p_str [post update] [string] | test.cpp:235:27:235:31 | *p_str [string] | provenance | |
|
||||
| test.cpp:236:5:236:26 | ... = ... | test.cpp:236:5:236:9 | *p_str [post update] [string] | provenance | |
|
||||
| test.cpp:241:20:241:38 | call to malloc | test.cpp:241:20:241:38 | call to malloc | provenance | |
|
||||
| test.cpp:241:20:241:38 | call to malloc | test.cpp:242:22:242:27 | buffer | provenance | |
|
||||
| test.cpp:242:16:242:19 | set_string output argument [string] | test.cpp:243:12:243:14 | *str [string] | provenance | |
|
||||
| test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer | provenance | |
|
||||
| test.cpp:242:22:242:27 | buffer | test.cpp:242:16:242:19 | set_string output argument [string] | provenance | |
|
||||
| test.cpp:243:12:243:14 | *str [string] | test.cpp:243:12:243:21 | string | provenance | |
|
||||
| test.cpp:249:14:249:33 | call to my_alloc | test.cpp:249:14:249:33 | call to my_alloc | provenance | |
|
||||
| test.cpp:249:14:249:33 | call to my_alloc | test.cpp:250:12:250:12 | p | provenance | |
|
||||
| test.cpp:256:9:256:25 | call to malloc | test.cpp:257:12:257:12 | p | provenance | |
|
||||
| test.cpp:256:5:256:25 | ... = ... | test.cpp:257:12:257:12 | p | provenance | |
|
||||
| test.cpp:256:9:256:25 | call to malloc | test.cpp:256:5:256:25 | ... = ... | provenance | |
|
||||
| test.cpp:262:15:262:30 | call to malloc | test.cpp:262:15:262:30 | call to malloc | provenance | |
|
||||
| test.cpp:262:15:262:30 | call to malloc | test.cpp:266:12:266:12 | p | provenance | |
|
||||
| test.cpp:264:13:264:30 | call to malloc | test.cpp:266:12:266:12 | p | provenance | |
|
||||
| test.cpp:264:9:264:30 | ... = ... | test.cpp:266:12:266:12 | p | provenance | |
|
||||
| test.cpp:264:13:264:30 | call to malloc | test.cpp:264:9:264:30 | ... = ... | provenance | |
|
||||
nodes
|
||||
| test.cpp:16:11:16:21 | **mk_string_t [string] | semmle.label | **mk_string_t [string] |
|
||||
| test.cpp:18:5:18:7 | *str [post update] [string] | semmle.label | *str [post update] [string] |
|
||||
| test.cpp:18:5:18:30 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:18:19:18:24 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:19:5:19:7 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:20:12:20:14 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | semmle.label | *call to mk_string_t [string] |
|
||||
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | semmle.label | *call to mk_string_t [string] |
|
||||
| test.cpp:42:13:42:15 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:42:18:42:23 | string | semmle.label | string |
|
||||
@@ -76,6 +89,8 @@ nodes
|
||||
| test.cpp:90:5:90:34 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:90:19:90:24 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:91:5:91:7 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:92:12:92:14 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | semmle.label | *call to mk_string_t_plus_one [string] |
|
||||
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | semmle.label | *call to mk_string_t_plus_one [string] |
|
||||
| test.cpp:99:13:99:15 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:99:18:99:23 | string | semmle.label | string |
|
||||
@@ -108,23 +123,30 @@ nodes
|
||||
| test.cpp:214:24:214:24 | p | semmle.label | p |
|
||||
| test.cpp:216:10:216:10 | p | semmle.label | p |
|
||||
| test.cpp:220:27:220:54 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:220:27:220:54 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:222:15:222:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:228:27:228:54 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:228:27:228:54 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:232:10:232:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:235:27:235:31 | *p_str [string] | semmle.label | *p_str [string] |
|
||||
| test.cpp:235:40:235:45 | buffer | semmle.label | buffer |
|
||||
| test.cpp:236:5:236:9 | *p_str [post update] [string] | semmle.label | *p_str [post update] [string] |
|
||||
| test.cpp:236:5:236:26 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:241:20:241:38 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:241:20:241:38 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:242:16:242:19 | set_string output argument [string] | semmle.label | set_string output argument [string] |
|
||||
| test.cpp:242:22:242:27 | buffer | semmle.label | buffer |
|
||||
| test.cpp:243:12:243:14 | *str [string] | semmle.label | *str [string] |
|
||||
| test.cpp:243:12:243:21 | string | semmle.label | string |
|
||||
| test.cpp:249:14:249:33 | call to my_alloc | semmle.label | call to my_alloc |
|
||||
| test.cpp:249:14:249:33 | call to my_alloc | semmle.label | call to my_alloc |
|
||||
| test.cpp:250:12:250:12 | p | semmle.label | p |
|
||||
| test.cpp:256:5:256:25 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:256:9:256:25 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:257:12:257:12 | p | semmle.label | p |
|
||||
| test.cpp:262:15:262:30 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:262:15:262:30 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:264:9:264:30 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:264:13:264:30 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:266:12:266:12 | p | semmle.label | p |
|
||||
subpaths
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
edges
|
||||
| main.cpp:6:27:6:30 | **argv | main.cpp:7:33:7:36 | **argv | provenance | |
|
||||
| main.cpp:7:33:7:36 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | |
|
||||
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:30:17:30:20 | *arg1 | provenance | |
|
||||
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:27:2:27:15 | *... = ... | provenance | |
|
||||
| overflowdestination.cpp:27:2:27:15 | *... = ... | overflowdestination.cpp:30:17:30:20 | *arg1 | provenance | |
|
||||
| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | *src | provenance | |
|
||||
| overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:50:52:50:54 | *src | provenance | |
|
||||
| overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:53:15:53:17 | *src | provenance | |
|
||||
| overflowdestination.cpp:57:52:57:54 | *src | overflowdestination.cpp:64:16:64:19 | *src2 | provenance | |
|
||||
| overflowdestination.cpp:57:52:57:54 | *src | overflowdestination.cpp:60:15:60:17 | *src | provenance | |
|
||||
| overflowdestination.cpp:60:15:60:17 | *src | overflowdestination.cpp:64:16:64:19 | *src2 | provenance | |
|
||||
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | *src | provenance | |
|
||||
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | *src | provenance | |
|
||||
| overflowdestination.cpp:75:30:75:32 | *src | overflowdestination.cpp:50:52:50:54 | *src | provenance | |
|
||||
@@ -16,6 +18,7 @@ nodes
|
||||
| main.cpp:6:27:6:30 | **argv | semmle.label | **argv |
|
||||
| main.cpp:7:33:7:36 | **argv | semmle.label | **argv |
|
||||
| overflowdestination.cpp:23:45:23:48 | **argv | semmle.label | **argv |
|
||||
| overflowdestination.cpp:27:2:27:15 | *... = ... | semmle.label | *... = ... |
|
||||
| overflowdestination.cpp:30:17:30:20 | *arg1 | semmle.label | *arg1 |
|
||||
| overflowdestination.cpp:43:8:43:10 | fgets output argument | semmle.label | fgets output argument |
|
||||
| overflowdestination.cpp:46:15:46:17 | *src | semmle.label | *src |
|
||||
@@ -23,6 +26,7 @@ nodes
|
||||
| overflowdestination.cpp:50:52:50:54 | *src | semmle.label | *src |
|
||||
| overflowdestination.cpp:53:15:53:17 | *src | semmle.label | *src |
|
||||
| overflowdestination.cpp:57:52:57:54 | *src | semmle.label | *src |
|
||||
| overflowdestination.cpp:60:15:60:17 | *src | semmle.label | *src |
|
||||
| overflowdestination.cpp:64:16:64:19 | *src2 | semmle.label | *src2 |
|
||||
| overflowdestination.cpp:73:8:73:10 | fgets output argument | semmle.label | fgets output argument |
|
||||
| overflowdestination.cpp:75:30:75:32 | *src | semmle.label | *src |
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
edges
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | provenance | TaintFunction |
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:33:13:33:36 | ... = ... | provenance | TaintFunction |
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:33:13:33:36 | ... = ... | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | provenance | |
|
||||
nodes
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | semmle.label | fgets output argument |
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:33:13:33:36 | ... = ... | semmle.label | ... = ... |
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | semmle.label | data |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user