mirror of
https://github.com/github/codeql.git
synced 2026-07-05 19:45:29 +02:00
Compare commits
400 Commits
codeql-cli
...
aeisenberg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e53ad33f6 | ||
|
|
3670c729c0 | ||
|
|
a09c12acfe | ||
|
|
a7030c7fed | ||
|
|
c3058f4744 | ||
|
|
6f2103f312 | ||
|
|
9b5bb95766 | ||
|
|
bc8c55836a | ||
|
|
1b4c3c7415 | ||
|
|
819be43ce7 | ||
|
|
43dc9bbc94 | ||
|
|
6de5b3021e | ||
|
|
6e059ea002 | ||
|
|
96a4d91a6c | ||
|
|
635fb4c25a | ||
|
|
3e4ff9e472 | ||
|
|
bdb41423e2 | ||
|
|
ed42c878b0 | ||
|
|
b36d35bf1e | ||
|
|
2b8afe55e8 | ||
|
|
fea9f5f431 | ||
|
|
a8a920c8f0 | ||
|
|
8a01799fb8 | ||
|
|
4b8d4f5bbd | ||
|
|
e448dcb725 | ||
|
|
9f1704560b | ||
|
|
1dab1590ea | ||
|
|
9c936867fa | ||
|
|
a7cc9f98ef | ||
|
|
cac1bef6ea | ||
|
|
fe8deeaf6b | ||
|
|
e98bfe921e | ||
|
|
bb7934b381 | ||
|
|
c113cfd8b7 | ||
|
|
5a9e27c6fc | ||
|
|
94f0a1532d | ||
|
|
a0f5e45ae9 | ||
|
|
ba335089c4 | ||
|
|
9c72e73a82 | ||
|
|
30d7f0dc98 | ||
|
|
2c9a6e7bef | ||
|
|
e25305e3cc | ||
|
|
f9599da32d | ||
|
|
be9cbd79d6 | ||
|
|
59c6f76457 | ||
|
|
2302c8d5fa | ||
|
|
a19373ab54 | ||
|
|
205469316c | ||
|
|
2a6f979ce6 | ||
|
|
9362ae0687 | ||
|
|
63a2657aef | ||
|
|
7080b256fb | ||
|
|
def62e8c22 | ||
|
|
1ed11b297b | ||
|
|
ef0ea247c4 | ||
|
|
3eba5b0aac | ||
|
|
357e1c0802 | ||
|
|
00137f2905 | ||
|
|
98a0959784 | ||
|
|
890f96d9b5 | ||
|
|
c0569da65c | ||
|
|
2a07441c19 | ||
|
|
7581cbade6 | ||
|
|
583513bafd | ||
|
|
43ca8ea5f7 | ||
|
|
a5cfdd2cfe | ||
|
|
62dfd1fa7d | ||
|
|
38548c9acd | ||
|
|
038bf612be | ||
|
|
f02c86cb22 | ||
|
|
a55b43b67e | ||
|
|
31bd701bd5 | ||
|
|
9bfb0d93ca | ||
|
|
897105de02 | ||
|
|
19c5889775 | ||
|
|
13d915927b | ||
|
|
7046f1a902 | ||
|
|
76700d17d6 | ||
|
|
f8d428cb2d | ||
|
|
93e55e2631 | ||
|
|
1797b6c7f9 | ||
|
|
581f4ed757 | ||
|
|
0ec3ee29e4 | ||
|
|
bb58a50503 | ||
|
|
f2de440886 | ||
|
|
d4fdd50e2c | ||
|
|
dd1bb18938 | ||
|
|
1f9239089f | ||
|
|
b2a7a3ed30 | ||
|
|
2b7e599dc4 | ||
|
|
61d4d17225 | ||
|
|
408954e4d8 | ||
|
|
87cd72496c | ||
|
|
cb524b6c19 | ||
|
|
bc6685aa3f | ||
|
|
5458c02cc2 | ||
|
|
33db0c13cd | ||
|
|
9128ec72ad | ||
|
|
80eb0a2df6 | ||
|
|
437bba1e3c | ||
|
|
15e4b7f95d | ||
|
|
d607c13ab6 | ||
|
|
9585390941 | ||
|
|
b2cb284ff2 | ||
|
|
7d84cfacef | ||
|
|
39862740e0 | ||
|
|
579c955892 | ||
|
|
175c71221a | ||
|
|
60965b0d8c | ||
|
|
a27dac029f | ||
|
|
36abf8733e | ||
|
|
9acc71a7cb | ||
|
|
9e6f28e335 | ||
|
|
29aec0d770 | ||
|
|
c5193cf03f | ||
|
|
06514159be | ||
|
|
daad62c4e0 | ||
|
|
1ab75eb6f4 | ||
|
|
118840dad4 | ||
|
|
c2d97b98e2 | ||
|
|
e36b42a03f | ||
|
|
f3661c34ee | ||
|
|
95742aec69 | ||
|
|
64f8316a6d | ||
|
|
1e327289b2 | ||
|
|
50abb6e3a1 | ||
|
|
5c2bf68a05 | ||
|
|
f8d45f04ed | ||
|
|
40b74167e0 | ||
|
|
3c8ea167c4 | ||
|
|
6ed1016bb8 | ||
|
|
92b4eb7f02 | ||
|
|
e1028a2765 | ||
|
|
5c79ad2412 | ||
|
|
af0c32c01d | ||
|
|
605f28f741 | ||
|
|
946fcf1c82 | ||
|
|
b0975bb3ea | ||
|
|
451d36dc97 | ||
|
|
c9c8259ed0 | ||
|
|
5d827b6fc8 | ||
|
|
3e7dc12246 | ||
|
|
c37994089c | ||
|
|
254de76078 | ||
|
|
dedf765542 | ||
|
|
b359205d17 | ||
|
|
578ce1e512 | ||
|
|
7fbc62358e | ||
|
|
0e183ab4a4 | ||
|
|
fa36ba901a | ||
|
|
d269a7e717 | ||
|
|
216f204438 | ||
|
|
583d0889e2 | ||
|
|
5d05e4d224 | ||
|
|
0f24db8759 | ||
|
|
f8570bb293 | ||
|
|
cb736c8c82 | ||
|
|
972cc47f67 | ||
|
|
b4a2a9db25 | ||
|
|
bd3b3178ba | ||
|
|
b3bdf89fc2 | ||
|
|
4be183c7f6 | ||
|
|
b30ae3980c | ||
|
|
fe57876fd8 | ||
|
|
897d12420b | ||
|
|
97186b3d30 | ||
|
|
56ba0f080a | ||
|
|
a7fcf52267 | ||
|
|
392adf2a25 | ||
|
|
b29f35f564 | ||
|
|
64fed4cb10 | ||
|
|
b4f01c9afa | ||
|
|
53a320a810 | ||
|
|
bb447d7174 | ||
|
|
447f339857 | ||
|
|
92508beb82 | ||
|
|
f43d427875 | ||
|
|
bc7cc2f7ce | ||
|
|
da36508714 | ||
|
|
591ac38c31 | ||
|
|
54c79bff74 | ||
|
|
2e40d01397 | ||
|
|
44d2bf42d7 | ||
|
|
fd23e0bdda | ||
|
|
3b6cd0f681 | ||
|
|
9de8085571 | ||
|
|
2d0c9b6bf2 | ||
|
|
55723618a9 | ||
|
|
2965a1f204 | ||
|
|
5158e7964e | ||
|
|
36fe72246b | ||
|
|
4810308b16 | ||
|
|
77208bcc91 | ||
|
|
e2ed0d02b0 | ||
|
|
37dae67a0d | ||
|
|
419d25cbcf | ||
|
|
981c5deb57 | ||
|
|
d853f0c400 | ||
|
|
a6bb9ebb9f | ||
|
|
079c7e089d | ||
|
|
273e8ce4ef | ||
|
|
00235ed3b3 | ||
|
|
25b012db48 | ||
|
|
5f7d3d0d36 | ||
|
|
7be45e7c5e | ||
|
|
6e73d13670 | ||
|
|
2890fe6d61 | ||
|
|
7ed09904b4 | ||
|
|
aa52585120 | ||
|
|
89a5acf6e8 | ||
|
|
7f131c1f35 | ||
|
|
1008411594 | ||
|
|
d1457995dd | ||
|
|
a404faa302 | ||
|
|
7825a2cdfc | ||
|
|
1a4845f417 | ||
|
|
f93b68d4dc | ||
|
|
98d936d8b3 | ||
|
|
f341d5010d | ||
|
|
9b0ef2fe21 | ||
|
|
58d198261e | ||
|
|
646639bc73 | ||
|
|
f22b11881e | ||
|
|
45e1a61d7b | ||
|
|
e77117f902 | ||
|
|
929d9da4b4 | ||
|
|
7c13163413 | ||
|
|
15c103e42d | ||
|
|
dee974ff2d | ||
|
|
c37dbb2e68 | ||
|
|
3cfd30ef6f | ||
|
|
be39883166 | ||
|
|
afd2f58f9f | ||
|
|
697b2dcde8 | ||
|
|
0102d68f38 | ||
|
|
e0fcb15739 | ||
|
|
b96b665262 | ||
|
|
037e6369ce | ||
|
|
d7f26dfc18 | ||
|
|
fda750ef26 | ||
|
|
423ff32d04 | ||
|
|
6d4ddc0329 | ||
|
|
bc56d16c18 | ||
|
|
dfc91b8331 | ||
|
|
bb23866cec | ||
|
|
d35a501121 | ||
|
|
a43698802f | ||
|
|
310a2c8bb3 | ||
|
|
2656a52880 | ||
|
|
abeefcaced | ||
|
|
5aeaab7c6d | ||
|
|
58d5ad48d5 | ||
|
|
d7c14775bf | ||
|
|
11bf982728 | ||
|
|
32737a17fb | ||
|
|
172d6139e2 | ||
|
|
c281e54d22 | ||
|
|
57016ddbde | ||
|
|
7d2a60e910 | ||
|
|
b4d35b52c3 | ||
|
|
5446532e1d | ||
|
|
acd4cf2878 | ||
|
|
e8d835b422 | ||
|
|
c7686b1838 | ||
|
|
cf5f838b13 | ||
|
|
e003b04061 | ||
|
|
cd57e61f65 | ||
|
|
91d28fb8b0 | ||
|
|
63f087a8e9 | ||
|
|
364d48948f | ||
|
|
17c4bbbc4e | ||
|
|
1b948ac2e2 | ||
|
|
feb3a8deb1 | ||
|
|
6924c6c51c | ||
|
|
3da88f2103 | ||
|
|
17d1c77a14 | ||
|
|
4f2060f96b | ||
|
|
10be2735ec | ||
|
|
d90527bead | ||
|
|
9349e6922d | ||
|
|
eeae91e620 | ||
|
|
046aeaa38c | ||
|
|
8b756d7f1b | ||
|
|
650446f761 | ||
|
|
a5ebe8c600 | ||
|
|
8687c5c145 | ||
|
|
8a7d28a2ed | ||
|
|
4c21980d4f | ||
|
|
9635a36044 | ||
|
|
760231c004 | ||
|
|
c77c7b0a98 | ||
|
|
837f20108d | ||
|
|
157e4670fd | ||
|
|
79c1374925 | ||
|
|
1510048f7a | ||
|
|
d8165145c7 | ||
|
|
ebd38eaf3b | ||
|
|
b8c11503f0 | ||
|
|
0a86642056 | ||
|
|
4e3791dc0d | ||
|
|
720fbaf301 | ||
|
|
1510fe370d | ||
|
|
2329b31601 | ||
|
|
a460e3ad3d | ||
|
|
cc4827600b | ||
|
|
04b0682bbf | ||
|
|
fd8f745468 | ||
|
|
f130616369 | ||
|
|
d2b874f217 | ||
|
|
6874b8d4b3 | ||
|
|
affdedd840 | ||
|
|
0a6aef71a2 | ||
|
|
53daa7c436 | ||
|
|
11304b2ae1 | ||
|
|
7f01586bf1 | ||
|
|
e5bce548de | ||
|
|
956311457d | ||
|
|
9b3ccade43 | ||
|
|
3d117243e4 | ||
|
|
02eb447a35 | ||
|
|
a6b486a448 | ||
|
|
d73ba13b28 | ||
|
|
b39a3ab12c | ||
|
|
83477439a1 | ||
|
|
b7483a5394 | ||
|
|
322bdcb703 | ||
|
|
8ce5c46e05 | ||
|
|
675de07c3e | ||
|
|
ed34c96357 | ||
|
|
eb9b41acab | ||
|
|
a764a79090 | ||
|
|
c13ee0859a | ||
|
|
3d8e173c57 | ||
|
|
80ac2aff26 | ||
|
|
6c69c1aeeb | ||
|
|
cbf158ea6b | ||
|
|
36de496d47 | ||
|
|
ed2a8db8c9 | ||
|
|
9c3b7e81c7 | ||
|
|
a93132daae | ||
|
|
43ae7462b4 | ||
|
|
b44db460f6 | ||
|
|
cc63563a88 | ||
|
|
8e11abca40 | ||
|
|
32a8b9a857 | ||
|
|
480ce39618 | ||
|
|
ecbce88ec7 | ||
|
|
9ff894bf83 | ||
|
|
8159098dc0 | ||
|
|
1349bf7b0b | ||
|
|
0775d35591 | ||
|
|
3f215d0954 | ||
|
|
093c63ea3b | ||
|
|
5ce3f9d6ff | ||
|
|
a53cbc1631 | ||
|
|
a72b1340eb | ||
|
|
b21672c81c | ||
|
|
d33b04cd96 | ||
|
|
2ca95166d9 | ||
|
|
2576c86ebf | ||
|
|
57bd3f3c14 | ||
|
|
fe0e7f5eac | ||
|
|
08c3bf26d5 | ||
|
|
3df23eecb6 | ||
|
|
c8a6e837b5 | ||
|
|
701b935564 | ||
|
|
6c24699403 | ||
|
|
adb1ed380a | ||
|
|
73e940de74 | ||
|
|
0200aedc2e | ||
|
|
26bac9f425 | ||
|
|
1385b22642 | ||
|
|
15206fd2ce | ||
|
|
98204a15a6 | ||
|
|
1a2e341b7c | ||
|
|
c8b1bc3a89 | ||
|
|
0a35feef76 | ||
|
|
eeac7e322a | ||
|
|
a0a1ddee86 | ||
|
|
f0ddfc9283 | ||
|
|
72f28513eb | ||
|
|
48975fa7d2 | ||
|
|
31eaa80f5b | ||
|
|
a93aabab40 | ||
|
|
919c6b4b0a | ||
|
|
10cc574289 | ||
|
|
01c13c4703 | ||
|
|
c5577cb09a | ||
|
|
502cf38fcc | ||
|
|
1b1c3f953b | ||
|
|
b366ffa69e | ||
|
|
95d1994196 | ||
|
|
f795d5e0d3 | ||
|
|
0521ef87da | ||
|
|
6fe8bafc7d | ||
|
|
872a000a33 | ||
|
|
8119fd2ad1 | ||
|
|
26b030f8cc | ||
|
|
dc73fcc4e8 | ||
|
|
dc58f6fa87 |
30
.github/workflows/close-stale.yml
vendored
Normal file
30
.github/workflows/close-stale.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
name: Mark stale issues
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: "30 1 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
if: github.repository == 'github/codeql'
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v3
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Comment or remove the `Stale` label in order to avoid having this issue closed in 7 days.'
|
||||||
|
close-issue-message: 'This issue was closed because it has been inactive for 7 days.'
|
||||||
|
days-before-stale: 14
|
||||||
|
days-before-close: 7
|
||||||
|
only-labels: awaiting-response
|
||||||
|
|
||||||
|
# do not mark PRs as stale
|
||||||
|
days-before-pr-stale: -1
|
||||||
|
days-before-pr-close: -1
|
||||||
|
|
||||||
|
# Uncomment for dry-run
|
||||||
|
# debug-only: true
|
||||||
|
# operations-per-run: 1000
|
||||||
11
.github/workflows/codeql-analysis.yml
vendored
11
.github/workflows/codeql-analysis.yml
vendored
@@ -19,13 +19,18 @@ jobs:
|
|||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security_events: write
|
||||||
|
pull_requests: read
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v1
|
uses: github/codeql-action/init@main
|
||||||
# Override language selection by uncommenting this and choosing your languages
|
# Override language selection by uncommenting this and choosing your languages
|
||||||
with:
|
with:
|
||||||
languages: csharp
|
languages: csharp
|
||||||
@@ -34,7 +39,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v1
|
uses: github/codeql-action/autobuild@main
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -48,4 +53,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@main
|
||||||
|
|||||||
@@ -56,6 +56,10 @@
|
|||||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
|
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
|
||||||
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll"
|
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll"
|
||||||
],
|
],
|
||||||
|
"DataFlow Java/C# Flow Summaries": [
|
||||||
|
"java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
|
||||||
|
"csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll"
|
||||||
|
],
|
||||||
"SsaReadPosition Java/C#": [
|
"SsaReadPosition Java/C#": [
|
||||||
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
||||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
|
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
|
||||||
|
|||||||
2
cpp/change-notes/2021-04-13-arithmetic-queries.md
Normal file
2
cpp/change-notes/2021-04-13-arithmetic-queries.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
lgtm
|
||||||
|
* The queries cpp/tainted-arithmetic, cpp/uncontrolled-arithmetic, and cpp/arithmetic-with-extreme-values have been improved to produce fewer false positives.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
codescanning
|
||||||
|
* The 'Pointer to stack object used as return value' (cpp/return-stack-allocated-object) query has been deprecated, and any uses should be replaced with `Returning stack-allocated memory` (cpp/return-stack-allocated-memory).
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
* @tags reliability
|
* @tags reliability
|
||||||
* security
|
* security
|
||||||
* external/cwe/cwe-562
|
* external/cwe/cwe-562
|
||||||
|
* @deprecated This query is not suitable for production use and has been deprecated. Use
|
||||||
|
* cpp/return-stack-allocated-memory instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import semmle.code.cpp.pointsto.PointsTo
|
import semmle.code.cpp.pointsto.PointsTo
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.dataflow.EscapesTree
|
import semmle.code.cpp.dataflow.EscapesTree
|
||||||
|
import semmle.code.cpp.models.interfaces.PointerWrapper
|
||||||
import semmle.code.cpp.dataflow.DataFlow
|
import semmle.code.cpp.dataflow.DataFlow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +40,10 @@ predicate hasNontrivialConversion(Expr e) {
|
|||||||
e instanceof ParenthesisExpr
|
e instanceof ParenthesisExpr
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
// A smart pointer can be stack-allocated while the data it points to is heap-allocated.
|
||||||
|
// So we exclude such "conversions" from this predicate.
|
||||||
|
e = any(PointerWrapper wrapper).getAnUnwrapperFunction().getACallToThisFunction()
|
||||||
|
or
|
||||||
hasNontrivialConversion(e.getConversion())
|
hasNontrivialConversion(e.getConversion())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
while(flagsLoop)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
if(flagsIf) break;
|
||||||
|
...
|
||||||
|
}while(flagsLoop); // BAD: when exiting through `break`, it is possible to get into an eternal loop.
|
||||||
|
...
|
||||||
|
while(flagsLoop)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
if(flagsIf) break;
|
||||||
|
...
|
||||||
|
} // GOOD: correct cycle
|
||||||
|
...
|
||||||
|
if(intA+intB) return 1; // BAD: possibly no comparison
|
||||||
|
...
|
||||||
|
if(intA+intB>intC) return 1; // GOOD: correct comparison
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE qhelp PUBLIC
|
||||||
|
"-//Semmle//qhelp//EN"
|
||||||
|
"qhelp.dtd">
|
||||||
|
<qhelp>
|
||||||
|
<overview>
|
||||||
|
<p>In some situations, after code refactoring, parts of the old constructs may remain. They are correctly accepted by the compiler, but can critically affect program execution. For example, if you switch from `do {...} while ();` to `while () {...}` forgetting to remove the old construct completely, you get `while(){...}while();` which may be vulnerable. These code snippets look suspicious and require the developer's attention.</p>
|
||||||
|
|
||||||
|
|
||||||
|
</overview>
|
||||||
|
<recommendation>
|
||||||
|
|
||||||
|
<p>We recommend that you use more explicit code transformations.</p>
|
||||||
|
|
||||||
|
</recommendation>
|
||||||
|
<example>
|
||||||
|
<p>The following example demonstrates the erroneous and corrected sections of the code.</p>
|
||||||
|
<sample src="InsufficientControlFlowManagementAfterRefactoringTheCode.c" />
|
||||||
|
|
||||||
|
</example>
|
||||||
|
<references>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
CWE Common Weakness Enumeration:
|
||||||
|
<a href="https://cwe.mitre.org/data/definitions/691.html"> CWE-691: Insufficient Control Flow Management</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</references>
|
||||||
|
</qhelp>
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* @name Errors After Refactoring
|
||||||
|
* @description --In some situations, after code refactoring, parts of the old constructs may remain.
|
||||||
|
* --They are correctly accepted by the compiler, but can critically affect program execution.
|
||||||
|
* --For example, if you switch from `do {...} while ();` to `while () {...}` with errors, you run the risk of running out of resources.
|
||||||
|
* --These code snippets look suspicious and require the developer's attention.
|
||||||
|
* @kind problem
|
||||||
|
* @id cpp/errors-after-refactoring
|
||||||
|
* @problem.severity warning
|
||||||
|
* @precision medium
|
||||||
|
* @tags correctness
|
||||||
|
* security
|
||||||
|
* external/cwe/cwe-691
|
||||||
|
*/
|
||||||
|
|
||||||
|
import cpp
|
||||||
|
import semmle.code.cpp.valuenumbering.HashCons
|
||||||
|
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using `while` directly after the body of another` while`.
|
||||||
|
*/
|
||||||
|
class UsingWhileAfterWhile extends WhileStmt {
|
||||||
|
/**
|
||||||
|
* Using a loop call after another loop has finished running can result in an eternal loop.
|
||||||
|
* For example, perhaps as a result of refactoring, the `do ... while ()` loop was incorrectly corrected.
|
||||||
|
* Even in the case of deliberate use of such an expression, it is better to correct it.
|
||||||
|
*/
|
||||||
|
UsingWhileAfterWhile() {
|
||||||
|
exists(WhileStmt wh1 |
|
||||||
|
wh1.getStmt().getAChild*().(BreakStmt).(ControlFlowNode).getASuccessor().getASuccessor() =
|
||||||
|
this and
|
||||||
|
hashCons(wh1.getCondition()) = hashCons(this.getCondition()) and
|
||||||
|
this.getStmt() instanceof EmptyStmt
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(ForStmt fr1 |
|
||||||
|
fr1.getStmt().getAChild*().(BreakStmt).(ControlFlowNode).getASuccessor().getASuccessor() =
|
||||||
|
this and
|
||||||
|
hashCons(fr1.getCondition()) = hashCons(this.getCondition()) and
|
||||||
|
this.getStmt() instanceof EmptyStmt
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using arithmetic in a condition.
|
||||||
|
*/
|
||||||
|
class UsingArithmeticInComparison extends BinaryArithmeticOperation {
|
||||||
|
/**
|
||||||
|
* Using arithmetic operations in a comparison operation can be dangerous.
|
||||||
|
* For example, part of the comparison may have been lost as a result of refactoring.
|
||||||
|
* Even if you deliberately use such an expression, it is better to add an explicit comparison.
|
||||||
|
*/
|
||||||
|
UsingArithmeticInComparison() {
|
||||||
|
this.getParent*() instanceof IfStmt and
|
||||||
|
not this.getAChild*().isConstant() and
|
||||||
|
not this.getParent*() instanceof Call and
|
||||||
|
not this.getParent*() instanceof AssignExpr and
|
||||||
|
not this.getParent*() instanceof ArrayExpr and
|
||||||
|
not this.getParent*() instanceof RemExpr and
|
||||||
|
not this.getParent*() instanceof AssignBitwiseOperation and
|
||||||
|
not this.getParent*() instanceof AssignArithmeticOperation and
|
||||||
|
not this.getParent*() instanceof EqualityOperation and
|
||||||
|
not this.getParent*() instanceof RelationalOperation
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds when the expression is inside the loop body. */
|
||||||
|
predicate insideTheLoop() { exists(Loop lp | lp.getStmt().getAChild*() = this.getParent*()) }
|
||||||
|
|
||||||
|
/** Holds when the expression is used in binary operations. */
|
||||||
|
predicate workingWithValue() {
|
||||||
|
this.getParent*() instanceof BinaryBitwiseOperation or
|
||||||
|
this.getParent*() instanceof NotExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds when the expression contains a pointer. */
|
||||||
|
predicate workingWithPointer() {
|
||||||
|
this.getAChild*().getFullyConverted().getType() instanceof DerivedType
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds when a null comparison expression exists. */
|
||||||
|
predicate compareWithZero() {
|
||||||
|
exists(Expr exp |
|
||||||
|
exp instanceof ComparisonOperation and
|
||||||
|
(
|
||||||
|
globalValueNumber(exp.getAChild*()) = globalValueNumber(this) or
|
||||||
|
hashCons(exp.getAChild*()) = hashCons(this)
|
||||||
|
) and
|
||||||
|
(
|
||||||
|
exp.(ComparisonOperation).getLeftOperand().getValue() = "0" or
|
||||||
|
exp.(ComparisonOperation).getRightOperand().getValue() = "0"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds when a comparison expression exists. */
|
||||||
|
predicate compareWithOutZero() {
|
||||||
|
exists(Expr exp |
|
||||||
|
exp instanceof ComparisonOperation and
|
||||||
|
(
|
||||||
|
globalValueNumber(exp.getAChild*()) = globalValueNumber(this) or
|
||||||
|
hashCons(exp.getAChild*()) = hashCons(this)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from Expr exp
|
||||||
|
where
|
||||||
|
exp instanceof UsingArithmeticInComparison and
|
||||||
|
not exp.(UsingArithmeticInComparison).workingWithValue() and
|
||||||
|
not exp.(UsingArithmeticInComparison).workingWithPointer() and
|
||||||
|
not exp.(UsingArithmeticInComparison).insideTheLoop() and
|
||||||
|
not exp.(UsingArithmeticInComparison).compareWithZero() and
|
||||||
|
exp.(UsingArithmeticInComparison).compareWithOutZero()
|
||||||
|
or
|
||||||
|
exists(WhileStmt wst | wst instanceof UsingWhileAfterWhile and exp = wst.getCondition())
|
||||||
|
select exp, "this expression needs your attention"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
if(len>0 & memset(buf,0,len)) return 1; // BAD: `memset` will be called regardless of the value of the `len` variable. moreover, one cannot be sure that it will happen after verification
|
||||||
|
...
|
||||||
|
if(len>0 && memset(buf,0,len)) return 1; // GOOD: `memset` will be called after the `len` variable has been checked.
|
||||||
|
...
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE qhelp PUBLIC
|
||||||
|
"-//Semmle//qhelp//EN"
|
||||||
|
"qhelp.dtd">
|
||||||
|
<qhelp>
|
||||||
|
<overview>
|
||||||
|
<p>Using bitwise operations can be a mistake in some situations. For example, if parameters are evaluated in an expression and the function should be called only upon certain test results. These bitwise operations look suspicious and require developer attention.</p>
|
||||||
|
|
||||||
|
|
||||||
|
</overview>
|
||||||
|
<recommendation>
|
||||||
|
|
||||||
|
<p>We recommend that you evaluate the correctness of using the specified bit operations.</p>
|
||||||
|
|
||||||
|
</recommendation>
|
||||||
|
<example>
|
||||||
|
<p>The following example demonstrates the erroneous and fixed use of bit and logical operations.</p>
|
||||||
|
<sample src="InsufficientControlFlowManagementWhenUsingBitOperations.c" />
|
||||||
|
|
||||||
|
</example>
|
||||||
|
<references>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
CWE Common Weakness Enumeration:
|
||||||
|
<a href="https://cwe.mitre.org/data/definitions/691.html"> CWE-691: Insufficient Control Flow Management</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</references>
|
||||||
|
</qhelp>
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* @name Errors When Using Bit Operations
|
||||||
|
* @description Unlike the binary operations `||` and `&&`, there is no sequence point after evaluating an
|
||||||
|
* operand of a bitwise operation like `|` or `&`. If left-to-right evaluation is expected this may be confusing.
|
||||||
|
* @kind problem
|
||||||
|
* @id cpp/errors-when-using-bit-operations
|
||||||
|
* @problem.severity warning
|
||||||
|
* @precision medium
|
||||||
|
* @tags correctness
|
||||||
|
* security
|
||||||
|
* external/cwe/cwe-691
|
||||||
|
*/
|
||||||
|
|
||||||
|
import cpp
|
||||||
|
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dangerous uses of bit operations.
|
||||||
|
* For example: `if(intA>0 & intA<10 & charBuf&myFunc(charBuf[intA]))`.
|
||||||
|
* In this case, the function will be called in any case, and even the sequence of the call is not guaranteed.
|
||||||
|
*/
|
||||||
|
class DangerousBitOperations extends BinaryBitwiseOperation {
|
||||||
|
FunctionCall bfc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The assignment indicates the conscious use of the bit operator.
|
||||||
|
* Use in comparison, conversion, or return value indicates conscious use of the bit operator.
|
||||||
|
* The use of shifts and bitwise operations on any element of an expression indicates a conscious use of the bitwise operator.
|
||||||
|
*/
|
||||||
|
DangerousBitOperations() {
|
||||||
|
bfc = this.getRightOperand() and
|
||||||
|
not this.getParent*() instanceof Assignment and
|
||||||
|
not this.getParent*() instanceof Initializer and
|
||||||
|
not this.getParent*() instanceof ReturnStmt and
|
||||||
|
not this.getParent*() instanceof EqualityOperation and
|
||||||
|
not this.getParent*() instanceof UnaryLogicalOperation and
|
||||||
|
not this.getParent*() instanceof BinaryLogicalOperation and
|
||||||
|
not this.getAChild*() instanceof BitwiseXorExpr and
|
||||||
|
not this.getAChild*() instanceof LShiftExpr and
|
||||||
|
not this.getAChild*() instanceof RShiftExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds when part of a bit expression is used in a logical operation. */
|
||||||
|
predicate useInLogicalOperations() {
|
||||||
|
exists(BinaryLogicalOperation blop, Expr exp |
|
||||||
|
blop.getAChild*() = exp and
|
||||||
|
exp.(FunctionCall).getTarget() = bfc.getTarget() and
|
||||||
|
not exp.getParent() instanceof ComparisonOperation and
|
||||||
|
not exp.getParent() instanceof BinaryBitwiseOperation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds when part of a bit expression is used as part of another supply. For example, as an argument to another function. */
|
||||||
|
predicate useInOtherCalls() {
|
||||||
|
bfc.hasQualifier() or
|
||||||
|
bfc.getTarget() instanceof Operator or
|
||||||
|
exists(FunctionCall fc | fc.getAnArgument().getAChild*() = this) or
|
||||||
|
bfc.getTarget() instanceof BuiltInFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds when the bit expression contains both arguments and a function call. */
|
||||||
|
predicate dangerousArgumentChecking() {
|
||||||
|
not this.getLeftOperand() instanceof Call and
|
||||||
|
globalValueNumber(this.getLeftOperand().getAChild*()) = globalValueNumber(bfc.getAnArgument())
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds when function calls are present in the bit expression. */
|
||||||
|
predicate functionCallsInBitsExpression() {
|
||||||
|
this.getLeftOperand().getAChild*() instanceof FunctionCall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from DangerousBitOperations dbo
|
||||||
|
where
|
||||||
|
not dbo.useInOtherCalls() and
|
||||||
|
dbo.useInLogicalOperations() and
|
||||||
|
(not dbo.functionCallsInBitsExpression() or dbo.dangerousArgumentChecking())
|
||||||
|
select dbo, "This bitwise operation appears in a context where a Boolean operation is expected."
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
if(len=funcReadData()==0) return 1; // BAD: variable `len` will not equal the value returned by function `funcReadData()`
|
||||||
|
...
|
||||||
|
if((len=funcReadData())==0) return 1; // GOOD: variable `len` equal the value returned by function `funcReadData()`
|
||||||
|
...
|
||||||
|
bool a=true;
|
||||||
|
a++;// BAD: variable `a` does not change its meaning
|
||||||
|
bool b;
|
||||||
|
b=-a;// BAD: variable `b` equal `true`
|
||||||
|
...
|
||||||
|
a=false;// GOOD: variable `a` equal `false`
|
||||||
|
b=!a;// GOOD: variable `b` equal `false`
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE qhelp PUBLIC
|
||||||
|
"-//Semmle//qhelp//EN"
|
||||||
|
"qhelp.dtd">
|
||||||
|
<qhelp>
|
||||||
|
<overview>
|
||||||
|
<p>Finding places of confusing use of boolean type. For example, a unary minus does not work before a boolean type and an increment always gives true.</p>
|
||||||
|
|
||||||
|
|
||||||
|
</overview>
|
||||||
|
<recommendation>
|
||||||
|
|
||||||
|
<p>we recommend making the code simpler.</p>
|
||||||
|
|
||||||
|
</recommendation>
|
||||||
|
<example>
|
||||||
|
<p>The following example demonstrates erroneous and fixed methods for using a boolean data type.</p>
|
||||||
|
<sample src="OperatorPrecedenceLogicErrorWhenUseBoolType.c" />
|
||||||
|
|
||||||
|
</example>
|
||||||
|
<references>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
CERT C Coding Standard:
|
||||||
|
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP00-C.+Use+parentheses+for+precedence+of+operation">EXP00-C. Use parentheses for precedence of operation</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</references>
|
||||||
|
</qhelp>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* @name Operator Precedence Logic Error When Use Bool Type
|
||||||
|
* @description --Finding places of confusing use of boolean type.
|
||||||
|
* --For example, a unary minus does not work before a boolean type and an increment always gives true.
|
||||||
|
* @kind problem
|
||||||
|
* @id cpp/operator-precedence-logic-error-when-use-bool-type
|
||||||
|
* @problem.severity warning
|
||||||
|
* @precision medium
|
||||||
|
* @tags correctness
|
||||||
|
* security
|
||||||
|
* external/cwe/cwe-783
|
||||||
|
* external/cwe/cwe-480
|
||||||
|
*/
|
||||||
|
|
||||||
|
import cpp
|
||||||
|
import semmle.code.cpp.valuenumbering.HashCons
|
||||||
|
|
||||||
|
/** Holds if `exp` increments a boolean value. */
|
||||||
|
predicate incrementBoolType(IncrementOperation exp) {
|
||||||
|
exp.getOperand().getType() instanceof BoolType
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if `exp` applies the unary minus operator to a boolean type. */
|
||||||
|
predicate revertSignBoolType(UnaryMinusExpr exp) {
|
||||||
|
exp.getAnOperand().getType() instanceof BoolType and
|
||||||
|
exp.getFullyConverted().getType() instanceof BoolType
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds, if this is an expression, uses comparison and assignment outside of execution precedence. */
|
||||||
|
predicate assignBoolType(Expr exp) {
|
||||||
|
exists(ComparisonOperation co |
|
||||||
|
exp.(AssignExpr).getRValue() = co and
|
||||||
|
exp.isCondition() and
|
||||||
|
not co.isParenthesised() and
|
||||||
|
not exp.(AssignExpr).getLValue().getType() instanceof BoolType and
|
||||||
|
not exists(Expr exbl |
|
||||||
|
hashCons(exbl.(AssignExpr).getLValue()) = hashCons(exp.(AssignExpr).getLValue()) and
|
||||||
|
not exbl.isCondition() and
|
||||||
|
exbl.(AssignExpr).getRValue().getType() instanceof BoolType and
|
||||||
|
exbl.(AssignExpr).getLValue().getType() = exp.(AssignExpr).getLValue().getType()
|
||||||
|
) and
|
||||||
|
co.getLeftOperand() instanceof FunctionCall and
|
||||||
|
not co.getRightOperand().getType() instanceof BoolType and
|
||||||
|
not co.getRightOperand().getValue() = "0" and
|
||||||
|
not co.getRightOperand().getValue() = "1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
from Expr exp
|
||||||
|
where
|
||||||
|
incrementBoolType(exp) or
|
||||||
|
revertSignBoolType(exp) or
|
||||||
|
assignBoolType(exp)
|
||||||
|
select exp, "this expression needs attention"
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
* @description The expression `buffer [strlen (buffer)] = 0` is potentially dangerous, if the variable `buffer` does not have a terminal zero, then access beyond the bounds of the allocated memory is possible, which will lead to undefined behavior.
|
* @description The expression `buffer [strlen (buffer)] = 0` is potentially dangerous, if the variable `buffer` does not have a terminal zero, then access beyond the bounds of the allocated memory is possible, which will lead to undefined behavior.
|
||||||
* If terminal zero is present, then the specified expression is meaningless.
|
* If terminal zero is present, then the specified expression is meaningless.
|
||||||
* @kind problem
|
* @kind problem
|
||||||
* @id cpp/access-memory-location-after-end-buffer
|
* @id cpp/access-memory-location-after-end-buffer-strlen
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @tags correctness
|
* @tags correctness
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @name Access Of Memory Location After The End Of A Buffer Using Strncat
|
* @name Access Of Memory Location After The End Of A Buffer Using Strncat
|
||||||
* @description Calls of the form `strncat(dest, source, sizeof (dest) - strlen (dest))` set the third argument to one more than possible. So when `dest` is full, the expression `sizeof(dest) - strlen (dest)` will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the `dest` buffer.
|
* @description Calls of the form `strncat(dest, source, sizeof (dest) - strlen (dest))` set the third argument to one more than possible. So when `dest` is full, the expression `sizeof(dest) - strlen (dest)` will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the `dest` buffer.
|
||||||
* @kind problem
|
* @kind problem
|
||||||
* @id cpp/access-memory-location-after-end-buffer
|
* @id cpp/access-memory-location-after-end-buffer-strncat
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @tags correctness
|
* @tags correctness
|
||||||
@@ -11,54 +11,32 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
|
import semmle.code.cpp.models.implementations.Strcat
|
||||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A call to `strncat` of the form `strncat(buff, str, someExpr - strlen(buf))`, for some expression `someExpr` equal to `sizeof(buff)`.
|
* Holds if `call` is a call to `strncat` such that `sizeArg` and `destArg` are the size and
|
||||||
|
* destination arguments, respectively.
|
||||||
*/
|
*/
|
||||||
class WrongCallStrncat extends FunctionCall {
|
predicate interestringCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
|
||||||
Expr leftsomeExpr;
|
exists(StrcatFunction strcat |
|
||||||
|
strcat = call.getTarget() and
|
||||||
WrongCallStrncat() {
|
sizeArg = call.getArgument(strcat.getParamSize()) and
|
||||||
this.getTarget().hasGlobalOrStdName("strncat") and
|
destArg = call.getArgument(strcat.getParamDest())
|
||||||
// the expression of the first argument in `strncat` and `strnlen` is identical
|
)
|
||||||
globalValueNumber(this.getArgument(0)) =
|
|
||||||
globalValueNumber(this.getArgument(2).(SubExpr).getRightOperand().(StrlenCall).getStringExpr()) and
|
|
||||||
// using a string constant often speaks of manually calculating the length of the required buffer.
|
|
||||||
(
|
|
||||||
not this.getArgument(1) instanceof StringLiteral and
|
|
||||||
not this.getArgument(1) instanceof CharLiteral
|
|
||||||
) and
|
|
||||||
// for use in predicates
|
|
||||||
leftsomeExpr = this.getArgument(2).(SubExpr).getLeftOperand()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the left side of the expression `someExpr` equal to `sizeof(buf)`.
|
|
||||||
*/
|
|
||||||
predicate isExpressionEqualSizeof() {
|
|
||||||
// the left side of the expression `someExpr` is `sizeof(buf)`.
|
|
||||||
globalValueNumber(this.getArgument(0)) =
|
|
||||||
globalValueNumber(leftsomeExpr.(SizeofExprOperator).getExprOperand())
|
|
||||||
or
|
|
||||||
// value of the left side of the expression `someExpr` equal `sizeof(buf)` value, and `buf` is array.
|
|
||||||
leftsomeExpr.getValue().toInt() = this.getArgument(0).getType().getSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the left side of the expression `someExpr` equal to variable containing the length of the memory allocated for the buffer.
|
|
||||||
*/
|
|
||||||
predicate isVariableEqualValueSizegBuffer() {
|
|
||||||
// the left side of expression `someExpr` is the variable that was used in the function of allocating memory for the buffer`.
|
|
||||||
exists(AllocationExpr alc |
|
|
||||||
leftsomeExpr.(VariableAccess).getTarget() =
|
|
||||||
alc.(FunctionCall).getArgument(0).(VariableAccess).getTarget()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
from WrongCallStrncat sc
|
from FunctionCall call, Expr sizeArg, Expr destArg, SubExpr sub, int n
|
||||||
where
|
where
|
||||||
sc.isExpressionEqualSizeof() or
|
interestringCallWithArgs(call, sizeArg, destArg) and
|
||||||
sc.isVariableEqualValueSizegBuffer()
|
// The destination buffer is an array of size n
|
||||||
select sc, "if the used buffer is full, writing out of the buffer is possible"
|
destArg.getUnspecifiedType().(ArrayType).getSize() = n and
|
||||||
|
// The size argument is equivalent to a subtraction
|
||||||
|
globalValueNumber(sizeArg).getAnExpr() = sub and
|
||||||
|
// ... where the left side of the subtraction is the constant n
|
||||||
|
globalValueNumber(sub.getLeftOperand()).getAnExpr().getValue().toInt() = n and
|
||||||
|
// ... and the right side of the subtraction is a call to `strlen` where the argument is the
|
||||||
|
// destination buffer.
|
||||||
|
globalValueNumber(sub.getRightOperand()).getAnExpr().(StrlenCall).getStringExpr() =
|
||||||
|
globalValueNumber(destArg).getAnExpr()
|
||||||
|
select call, "Possible out-of-bounds write due to incorrect size argument."
|
||||||
|
|||||||
@@ -1307,7 +1307,8 @@ private predicate conditionJumps(Expr test, boolean truth, Node n2, Pos p2) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Factored out for performance. See QL-796.
|
// Pulled out for performance. See
|
||||||
|
// https://github.com/github/codeql-coreql-team/issues/1044.
|
||||||
private predicate normalGroupMemberBaseCase(Node memberNode, Pos memberPos, Node atNode) {
|
private predicate normalGroupMemberBaseCase(Node memberNode, Pos memberPos, Node atNode) {
|
||||||
memberNode = atNode and
|
memberNode = atNode and
|
||||||
memberPos.isAt() and
|
memberPos.isAt() and
|
||||||
|
|||||||
@@ -104,9 +104,43 @@ private predicate loopConditionAlwaysUponEntry(ControlFlowNode loop, Expr condit
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This relation is the same as the `el instanceof Function`, only obfuscated
|
||||||
|
* so the optimizer will not understand that any `FunctionCall.getTarget()`
|
||||||
|
* should be in this relation.
|
||||||
|
*/
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate isFunction(Element el) {
|
||||||
|
el instanceof Function
|
||||||
|
or
|
||||||
|
el.(Expr).getParent() = el
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `fc` is a `FunctionCall` with no return value for `getTarget`. This
|
||||||
|
* can happen in case of rare database inconsistencies.
|
||||||
|
*/
|
||||||
|
pragma[noopt]
|
||||||
|
private predicate callHasNoTarget(@funbindexpr fc) {
|
||||||
|
exists(Function f |
|
||||||
|
funbind(fc, f) and
|
||||||
|
not isFunction(f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pulled out for performance. See
|
||||||
|
// https://github.com/github/codeql-coreql-team/issues/1044.
|
||||||
|
private predicate potentiallyReturningFunctionCall_base(FunctionCall fc) {
|
||||||
|
fc.isVirtual()
|
||||||
|
or
|
||||||
|
callHasNoTarget(fc)
|
||||||
|
}
|
||||||
|
|
||||||
/** A function call that *may* return; if in doubt, we assume it may. */
|
/** A function call that *may* return; if in doubt, we assume it may. */
|
||||||
private predicate potentiallyReturningFunctionCall(FunctionCall fc) {
|
private predicate potentiallyReturningFunctionCall(FunctionCall fc) {
|
||||||
potentiallyReturningFunction(fc.getTarget()) or fc.isVirtual()
|
potentiallyReturningFunctionCall_base(fc)
|
||||||
|
or
|
||||||
|
potentiallyReturningFunction(fc.getTarget())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A function that *may* return; if in doubt, we assume it may. */
|
/** A function that *may* return; if in doubt, we assume it may. */
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private import cpp
|
private import cpp
|
||||||
|
private import semmle.code.cpp.models.interfaces.PointerWrapper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `f` is an instantiation of the `std::move` or `std::forward`
|
* Holds if `f` is an instantiation of the `std::move` or `std::forward`
|
||||||
@@ -94,6 +95,12 @@ private predicate pointerToPointerStep(Expr pointerIn, Expr pointerOut) {
|
|||||||
|
|
||||||
private predicate lvalueToReferenceStep(Expr lvalueIn, Expr referenceOut) {
|
private predicate lvalueToReferenceStep(Expr lvalueIn, Expr referenceOut) {
|
||||||
lvalueIn.getConversion() = referenceOut.(ReferenceToExpr)
|
lvalueIn.getConversion() = referenceOut.(ReferenceToExpr)
|
||||||
|
or
|
||||||
|
exists(PointerWrapper wrapper, Call call | call = referenceOut |
|
||||||
|
referenceOut.getUnspecifiedType() instanceof ReferenceType and
|
||||||
|
call = wrapper.getAnUnwrapperFunction().getACallToThisFunction() and
|
||||||
|
lvalueIn = call.getQualifier().getFullyConverted()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate referenceToLvalueStep(Expr referenceIn, Expr lvalueOut) {
|
private predicate referenceToLvalueStep(Expr referenceIn, Expr lvalueOut) {
|
||||||
@@ -106,6 +113,13 @@ private predicate referenceToPointerStep(Expr referenceIn, Expr pointerOut) {
|
|||||||
stdAddressOf(call.getTarget()) and
|
stdAddressOf(call.getTarget()) and
|
||||||
referenceIn = call.getArgument(0).getFullyConverted()
|
referenceIn = call.getArgument(0).getFullyConverted()
|
||||||
)
|
)
|
||||||
|
or
|
||||||
|
exists(CopyConstructor copy, Call call | call = pointerOut |
|
||||||
|
copy.getDeclaringType() instanceof PointerWrapper and
|
||||||
|
call.getTarget() = copy and
|
||||||
|
// The 0'th argument is the value being copied.
|
||||||
|
referenceIn = call.getArgument(0).getFullyConverted()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate referenceToReferenceStep(Expr referenceIn, Expr referenceOut) {
|
private predicate referenceToReferenceStep(Expr referenceIn, Expr referenceOut) {
|
||||||
@@ -190,6 +204,19 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node
|
|||||||
// See the `lvalueToUpdate` case for an explanation of this conjunct.
|
// See the `lvalueToUpdate` case for an explanation of this conjunct.
|
||||||
call.getType().isDeeplyConstBelow()
|
call.getType().isDeeplyConstBelow()
|
||||||
)
|
)
|
||||||
|
or
|
||||||
|
// Pointer wrappers behave as raw pointers for dataflow purposes.
|
||||||
|
outer = call.getAnArgument().getFullyConverted() and
|
||||||
|
exists(PointerWrapper wrapper | wrapper = outer.getType().stripTopLevelSpecifiers() |
|
||||||
|
not wrapper.pointsToConst()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
outer = call.getQualifier().getFullyConverted() and
|
||||||
|
outer.getUnspecifiedType() instanceof PointerWrapper and
|
||||||
|
not (
|
||||||
|
call.getTarget().hasSpecifier("const") and
|
||||||
|
call.getType().isDeeplyConstBelow()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(PointerFieldAccess fa |
|
exists(PointerFieldAccess fa |
|
||||||
@@ -218,7 +245,9 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode
|
|||||||
not stdIdentityFunction(call.getTarget()) and
|
not stdIdentityFunction(call.getTarget()) and
|
||||||
not stdAddressOf(call.getTarget()) and
|
not stdAddressOf(call.getTarget()) and
|
||||||
exists(ReferenceType rt | rt = outer.getType().stripTopLevelSpecifiers() |
|
exists(ReferenceType rt | rt = outer.getType().stripTopLevelSpecifiers() |
|
||||||
not rt.getBaseType().isConst()
|
not rt.getBaseType().isConst() or
|
||||||
|
rt.getBaseType().getUnspecifiedType() =
|
||||||
|
any(PointerWrapper wrapper | not wrapper.pointsToConst())
|
||||||
)
|
)
|
||||||
) and
|
) and
|
||||||
reference = outer
|
reference = outer
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class Node extends TNode {
|
|||||||
/**
|
/**
|
||||||
* INTERNAL: Do not use. Alternative name for `getFunction`.
|
* INTERNAL: Do not use. Alternative name for `getFunction`.
|
||||||
*/
|
*/
|
||||||
final Function getEnclosingCallable() { result = unique(Function f | f = this.getFunction() | f) }
|
final Function getEnclosingCallable() { result = this.getFunction() }
|
||||||
|
|
||||||
/** Gets the type of this node. */
|
/** Gets the type of this node. */
|
||||||
Type getType() { none() } // overridden in subclasses
|
Type getType() { none() } // overridden in subclasses
|
||||||
@@ -324,7 +324,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode {
|
|||||||
* A synthetic data flow node used for flow into a collection when an iterator
|
* A synthetic data flow node used for flow into a collection when an iterator
|
||||||
* write occurs in a callee.
|
* write occurs in a callee.
|
||||||
*/
|
*/
|
||||||
class IteratorPartialDefinitionNode extends PartialDefinitionNode {
|
private class IteratorPartialDefinitionNode extends PartialDefinitionNode {
|
||||||
override IteratorPartialDefinition pd;
|
override IteratorPartialDefinition pd;
|
||||||
|
|
||||||
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
|
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
|
||||||
@@ -715,6 +715,7 @@ private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private module FieldFlow {
|
private module FieldFlow {
|
||||||
|
private import DataFlowImplCommon
|
||||||
private import DataFlowImplLocal
|
private import DataFlowImplLocal
|
||||||
private import DataFlowPrivate
|
private import DataFlowPrivate
|
||||||
|
|
||||||
@@ -747,7 +748,7 @@ private module FieldFlow {
|
|||||||
exists(FieldConfiguration cfg | cfg.hasFlow(node1, node2)) and
|
exists(FieldConfiguration cfg | cfg.hasFlow(node1, node2)) and
|
||||||
// This configuration should not be able to cross function boundaries, but
|
// This configuration should not be able to cross function boundaries, but
|
||||||
// we double-check here just to be sure.
|
// we double-check here just to be sure.
|
||||||
node1.getEnclosingCallable() = node2.getEnclosingCallable()
|
getNodeEnclosingCallable(node1) = getNodeEnclosingCallable(node2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ private import semmle.code.cpp.controlflow.SSA
|
|||||||
private import semmle.code.cpp.dataflow.internal.SubBasicBlocks
|
private import semmle.code.cpp.dataflow.internal.SubBasicBlocks
|
||||||
private import semmle.code.cpp.dataflow.internal.AddressFlow
|
private import semmle.code.cpp.dataflow.internal.AddressFlow
|
||||||
private import semmle.code.cpp.models.implementations.Iterator
|
private import semmle.code.cpp.models.implementations.Iterator
|
||||||
|
private import semmle.code.cpp.models.interfaces.PointerWrapper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A conceptual variable that is assigned only once, like an SSA variable. This
|
* A conceptual variable that is assigned only once, like an SSA variable. This
|
||||||
@@ -158,18 +159,14 @@ private module PartialDefinitions {
|
|||||||
Expr innerDefinedExpr;
|
Expr innerDefinedExpr;
|
||||||
|
|
||||||
IteratorPartialDefinition() {
|
IteratorPartialDefinition() {
|
||||||
exists(Expr convertedInner |
|
innerDefinedExpr = getInnerDefinedExpr(this, node) and
|
||||||
not this instanceof Conversion and
|
(
|
||||||
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
|
innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
|
||||||
innerDefinedExpr = convertedInner.getUnconverted() and
|
or
|
||||||
(
|
innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
|
||||||
innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
|
collection instanceof IteratorParameter
|
||||||
or
|
) and
|
||||||
innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
|
innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
|
||||||
collection instanceof IteratorParameter
|
|
||||||
) and
|
|
||||||
innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
|
|
||||||
)
|
|
||||||
or
|
or
|
||||||
// iterators passed by value without a copy constructor
|
// iterators passed by value without a copy constructor
|
||||||
exists(Call call |
|
exists(Call call |
|
||||||
@@ -207,16 +204,18 @@ private module PartialDefinitions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Expr getInnerDefinedExpr(Expr e, ControlFlowNode node) {
|
||||||
|
not e instanceof Conversion and
|
||||||
|
exists(Expr convertedInner |
|
||||||
|
valueToUpdate(convertedInner, e.getFullyConverted(), node) and
|
||||||
|
result = convertedInner.getUnconverted()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
class VariablePartialDefinition extends PartialDefinition {
|
class VariablePartialDefinition extends PartialDefinition {
|
||||||
Expr innerDefinedExpr;
|
Expr innerDefinedExpr;
|
||||||
|
|
||||||
VariablePartialDefinition() {
|
VariablePartialDefinition() { innerDefinedExpr = getInnerDefinedExpr(this, node) }
|
||||||
not this instanceof Conversion and
|
|
||||||
exists(Expr convertedInner |
|
|
||||||
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
|
|
||||||
innerDefinedExpr = convertedInner.getUnconverted()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
deprecated override predicate partiallyDefines(Variable v) {
|
deprecated override predicate partiallyDefines(Variable v) {
|
||||||
innerDefinedExpr = v.getAnAccess()
|
innerDefinedExpr = v.getAnAccess()
|
||||||
@@ -296,7 +295,8 @@ module FlowVar_internal {
|
|||||||
// treating them as immutable, but for data flow it gives better results in
|
// treating them as immutable, but for data flow it gives better results in
|
||||||
// practice to make the variable synonymous with its contents.
|
// practice to make the variable synonymous with its contents.
|
||||||
not v.getUnspecifiedType() instanceof ReferenceType and
|
not v.getUnspecifiedType() instanceof ReferenceType and
|
||||||
not v instanceof IteratorParameter
|
not v instanceof IteratorParameter and
|
||||||
|
not v instanceof PointerWrapperParameter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -644,10 +644,19 @@ module FlowVar_internal {
|
|||||||
predicate parameterIsNonConstReference(Parameter p) {
|
predicate parameterIsNonConstReference(Parameter p) {
|
||||||
exists(ReferenceType refType |
|
exists(ReferenceType refType |
|
||||||
refType = p.getUnderlyingType() and
|
refType = p.getUnderlyingType() and
|
||||||
not refType.getBaseType().isConst()
|
(
|
||||||
|
not refType.getBaseType().isConst()
|
||||||
|
or
|
||||||
|
// A field of a parameter of type `const std::shared_ptr<A>& p` can still be changed even though
|
||||||
|
// the base type of the reference is `const`.
|
||||||
|
refType.getBaseType().getUnspecifiedType() =
|
||||||
|
any(PointerWrapper wrapper | not wrapper.pointsToConst())
|
||||||
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
p instanceof IteratorParameter
|
p instanceof IteratorParameter
|
||||||
|
or
|
||||||
|
p instanceof PointerWrapperParameter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -836,6 +845,10 @@ module FlowVar_internal {
|
|||||||
IteratorParameter() { this.getUnspecifiedType() instanceof Iterator }
|
IteratorParameter() { this.getUnspecifiedType() instanceof Iterator }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PointerWrapperParameter extends Parameter {
|
||||||
|
PointerWrapperParameter() { this.getUnspecifiedType() instanceof PointerWrapper }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `v` is initialized to have value `assignedExpr`.
|
* Holds if `v` is initialized to have value `assignedExpr`.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||||
private import semmle.code.cpp.models.interfaces.Taint
|
private import semmle.code.cpp.models.interfaces.Taint
|
||||||
private import semmle.code.cpp.models.interfaces.Iterator
|
private import semmle.code.cpp.models.interfaces.Iterator
|
||||||
|
private import semmle.code.cpp.models.interfaces.PointerWrapper
|
||||||
|
|
||||||
private module DataFlow {
|
private module DataFlow {
|
||||||
import semmle.code.cpp.dataflow.internal.DataFlowUtil
|
import semmle.code.cpp.dataflow.internal.DataFlowUtil
|
||||||
@@ -141,7 +142,10 @@ private predicate noFlowFromChildExpr(Expr e) {
|
|||||||
or
|
or
|
||||||
e instanceof LogicalOrExpr
|
e instanceof LogicalOrExpr
|
||||||
or
|
or
|
||||||
e instanceof Call
|
// Allow taint from `operator*` on smart pointers.
|
||||||
|
exists(Call call | e = call |
|
||||||
|
not call.getTarget() = any(PointerWrapper wrapper).getAnUnwrapperFunction()
|
||||||
|
)
|
||||||
or
|
or
|
||||||
e instanceof SizeofOperator
|
e instanceof SizeofOperator
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ class OverloadedPointerDereferenceFunction extends Function {
|
|||||||
* T1 operator*(const T2 &);
|
* T1 operator*(const T2 &);
|
||||||
* T1 a; T2 b;
|
* T1 a; T2 b;
|
||||||
* a = *b;
|
* a = *b;
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
class OverloadedPointerDereferenceExpr extends FunctionCall {
|
class OverloadedPointerDereferenceExpr extends FunctionCall {
|
||||||
OverloadedPointerDereferenceExpr() {
|
OverloadedPointerDereferenceExpr() {
|
||||||
|
|||||||
@@ -1271,7 +1271,8 @@ private predicate convparents(Expr child, int idx, Element parent) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pulled out for performance. See QL-796.
|
// Pulled out for performance. See
|
||||||
|
// https://github.com/github/codeql-coreql-team/issues/1044.
|
||||||
private predicate hasNoConversions(Expr e) { not e.hasConversion() }
|
private predicate hasNoConversions(Expr e) { not e.hasConversion() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -362,15 +362,22 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to.
|
* Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to.
|
||||||
* For instance, an update to a field of a struct containing only one field. For these cases we
|
* For instance, an update to a field of a struct containing only one field. Even if the store does
|
||||||
* attach the PostUpdateNode to the store instruction. There's no obvious pre update node for this case
|
* have a chi instruction, a subsequent use of the result of the store may be linked directly to the
|
||||||
* (as the entire memory is updated), so `getPreUpdateNode` is implemented as `none()`.
|
* result of the store as an inexact definition if the store totally overlaps the use. For these
|
||||||
|
* cases we attach the PostUpdateNode to the store instruction. There's no obvious pre update node
|
||||||
|
* for this case (as the entire memory is updated), so `getPreUpdateNode` is implemented as
|
||||||
|
* `none()`.
|
||||||
*/
|
*/
|
||||||
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
|
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||||
override StoreInstruction instr;
|
override StoreInstruction instr;
|
||||||
|
|
||||||
ExplicitSingleFieldStoreQualifierNode() {
|
ExplicitSingleFieldStoreQualifierNode() {
|
||||||
not exists(ChiInstruction chi | chi.getPartial() = instr) and
|
(
|
||||||
|
instr.getAUse().isDefinitionInexact()
|
||||||
|
or
|
||||||
|
not exists(ChiInstruction chi | chi.getPartial() = instr)
|
||||||
|
) and
|
||||||
// Without this condition any store would create a `PostUpdateNode`.
|
// Without this condition any store would create a `PostUpdateNode`.
|
||||||
instr.getDestinationAddress() instanceof FieldAddressInstruction
|
instr.getDestinationAddress() instanceof FieldAddressInstruction
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,34 +6,7 @@ private import semmle.code.cpp.ir.ValueNumbering
|
|||||||
private import semmle.code.cpp.ir.IR
|
private import semmle.code.cpp.ir.IR
|
||||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||||
|
private import PrintIRUtilities
|
||||||
/**
|
|
||||||
* Gets a short ID for an IR dataflow node.
|
|
||||||
* - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`).
|
|
||||||
* - For `Operand`s, this is the label of the operand, prefixed with the result ID of the
|
|
||||||
* instruction and a dot (e.g. `m128.left`).
|
|
||||||
* - For `Variable`s, this is the qualified name of the variable.
|
|
||||||
*/
|
|
||||||
private string nodeId(DataFlow::Node node, int order1, int order2) {
|
|
||||||
exists(Instruction instruction | instruction = node.asInstruction() |
|
|
||||||
result = instruction.getResultId() and
|
|
||||||
order1 = instruction.getBlock().getDisplayIndex() and
|
|
||||||
order2 = instruction.getDisplayIndexInBlock()
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(Operand operand, Instruction instruction |
|
|
||||||
operand = node.asOperand() and
|
|
||||||
instruction = operand.getUse()
|
|
||||||
|
|
|
||||||
result = instruction.getResultId() + "." + operand.getDumpId() and
|
|
||||||
order1 = instruction.getBlock().getDisplayIndex() and
|
|
||||||
order2 = instruction.getDisplayIndexInBlock()
|
|
||||||
)
|
|
||||||
or
|
|
||||||
result = "var(" + node.asVariable().getQualifiedName() + ")" and
|
|
||||||
order1 = 1000000 and
|
|
||||||
order2 = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the local dataflow from other nodes in the same function to this node.
|
* Gets the local dataflow from other nodes in the same function to this node.
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Print the dataflow local store steps in IR dumps.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import cpp
|
||||||
|
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
|
||||||
|
// that the cached IR gets the same checksum here as it does in queries that use
|
||||||
|
// `ValueNumbering` without `DataFlow`.
|
||||||
|
private import semmle.code.cpp.ir.ValueNumbering
|
||||||
|
private import semmle.code.cpp.ir.IR
|
||||||
|
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||||
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||||
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||||
|
private import PrintIRUtilities
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property provider for local IR dataflow store steps.
|
||||||
|
*/
|
||||||
|
class LocalFlowPropertyProvider extends IRPropertyProvider {
|
||||||
|
override string getInstructionProperty(Instruction instruction, string key) {
|
||||||
|
exists(DataFlow::Node objectNode, Content content |
|
||||||
|
key = "content[" + content.toString() + "]" and
|
||||||
|
instruction = objectNode.asInstruction() and
|
||||||
|
result =
|
||||||
|
strictconcat(string element, DataFlow::Node fieldNode |
|
||||||
|
storeStep(fieldNode, content, objectNode) and
|
||||||
|
element = nodeId(fieldNode, _, _)
|
||||||
|
|
|
||||||
|
element, ", "
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Shared utilities used when printing dataflow annotations in IR dumps.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import cpp
|
||||||
|
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
|
||||||
|
// that the cached IR gets the same checksum here as it does in queries that use
|
||||||
|
// `ValueNumbering` without `DataFlow`.
|
||||||
|
private import semmle.code.cpp.ir.ValueNumbering
|
||||||
|
private import semmle.code.cpp.ir.IR
|
||||||
|
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a short ID for an IR dataflow node.
|
||||||
|
* - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`).
|
||||||
|
* - For `Operand`s, this is the label of the operand, prefixed with the result ID of the
|
||||||
|
* instruction and a dot (e.g. `m128.left`).
|
||||||
|
* - For `Variable`s, this is the qualified name of the variable.
|
||||||
|
*/
|
||||||
|
string nodeId(DataFlow::Node node, int order1, int order2) {
|
||||||
|
exists(Instruction instruction | instruction = node.asInstruction() |
|
||||||
|
result = instruction.getResultId() and
|
||||||
|
order1 = instruction.getBlock().getDisplayIndex() and
|
||||||
|
order2 = instruction.getDisplayIndexInBlock()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(Operand operand, Instruction instruction |
|
||||||
|
operand = node.asOperand() and
|
||||||
|
instruction = operand.getUse()
|
||||||
|
|
|
||||||
|
result = instruction.getResultId() + "." + operand.getDumpId() and
|
||||||
|
order1 = instruction.getBlock().getDisplayIndex() and
|
||||||
|
order2 = instruction.getDisplayIndexInBlock()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
result = "var(" + node.asVariable().getQualifiedName() + ")" and
|
||||||
|
order1 = 1000000 and
|
||||||
|
order2 = 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* Predicates to compute the modeled side effects of calls during IR construction.
|
||||||
|
*
|
||||||
|
* These are used in `TranslatedElement.qll` to generate the `TTranslatedSideEffect` instances, and
|
||||||
|
* also in `TranslatedCall.qll` to inject the actual side effect instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import cpp
|
||||||
|
private import semmle.code.cpp.ir.implementation.Opcode
|
||||||
|
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the specified call has a side effect that does not come from a `SideEffectFunction`
|
||||||
|
* model.
|
||||||
|
*/
|
||||||
|
private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buffer, boolean isWrite) {
|
||||||
|
not call.getTarget() instanceof SideEffectFunction and
|
||||||
|
(
|
||||||
|
exists(MemberFunction mfunc |
|
||||||
|
// A non-static member function, including a constructor or destructor, may write to `*this`,
|
||||||
|
// and may also read from `*this` if it is not a constructor.
|
||||||
|
i = -1 and
|
||||||
|
mfunc = call.getTarget() and
|
||||||
|
not mfunc.isStatic() and
|
||||||
|
buffer = false and
|
||||||
|
(
|
||||||
|
isWrite = false and not mfunc instanceof Constructor
|
||||||
|
or
|
||||||
|
isWrite = true and not mfunc instanceof ConstMemberFunction
|
||||||
|
)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(Expr expr |
|
||||||
|
// A pointer-like argument is assumed to read from the pointed-to buffer, and may write to the
|
||||||
|
// buffer as well unless the pointer points to a `const` value.
|
||||||
|
i >= 0 and
|
||||||
|
buffer = true and
|
||||||
|
expr = call.getArgument(i).getFullyConverted() and
|
||||||
|
exists(Type t | t = expr.getUnspecifiedType() |
|
||||||
|
t instanceof ArrayType or
|
||||||
|
t instanceof PointerType or
|
||||||
|
t instanceof ReferenceType
|
||||||
|
) and
|
||||||
|
(
|
||||||
|
isWrite = true and
|
||||||
|
not call.getTarget().getParameter(i).getType().isDeeplyConstBelow()
|
||||||
|
or
|
||||||
|
isWrite = false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a side effect opcode for parameter index `i` of the specified call.
|
||||||
|
*
|
||||||
|
* This predicate will return at most two results: one read side effect, and one write side effect.
|
||||||
|
*/
|
||||||
|
Opcode getASideEffectOpcode(Call call, ParameterIndex i) {
|
||||||
|
exists(boolean buffer |
|
||||||
|
(
|
||||||
|
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(i, buffer)
|
||||||
|
or
|
||||||
|
not call.getTarget() instanceof SideEffectFunction and
|
||||||
|
hasDefaultSideEffect(call, i, buffer, false)
|
||||||
|
) and
|
||||||
|
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(i))
|
||||||
|
then (
|
||||||
|
buffer = true and
|
||||||
|
result instanceof Opcode::SizedBufferReadSideEffect
|
||||||
|
) else (
|
||||||
|
buffer = false and result instanceof Opcode::IndirectReadSideEffect
|
||||||
|
or
|
||||||
|
buffer = true and result instanceof Opcode::BufferReadSideEffect
|
||||||
|
)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(boolean buffer, boolean mustWrite |
|
||||||
|
(
|
||||||
|
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(i, buffer, mustWrite)
|
||||||
|
or
|
||||||
|
not call.getTarget() instanceof SideEffectFunction and
|
||||||
|
hasDefaultSideEffect(call, i, buffer, true) and
|
||||||
|
mustWrite = false
|
||||||
|
) and
|
||||||
|
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(i))
|
||||||
|
then (
|
||||||
|
buffer = true and
|
||||||
|
mustWrite = false and
|
||||||
|
result instanceof Opcode::SizedBufferMayWriteSideEffect
|
||||||
|
or
|
||||||
|
buffer = true and
|
||||||
|
mustWrite = true and
|
||||||
|
result instanceof Opcode::SizedBufferMustWriteSideEffect
|
||||||
|
) else (
|
||||||
|
buffer = false and
|
||||||
|
mustWrite = false and
|
||||||
|
result instanceof Opcode::IndirectMayWriteSideEffect
|
||||||
|
or
|
||||||
|
buffer = false and
|
||||||
|
mustWrite = true and
|
||||||
|
result instanceof Opcode::IndirectMustWriteSideEffect
|
||||||
|
or
|
||||||
|
buffer = true and mustWrite = false and result instanceof Opcode::BufferMayWriteSideEffect
|
||||||
|
or
|
||||||
|
buffer = true and mustWrite = true and result instanceof Opcode::BufferMustWriteSideEffect
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
|||||||
private import semmle.code.cpp.ir.internal.CppType
|
private import semmle.code.cpp.ir.internal.CppType
|
||||||
private import semmle.code.cpp.models.interfaces.SideEffect
|
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||||
private import InstructionTag
|
private import InstructionTag
|
||||||
|
private import SideEffects
|
||||||
private import TranslatedElement
|
private import TranslatedElement
|
||||||
private import TranslatedExpr
|
private import TranslatedExpr
|
||||||
private import TranslatedFunction
|
private import TranslatedFunction
|
||||||
@@ -424,12 +425,15 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
|
class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
|
||||||
TranslatedStructorCallSideEffects() { getParent().(TranslatedStructorCall).hasQualifier() }
|
TranslatedStructorCallSideEffects() {
|
||||||
|
getParent().(TranslatedStructorCall).hasQualifier() and
|
||||||
|
getASideEffectOpcode(expr, -1) instanceof WriteSideEffectOpcode
|
||||||
|
}
|
||||||
|
|
||||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) {
|
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) {
|
||||||
opcode instanceof Opcode::IndirectMayWriteSideEffect and
|
|
||||||
tag instanceof OnlyInstructionTag and
|
tag instanceof OnlyInstructionTag and
|
||||||
t = getTypeForPRValue(expr.getTarget().getDeclaringType())
|
t = getTypeForPRValue(expr.getTarget().getDeclaringType()) and
|
||||||
|
opcode = getASideEffectOpcode(expr, -1).(WriteSideEffectOpcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||||
@@ -460,9 +464,11 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
|
|||||||
Call call;
|
Call call;
|
||||||
Expr arg;
|
Expr arg;
|
||||||
int index;
|
int index;
|
||||||
boolean write;
|
SideEffectOpcode sideEffectOpcode;
|
||||||
|
|
||||||
TranslatedSideEffect() { this = TTranslatedArgumentSideEffect(call, arg, index, write) }
|
TranslatedSideEffect() {
|
||||||
|
this = TTranslatedArgumentSideEffect(call, arg, index, sideEffectOpcode)
|
||||||
|
}
|
||||||
|
|
||||||
override Locatable getAST() { result = arg }
|
override Locatable getAST() { result = arg }
|
||||||
|
|
||||||
@@ -472,13 +478,13 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
|
|||||||
|
|
||||||
int getArgumentIndex() { result = index }
|
int getArgumentIndex() { result = index }
|
||||||
|
|
||||||
predicate isWrite() { write = true }
|
predicate isWrite() { sideEffectOpcode instanceof WriteSideEffectOpcode }
|
||||||
|
|
||||||
override string toString() {
|
override string toString() {
|
||||||
write = true and
|
isWrite() and
|
||||||
result = "(write side effect for " + arg.toString() + ")"
|
result = "(write side effect for " + arg.toString() + ")"
|
||||||
or
|
or
|
||||||
write = false and
|
not isWrite() and
|
||||||
result = "(read side effect for " + arg.toString() + ")"
|
result = "(read side effect for " + arg.toString() + ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,29 +495,29 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
|
|||||||
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
|
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
|
||||||
|
|
||||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
|
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
|
||||||
isWrite() and
|
|
||||||
hasSpecificWriteSideEffect(opcode) and
|
|
||||||
tag = OnlyInstructionTag() and
|
tag = OnlyInstructionTag() and
|
||||||
|
opcode = sideEffectOpcode and
|
||||||
(
|
(
|
||||||
opcode instanceof BufferAccessOpcode and
|
isWrite() and
|
||||||
type = getUnknownType()
|
(
|
||||||
or
|
opcode instanceof BufferAccessOpcode and
|
||||||
not opcode instanceof BufferAccessOpcode and
|
type = getUnknownType()
|
||||||
exists(Type baseType | baseType = arg.getUnspecifiedType().(DerivedType).getBaseType() |
|
or
|
||||||
if baseType instanceof VoidType
|
not opcode instanceof BufferAccessOpcode and
|
||||||
then type = getUnknownType()
|
exists(Type baseType | baseType = arg.getUnspecifiedType().(DerivedType).getBaseType() |
|
||||||
else type = getTypeForPRValueOrUnknown(baseType)
|
if baseType instanceof VoidType
|
||||||
|
then type = getUnknownType()
|
||||||
|
else type = getTypeForPRValueOrUnknown(baseType)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
index = -1 and
|
||||||
|
not arg.getUnspecifiedType() instanceof DerivedType and
|
||||||
|
type = getTypeForPRValueOrUnknown(arg.getUnspecifiedType())
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
index = -1 and
|
not isWrite() and
|
||||||
not arg.getUnspecifiedType() instanceof DerivedType and
|
type = getVoidType()
|
||||||
type = getTypeForPRValueOrUnknown(arg.getUnspecifiedType())
|
|
||||||
)
|
)
|
||||||
or
|
|
||||||
not isWrite() and
|
|
||||||
hasSpecificReadSideEffect(opcode) and
|
|
||||||
tag = OnlyInstructionTag() and
|
|
||||||
type = getVoidType()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||||
@@ -535,7 +541,7 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
|
|||||||
|
|
||||||
override CppType getInstructionMemoryOperandType(InstructionTag tag, TypedOperandTag operandTag) {
|
override CppType getInstructionMemoryOperandType(InstructionTag tag, TypedOperandTag operandTag) {
|
||||||
not isWrite() and
|
not isWrite() and
|
||||||
if hasSpecificReadSideEffect(any(BufferAccessOpcode op))
|
if sideEffectOpcode instanceof BufferAccessOpcode
|
||||||
then
|
then
|
||||||
result = getUnknownType() and
|
result = getUnknownType() and
|
||||||
tag instanceof OnlyInstructionTag and
|
tag instanceof OnlyInstructionTag and
|
||||||
@@ -557,56 +563,6 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate hasSpecificWriteSideEffect(Opcode op) {
|
|
||||||
exists(boolean buffer, boolean mustWrite |
|
|
||||||
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
|
|
||||||
then
|
|
||||||
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, true, mustWrite) and
|
|
||||||
buffer = true and
|
|
||||||
(
|
|
||||||
mustWrite = false and op instanceof Opcode::SizedBufferMayWriteSideEffect
|
|
||||||
or
|
|
||||||
mustWrite = true and op instanceof Opcode::SizedBufferMustWriteSideEffect
|
|
||||||
)
|
|
||||||
else (
|
|
||||||
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, buffer, mustWrite) and
|
|
||||||
(
|
|
||||||
buffer = true and mustWrite = false and op instanceof Opcode::BufferMayWriteSideEffect
|
|
||||||
or
|
|
||||||
buffer = false and mustWrite = false and op instanceof Opcode::IndirectMayWriteSideEffect
|
|
||||||
or
|
|
||||||
buffer = true and mustWrite = true and op instanceof Opcode::BufferMustWriteSideEffect
|
|
||||||
or
|
|
||||||
buffer = false and mustWrite = true and op instanceof Opcode::IndirectMustWriteSideEffect
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
not call.getTarget() instanceof SideEffectFunction and
|
|
||||||
getArgumentIndex() != -1 and
|
|
||||||
op instanceof Opcode::BufferMayWriteSideEffect
|
|
||||||
or
|
|
||||||
not call.getTarget() instanceof SideEffectFunction and
|
|
||||||
getArgumentIndex() = -1 and
|
|
||||||
op instanceof Opcode::IndirectMayWriteSideEffect
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate hasSpecificReadSideEffect(Opcode op) {
|
|
||||||
exists(boolean buffer |
|
|
||||||
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, buffer) and
|
|
||||||
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
|
|
||||||
then buffer = true and op instanceof Opcode::SizedBufferReadSideEffect
|
|
||||||
else (
|
|
||||||
buffer = true and op instanceof Opcode::BufferReadSideEffect
|
|
||||||
or
|
|
||||||
buffer = false and op instanceof Opcode::IndirectReadSideEffect
|
|
||||||
)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
not call.getTarget() instanceof SideEffectFunction and
|
|
||||||
op instanceof Opcode::BufferReadSideEffect
|
|
||||||
}
|
|
||||||
|
|
||||||
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
|
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
|
||||||
tag = OnlyInstructionTag() and
|
tag = OnlyInstructionTag() and
|
||||||
result = getTranslatedCallInstruction(call)
|
result = getTranslatedCallInstruction(call)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ private import TranslatedStmt
|
|||||||
private import TranslatedExpr
|
private import TranslatedExpr
|
||||||
private import IRConstruction
|
private import IRConstruction
|
||||||
private import semmle.code.cpp.models.interfaces.SideEffect
|
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||||
|
private import SideEffects
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the "real" parent of `expr`. This predicate treats conversions as if
|
* Gets the "real" parent of `expr`. This predicate treats conversions as if
|
||||||
@@ -41,7 +42,8 @@ IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) {
|
|||||||
*/
|
*/
|
||||||
predicate isIRConstant(Expr expr) { exists(expr.getValue()) }
|
predicate isIRConstant(Expr expr) { exists(expr.getValue()) }
|
||||||
|
|
||||||
// Pulled out to work around QL-796
|
// Pulled out for performance. See
|
||||||
|
// https://github.com/github/codeql-coreql-team/issues/1044.
|
||||||
private predicate isOrphan(Expr expr) { not exists(getRealParent(expr)) }
|
private predicate isOrphan(Expr expr) { not exists(getRealParent(expr)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -635,46 +637,15 @@ newtype TTranslatedElement =
|
|||||||
// The side effects of an allocation, i.e. `new`, `new[]` or `malloc`
|
// The side effects of an allocation, i.e. `new`, `new[]` or `malloc`
|
||||||
TTranslatedAllocationSideEffects(AllocationExpr expr) { not ignoreExpr(expr) } or
|
TTranslatedAllocationSideEffects(AllocationExpr expr) { not ignoreExpr(expr) } or
|
||||||
// A precise side effect of an argument to a `Call`
|
// A precise side effect of an argument to a `Call`
|
||||||
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) {
|
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, SideEffectOpcode opcode) {
|
||||||
(
|
|
||||||
expr = call.getArgument(n).getFullyConverted()
|
|
||||||
or
|
|
||||||
expr = call.getQualifier().getFullyConverted() and
|
|
||||||
n = -1 and
|
|
||||||
// Exclude calls to static member functions. They don't modify the qualifier
|
|
||||||
not exists(MemberFunction func | func = call.getTarget() and func.isStatic())
|
|
||||||
) and
|
|
||||||
(
|
|
||||||
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(n, _) and
|
|
||||||
isWrite = false
|
|
||||||
or
|
|
||||||
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(n, _, _) and
|
|
||||||
isWrite = true
|
|
||||||
or
|
|
||||||
not call.getTarget() instanceof SideEffectFunction and
|
|
||||||
exists(Type t | t = expr.getUnspecifiedType() |
|
|
||||||
t instanceof ArrayType or
|
|
||||||
t instanceof PointerType or
|
|
||||||
t instanceof ReferenceType
|
|
||||||
) and
|
|
||||||
(
|
|
||||||
isWrite = true and
|
|
||||||
not call.getTarget().getParameter(n).getType().isDeeplyConstBelow()
|
|
||||||
or
|
|
||||||
isWrite = false
|
|
||||||
)
|
|
||||||
or
|
|
||||||
not call.getTarget() instanceof SideEffectFunction and
|
|
||||||
n = -1 and
|
|
||||||
(
|
|
||||||
isWrite = true and
|
|
||||||
not call.getTarget() instanceof ConstMemberFunction
|
|
||||||
or
|
|
||||||
isWrite = false
|
|
||||||
)
|
|
||||||
) and
|
|
||||||
not ignoreExpr(expr) and
|
not ignoreExpr(expr) and
|
||||||
not ignoreExpr(call)
|
not ignoreExpr(call) and
|
||||||
|
(
|
||||||
|
n >= 0 and expr = call.getArgument(n).getFullyConverted()
|
||||||
|
or
|
||||||
|
n = -1 and expr = call.getQualifier().getFullyConverted()
|
||||||
|
) and
|
||||||
|
opcode = getASideEffectOpcode(call, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -13,23 +13,25 @@ private class UniqueOrSharedPtr extends Class, PointerWrapper {
|
|||||||
or
|
or
|
||||||
result.getClassAndName(["operator->", "get"]) = this
|
result.getClassAndName(["operator->", "get"]) = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override predicate pointsToConst() { this.getTemplateArgument(0).(Type).isConst() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Any function that unwraps a pointer wrapper class to reveal the underlying pointer. */
|
/** Any function that unwraps a pointer wrapper class to reveal the underlying pointer. */
|
||||||
private class PointerWrapperDataFlow extends DataFlowFunction {
|
private class PointerWrapperFlow extends TaintFunction, DataFlowFunction {
|
||||||
PointerWrapperDataFlow() {
|
PointerWrapperFlow() {
|
||||||
this = any(PointerWrapper wrapper).getAnUnwrapperFunction() and
|
this = any(PointerWrapper wrapper).getAnUnwrapperFunction() and
|
||||||
not this.getUnspecifiedType() instanceof ReferenceType
|
not this.getUnspecifiedType() instanceof ReferenceType
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||||
input.isQualifierAddress() and output.isReturnValue()
|
|
||||||
or
|
|
||||||
input.isQualifierObject() and output.isReturnValueDeref()
|
|
||||||
or
|
|
||||||
input.isReturnValueDeref() and
|
input.isReturnValueDeref() and
|
||||||
output.isQualifierObject()
|
output.isQualifierObject()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||||
|
input.isQualifierObject() and output.isReturnValue()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,4 +11,7 @@ abstract class PointerWrapper extends Class {
|
|||||||
* that return a reference to the pointed-to object.
|
* that return a reference to the pointed-to object.
|
||||||
*/
|
*/
|
||||||
abstract MemberFunction getAnUnwrapperFunction();
|
abstract MemberFunction getAnUnwrapperFunction();
|
||||||
|
|
||||||
|
/** Holds if the type of the data that is pointed to by this pointer wrapper is `const`. */
|
||||||
|
abstract predicate pointsToConst();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.controlflow.Dominance
|
import semmle.code.cpp.controlflow.Dominance
|
||||||
|
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||||
|
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the value of `use` is guarded using `abs`.
|
* Holds if the value of `use` is guarded using `abs`.
|
||||||
@@ -94,9 +96,15 @@ predicate guardedGreater(Operation e, Expr use) {
|
|||||||
VariableAccess varUse(LocalScopeVariable v) { result = v.getAnAccess() }
|
VariableAccess varUse(LocalScopeVariable v) { result = v.getAnAccess() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `e` is not guarded against overflow by `use`.
|
* Holds if `e` potentially overflows and `use` is an operand of `e` that is not guarded.
|
||||||
*/
|
*/
|
||||||
predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
|
predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
|
||||||
|
(
|
||||||
|
convertedExprMightOverflowPositively(e)
|
||||||
|
or
|
||||||
|
// Ensure that the predicate holds when range analysis cannot determine an upper bound
|
||||||
|
upperBound(e.getFullyConverted()) = exprMaxVal(e.getFullyConverted())
|
||||||
|
) and
|
||||||
use = e.getAnOperand() and
|
use = e.getAnOperand() and
|
||||||
exists(LocalScopeVariable v | use.getTarget() = v |
|
exists(LocalScopeVariable v | use.getTarget() = v |
|
||||||
// overflow possible if large
|
// overflow possible if large
|
||||||
@@ -115,9 +123,15 @@ predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `e` is not guarded against underflow by `use`.
|
* Holds if `e` potentially underflows and `use` is an operand of `e` that is not guarded.
|
||||||
*/
|
*/
|
||||||
predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) {
|
predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) {
|
||||||
|
(
|
||||||
|
convertedExprMightOverflowNegatively(e)
|
||||||
|
or
|
||||||
|
// Ensure that the predicate holds when range analysis cannot determine a lower bound
|
||||||
|
lowerBound(e.getFullyConverted()) = exprMinVal(e.getFullyConverted())
|
||||||
|
) and
|
||||||
use = e.getAnOperand() and
|
use = e.getAnOperand() and
|
||||||
exists(LocalScopeVariable v | use.getTarget() = v |
|
exists(LocalScopeVariable v | use.getTarget() = v |
|
||||||
// underflow possible if use is left operand and small
|
// underflow possible if use is left operand and small
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
| test.c:15:6:15:16 | ... + ... | this expression needs your attention |
|
||||||
|
| test.c:17:17:17:27 | ... + ... | this expression needs your attention |
|
||||||
|
| test.c:22:10:22:15 | ... > ... | this expression needs your attention |
|
||||||
|
| test.c:26:10:26:15 | ... > ... | this expression needs your attention |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementAfterRefactoringTheCode.ql
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
| test.c:8:6:8:51 | ... & ... | This bitwise operation appears in a context where a Boolean operation is expected. |
|
||||||
|
| test.c:10:6:10:30 | ... & ... | This bitwise operation appears in a context where a Boolean operation is expected. |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.ql
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
int tmpFunction(){
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
void workFunction_0(char *s) {
|
||||||
|
int intSize;
|
||||||
|
char buf[80];
|
||||||
|
if(intSize>0 && intSize<80 && memset(buf,0,intSize)) return; // GOOD
|
||||||
|
if(intSize>0 & intSize<80 & memset(buf,0,intSize)) return; // BAD
|
||||||
|
if(intSize>0 && tmpFunction()) return;
|
||||||
|
if(intSize<0 & tmpFunction()) return; // BAD
|
||||||
|
}
|
||||||
|
void workFunction_1(char *s) {
|
||||||
|
int intA,intB;
|
||||||
|
|
||||||
|
if(intA + intB) return; // BAD
|
||||||
|
if(intA + intB>4) return; // GOOD
|
||||||
|
if(intA>0 && (intA + intB)) return; // BAD
|
||||||
|
while(intA>0)
|
||||||
|
{
|
||||||
|
if(intB - intA<10) break;
|
||||||
|
intA--;
|
||||||
|
}while(intA>0); // BAD
|
||||||
|
for(intA=100; intA>0; intA--)
|
||||||
|
{
|
||||||
|
if(intB - intA<10) break;
|
||||||
|
}while(intA>0); // BAD
|
||||||
|
while(intA>0)
|
||||||
|
{
|
||||||
|
if(intB - intA<10) break;
|
||||||
|
intA--;
|
||||||
|
} // GOOD
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
| test.c:42:3:42:24 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:54:3:54:24 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
| test.c:43:3:43:40 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:55:3:55:40 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
| test.c:44:3:44:40 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:56:3:56:44 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
| test.c:45:3:45:44 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:57:3:57:44 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
| test.c:46:3:46:44 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:58:3:58:48 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
| test.c:47:3:47:48 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:59:3:59:48 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
| test.c:48:3:48:48 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:60:3:60:52 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
| test.c:49:3:49:50 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:61:3:61:50 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
| test.c:50:3:50:50 | ... = ... | potential unsafe or redundant assignment. |
|
| test.c:62:3:62:54 | ... = ... | potential unsafe or redundant assignment. |
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
| test.c:4:3:4:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
|
| test.c:8:3:8:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
|
||||||
| test.c:11:3:11:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
|
| test.c:9:3:9:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
|
||||||
| test.c:19:3:19:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
|
| test.c:17:3:17:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
|
||||||
|
| test.c:18:3:18:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
|
||||||
|
| test.c:46:3:46:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
| test.cpp:10:8:10:10 | - ... | this expression needs attention |
|
||||||
|
| test.cpp:12:3:12:6 | ... ++ | this expression needs attention |
|
||||||
|
| test.cpp:13:3:13:6 | ++ ... | this expression needs attention |
|
||||||
|
| test.cpp:14:6:14:21 | ... = ... | this expression needs attention |
|
||||||
|
| test.cpp:16:6:16:21 | ... = ... | this expression needs attention |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.ql
|
||||||
@@ -1,70 +1,84 @@
|
|||||||
void workFunction_0(char *s) {
|
char * strncat(char*, const char*, unsigned);
|
||||||
|
unsigned strlen(const char*);
|
||||||
|
void* malloc(unsigned);
|
||||||
|
|
||||||
|
void strncat_test1(char *s) {
|
||||||
char buf[80];
|
char buf[80];
|
||||||
strncat(buf, s, sizeof(buf)-strlen(buf)-1); // GOOD
|
strncat(buf, s, sizeof(buf) - strlen(buf) - 1); // GOOD
|
||||||
strncat(buf, s, sizeof(buf)-strlen(buf)); // BAD
|
strncat(buf, s, sizeof(buf) - strlen(buf)); // BAD
|
||||||
strncat(buf, "fix", sizeof(buf)-strlen(buf)); // BAD [NOT DETECTED]
|
strncat(buf, "fix", sizeof(buf)-strlen(buf)); // BAD
|
||||||
}
|
}
|
||||||
void workFunction_1(char *s) {
|
|
||||||
#define MAX_SIZE 80
|
#define MAX_SIZE 80
|
||||||
|
|
||||||
|
void strncat_test2(char *s) {
|
||||||
char buf[MAX_SIZE];
|
char buf[MAX_SIZE];
|
||||||
strncat(buf, s, MAX_SIZE-strlen(buf)-1); // GOOD
|
strncat(buf, s, MAX_SIZE - strlen(buf) - 1); // GOOD
|
||||||
strncat(buf, s, MAX_SIZE-strlen(buf)); // BAD
|
strncat(buf, s, MAX_SIZE - strlen(buf)); // BAD
|
||||||
strncat(buf, "fix", MAX_SIZE-strlen(buf)); // BAD [NOT DETECTED]
|
strncat(buf, "fix", MAX_SIZE - strlen(buf)); // BAD
|
||||||
}
|
}
|
||||||
void workFunction_2_0(char *s) {
|
|
||||||
char * buf;
|
void strncat_test3(char *s) {
|
||||||
int len=80;
|
int len = 80;
|
||||||
buf = (char *) malloc(len);
|
char* buf = (char *) malloc(len);
|
||||||
strncat(buf, s, len-strlen(buf)-1); // GOOD
|
strncat(buf, s, len - strlen(buf) - 1); // GOOD
|
||||||
strncat(buf, s, len-strlen(buf)); // BAD
|
strncat(buf, s, len - strlen(buf)); // BAD [NOT DETECTED]
|
||||||
strncat(buf, "fix", len-strlen(buf)); // BAD [NOT DETECTED]
|
strncat(buf, "fix", len - strlen(buf)); // BAD [NOT DETECTED]
|
||||||
}
|
}
|
||||||
void workFunction_2_1(char *s) {
|
|
||||||
char * buf;
|
void strncat_test4(char *s) {
|
||||||
int len=80;
|
int len = 80;
|
||||||
buf = (char *) malloc(len+1);
|
char* buf = (char *) malloc(len + 1);
|
||||||
strncat(buf, s, len-strlen(buf)-1); // GOOD
|
strncat(buf, s, len - strlen(buf) - 1); // GOOD
|
||||||
strncat(buf, s, len-strlen(buf)); // GOOD
|
strncat(buf, s, len - strlen(buf)); // GOOD
|
||||||
}
|
}
|
||||||
|
|
||||||
struct buffers
|
struct buffers
|
||||||
{
|
{
|
||||||
unsigned char buff1[50];
|
unsigned char array[50];
|
||||||
unsigned char *buff2;
|
unsigned char *pointer;
|
||||||
} globalBuff1,*globalBuff2,globalBuff1_c,*globalBuff2_c;
|
} globalBuff1,*globalBuff2,globalBuff1_c,*globalBuff2_c;
|
||||||
|
|
||||||
|
void strncat_test5(char* s, struct buffers* buffers) {
|
||||||
|
unsigned len_array = strlen(buffers->array);
|
||||||
|
unsigned max_size = sizeof(buffers->array);
|
||||||
|
unsigned free_size = max_size - len_array;
|
||||||
|
strncat(buffers->array, s, free_size); // BAD
|
||||||
|
}
|
||||||
|
|
||||||
void badFunc0(){
|
void strlen_test1(){
|
||||||
unsigned char buff1[12];
|
unsigned char buff1[12];
|
||||||
struct buffers buffAll;
|
struct buffers buffAll;
|
||||||
struct buffers * buffAll1;
|
struct buffers * buffAll1;
|
||||||
|
|
||||||
buff1[strlen(buff1)]=0; // BAD
|
buff1[strlen(buff1)]=0; // BAD
|
||||||
buffAll.buff1[strlen(buffAll.buff1)]=0; // BAD
|
buffAll.array[strlen(buffAll.array)]=0; // BAD
|
||||||
buffAll.buff2[strlen(buffAll.buff2)]=0; // BAD
|
buffAll.pointer[strlen(buffAll.pointer)]=0; // BAD
|
||||||
buffAll1->buff1[strlen(buffAll1->buff1)]=0; // BAD
|
buffAll1->array[strlen(buffAll1->array)]=0; // BAD
|
||||||
buffAll1->buff2[strlen(buffAll1->buff2)]=0; // BAD
|
buffAll1->pointer[strlen(buffAll1->pointer)]=0; // BAD
|
||||||
globalBuff1.buff1[strlen(globalBuff1.buff1)]=0; // BAD
|
globalBuff1.array[strlen(globalBuff1.array)]=0; // BAD
|
||||||
globalBuff1.buff2[strlen(globalBuff1.buff2)]=0; // BAD
|
globalBuff1.pointer[strlen(globalBuff1.pointer)]=0; // BAD
|
||||||
globalBuff2->buff1[strlen(globalBuff2->buff1)]=0; // BAD
|
globalBuff2->array[strlen(globalBuff2->array)]=0; // BAD
|
||||||
globalBuff2->buff2[strlen(globalBuff2->buff2)]=0; // BAD
|
globalBuff2->pointer[strlen(globalBuff2->pointer)]=0; // BAD
|
||||||
}
|
}
|
||||||
void noBadFunc0(){
|
|
||||||
|
void strlen_test2(){
|
||||||
unsigned char buff1[12],buff1_c[12];
|
unsigned char buff1[12],buff1_c[12];
|
||||||
struct buffers buffAll,buffAll_c;
|
struct buffers buffAll,buffAll_c;
|
||||||
struct buffers * buffAll1,*buffAll1_c;
|
struct buffers * buffAll1,*buffAll1_c;
|
||||||
|
|
||||||
buff1[strlen(buff1_c)]=0; // GOOD
|
buff1[strlen(buff1_c)]=0; // GOOD
|
||||||
buffAll.buff1[strlen(buffAll_c.buff1)]=0; // GOOD
|
buffAll.array[strlen(buffAll_c.array)]=0; // GOOD
|
||||||
buffAll.buff2[strlen(buffAll.buff1)]=0; // GOOD
|
buffAll.pointer[strlen(buffAll.array)]=0; // GOOD
|
||||||
buffAll1->buff1[strlen(buffAll1_c->buff1)]=0; // GOOD
|
buffAll1->array[strlen(buffAll1_c->array)]=0; // GOOD
|
||||||
buffAll1->buff2[strlen(buffAll1->buff1)]=0; // GOOD
|
buffAll1->pointer[strlen(buffAll1->array)]=0; // GOOD
|
||||||
globalBuff1.buff1[strlen(globalBuff1_c.buff1)]=0; // GOOD
|
globalBuff1.array[strlen(globalBuff1_c.array)]=0; // GOOD
|
||||||
globalBuff1.buff2[strlen(globalBuff1.buff1)]=0; // GOOD
|
globalBuff1.pointer[strlen(globalBuff1.array)]=0; // GOOD
|
||||||
globalBuff2->buff1[strlen(globalBuff2_c->buff1)]=0; // GOOD
|
globalBuff2->array[strlen(globalBuff2_c->array)]=0; // GOOD
|
||||||
globalBuff2->buff2[strlen(globalBuff2->buff1)]=0; // GOOD
|
globalBuff2->pointer[strlen(globalBuff2->array)]=0; // GOOD
|
||||||
}
|
}
|
||||||
void goodFunc0(){
|
|
||||||
|
void strlen_test3(){
|
||||||
unsigned char buffer[12];
|
unsigned char buffer[12];
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 6; i++)
|
for(i = 0; i < 6; i++)
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
int tmpFunc()
|
||||||
|
{
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
void testFunction()
|
||||||
|
{
|
||||||
|
int i1,i2,i3;
|
||||||
|
bool b1,b2,b3;
|
||||||
|
char c1,c2,c3;
|
||||||
|
b1 = -b2; //BAD
|
||||||
|
b1 = !b2; //GOOD
|
||||||
|
b1++; //BAD
|
||||||
|
++b1; //BAD
|
||||||
|
if(i1=tmpFunc()!=i2) //BAD
|
||||||
|
return;
|
||||||
|
if(i1=tmpFunc()!=11) //BAD
|
||||||
|
return;
|
||||||
|
if((i1=tmpFunc())!=i2) //GOOD
|
||||||
|
return;
|
||||||
|
if((i1=tmpFunc())!=11) //GOOD
|
||||||
|
return;
|
||||||
|
if(i1=tmpFunc()!=1) //GOOD
|
||||||
|
return;
|
||||||
|
if(i1=tmpFunc()==b1) //GOOD
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ unreachableNodeCCtx
|
|||||||
localCallNodes
|
localCallNodes
|
||||||
postIsNotPre
|
postIsNotPre
|
||||||
postHasUniquePre
|
postHasUniquePre
|
||||||
|
| test.cpp:373:5:373:20 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||||
uniquePostUpdate
|
uniquePostUpdate
|
||||||
postIsInSameCallable
|
postIsInSameCallable
|
||||||
reverseRead
|
reverseRead
|
||||||
@@ -82,4 +83,5 @@ postWithInFlow
|
|||||||
| test.cpp:125:3:125:11 | Chi | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:125:3:125:11 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
| test.cpp:359:5:359:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:359:5:359:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
| test.cpp:373:5:373:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:373:5:373:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| test.cpp:373:5:373:20 | Store | PostUpdateNode should not be the target of local flow. |
|
||||||
| test.cpp:465:3:465:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:465:3:465:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ unreachableNodeCCtx
|
|||||||
localCallNodes
|
localCallNodes
|
||||||
postIsNotPre
|
postIsNotPre
|
||||||
postHasUniquePre
|
postHasUniquePre
|
||||||
|
| D.cpp:57:5:57:42 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||||
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||||
|
| simple.cpp:83:9:83:28 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||||
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||||
uniquePostUpdate
|
uniquePostUpdate
|
||||||
postIsInSameCallable
|
postIsInSameCallable
|
||||||
@@ -54,6 +56,7 @@ postWithInFlow
|
|||||||
| D.cpp:49:15:49:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
| D.cpp:49:15:49:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
| D.cpp:56:15:56:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
| D.cpp:56:15:56:24 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
| D.cpp:57:5:57:42 | Chi | PostUpdateNode should not be the target of local flow. |
|
| D.cpp:57:5:57:42 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| D.cpp:57:5:57:42 | Store | PostUpdateNode should not be the target of local flow. |
|
||||||
| aliasing.cpp:9:3:9:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
| aliasing.cpp:9:3:9:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
| aliasing.cpp:13:3:13:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
| aliasing.cpp:13:3:13:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
| aliasing.cpp:17:3:17:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
| aliasing.cpp:17:3:17:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
@@ -150,6 +153,7 @@ postWithInFlow
|
|||||||
| simple.cpp:23:35:23:35 | Chi | PostUpdateNode should not be the target of local flow. |
|
| simple.cpp:23:35:23:35 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should not be the target of local flow. |
|
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should not be the target of local flow. |
|
||||||
| simple.cpp:83:9:83:28 | Chi | PostUpdateNode should not be the target of local flow. |
|
| simple.cpp:83:9:83:28 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| simple.cpp:83:9:83:28 | Store | PostUpdateNode should not be the target of local flow. |
|
||||||
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should not be the target of local flow. |
|
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should not be the target of local flow. |
|
||||||
| struct_init.c:20:20:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
| struct_init.c:20:20:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
| struct_init.c:20:34:20:34 | Chi | PostUpdateNode should not be the target of local flow. |
|
| struct_init.c:20:34:20:34 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||||
|
|||||||
@@ -228,8 +228,8 @@ edges
|
|||||||
| simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] |
|
| simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] |
|
||||||
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] |
|
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] |
|
||||||
| simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i |
|
| simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i |
|
||||||
| simple.cpp:83:9:83:28 | Chi [f1] | simple.cpp:84:14:84:20 | this indirection [f1] |
|
| simple.cpp:83:9:83:28 | Store [f1] | simple.cpp:84:14:84:20 | this indirection [f1] |
|
||||||
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Chi [f1] |
|
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Store [f1] |
|
||||||
| simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
|
| simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
|
||||||
| simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] |
|
| simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] |
|
||||||
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] |
|
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] |
|
||||||
@@ -494,7 +494,7 @@ nodes
|
|||||||
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
|
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
|
||||||
| simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] |
|
| simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] |
|
||||||
| simple.cpp:67:13:67:13 | i | semmle.label | i |
|
| simple.cpp:67:13:67:13 | i | semmle.label | i |
|
||||||
| simple.cpp:83:9:83:28 | Chi [f1] | semmle.label | Chi [f1] |
|
| simple.cpp:83:9:83:28 | Store [f1] | semmle.label | Store [f1] |
|
||||||
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
|
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
|
||||||
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
|
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
|
||||||
| simple.cpp:84:14:84:20 | this indirection [f1] | semmle.label | this indirection [f1] |
|
| simple.cpp:84:14:84:20 | this indirection [f1] | semmle.label | this indirection [f1] |
|
||||||
|
|||||||
@@ -19,15 +19,19 @@ class IRPartialDefNode extends IRNode {
|
|||||||
override string toString() { result = n.asPartialDefinition().toString() }
|
override string toString() { result = n.asPartialDefinition().toString() }
|
||||||
}
|
}
|
||||||
|
|
||||||
from Node node, AST::Node astNode, IR::Node irNode, string msg
|
from Node node, string msg
|
||||||
where
|
where
|
||||||
node.asIR() = irNode and
|
exists(IR::Node irNode, Expr partial |
|
||||||
exists(irNode.asPartialDefinition()) and
|
node.asIR() = irNode and
|
||||||
not exists(AST::Node otherNode | otherNode.asPartialDefinition() = irNode.asPartialDefinition()) and
|
partial = irNode.asPartialDefinition() and
|
||||||
|
not exists(AST::Node otherNode | otherNode.asPartialDefinition() = partial)
|
||||||
|
) and
|
||||||
msg = "IR only"
|
msg = "IR only"
|
||||||
or
|
or
|
||||||
node.asAST() = astNode and
|
exists(AST::Node astNode, Expr partial |
|
||||||
exists(astNode.asPartialDefinition()) and
|
node.asAST() = astNode and
|
||||||
not exists(IR::Node otherNode | otherNode.asPartialDefinition() = astNode.asPartialDefinition()) and
|
partial = astNode.asPartialDefinition() and
|
||||||
|
not exists(IR::Node otherNode | otherNode.asPartialDefinition() = partial)
|
||||||
|
) and
|
||||||
msg = "AST only"
|
msg = "AST only"
|
||||||
select node, msg
|
select node, msg
|
||||||
|
|||||||
@@ -3223,49 +3223,63 @@
|
|||||||
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:12:11:12:11 | p | |
|
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:12:11:12:11 | p | |
|
||||||
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:13:10:13:10 | p | |
|
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:13:10:13:10 | p | |
|
||||||
| smart_pointer.cpp:11:52:11:57 | call to source | smart_pointer.cpp:11:30:11:50 | call to make_shared | TAINT |
|
| smart_pointer.cpp:11:52:11:57 | call to source | smart_pointer.cpp:11:30:11:50 | call to make_shared | TAINT |
|
||||||
| smart_pointer.cpp:12:11:12:11 | p | smart_pointer.cpp:12:10:12:10 | call to operator* | TAINT |
|
| smart_pointer.cpp:12:11:12:11 | p | smart_pointer.cpp:12:10:12:10 | call to operator* | |
|
||||||
| smart_pointer.cpp:12:11:12:11 | ref arg p | smart_pointer.cpp:13:10:13:10 | p | |
|
| smart_pointer.cpp:12:11:12:11 | ref arg p | smart_pointer.cpp:13:10:13:10 | p | |
|
||||||
| smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:18:11:18:11 | p | |
|
| smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:18:11:18:11 | p | |
|
||||||
| smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:19:10:19:10 | p | |
|
| smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:19:10:19:10 | p | |
|
||||||
|
| smart_pointer.cpp:18:10:18:10 | ref arg call to operator* | smart_pointer.cpp:18:11:18:11 | p [inner post update] | |
|
||||||
|
| smart_pointer.cpp:18:10:18:10 | ref arg call to operator* | smart_pointer.cpp:19:10:19:10 | p | |
|
||||||
| smart_pointer.cpp:18:11:18:11 | p | smart_pointer.cpp:18:10:18:10 | call to operator* | TAINT |
|
| smart_pointer.cpp:18:11:18:11 | p | smart_pointer.cpp:18:10:18:10 | call to operator* | TAINT |
|
||||||
|
| smart_pointer.cpp:18:11:18:11 | ref arg p | smart_pointer.cpp:18:11:18:11 | p [inner post update] | |
|
||||||
| smart_pointer.cpp:18:11:18:11 | ref arg p | smart_pointer.cpp:19:10:19:10 | p | |
|
| smart_pointer.cpp:18:11:18:11 | ref arg p | smart_pointer.cpp:19:10:19:10 | p | |
|
||||||
| smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:24:11:24:11 | p | |
|
| smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:24:11:24:11 | p | |
|
||||||
| smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:25:10:25:10 | p | |
|
| smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:25:10:25:10 | p | |
|
||||||
| smart_pointer.cpp:23:52:23:57 | call to source | smart_pointer.cpp:23:30:23:50 | call to make_unique | TAINT |
|
| smart_pointer.cpp:23:52:23:57 | call to source | smart_pointer.cpp:23:30:23:50 | call to make_unique | TAINT |
|
||||||
| smart_pointer.cpp:24:11:24:11 | p | smart_pointer.cpp:24:10:24:10 | call to operator* | TAINT |
|
| smart_pointer.cpp:24:11:24:11 | p | smart_pointer.cpp:24:10:24:10 | call to operator* | |
|
||||||
| smart_pointer.cpp:24:11:24:11 | ref arg p | smart_pointer.cpp:25:10:25:10 | p | |
|
| smart_pointer.cpp:24:11:24:11 | ref arg p | smart_pointer.cpp:25:10:25:10 | p | |
|
||||||
| smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:30:11:30:11 | p | |
|
| smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:30:11:30:11 | p | |
|
||||||
| smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:31:10:31:10 | p | |
|
| smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:31:10:31:10 | p | |
|
||||||
|
| smart_pointer.cpp:30:10:30:10 | ref arg call to operator* | smart_pointer.cpp:30:11:30:11 | p [inner post update] | |
|
||||||
|
| smart_pointer.cpp:30:10:30:10 | ref arg call to operator* | smart_pointer.cpp:31:10:31:10 | p | |
|
||||||
| smart_pointer.cpp:30:11:30:11 | p | smart_pointer.cpp:30:10:30:10 | call to operator* | TAINT |
|
| smart_pointer.cpp:30:11:30:11 | p | smart_pointer.cpp:30:10:30:10 | call to operator* | TAINT |
|
||||||
|
| smart_pointer.cpp:30:11:30:11 | ref arg p | smart_pointer.cpp:30:11:30:11 | p [inner post update] | |
|
||||||
| smart_pointer.cpp:30:11:30:11 | ref arg p | smart_pointer.cpp:31:10:31:10 | p | |
|
| smart_pointer.cpp:30:11:30:11 | ref arg p | smart_pointer.cpp:31:10:31:10 | p | |
|
||||||
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:37:6:37:6 | p | |
|
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:37:6:37:6 | p | |
|
||||||
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:38:10:38:10 | p | |
|
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:38:10:38:10 | p | |
|
||||||
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:39:11:39:11 | p | |
|
| smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:39:11:39:11 | p | |
|
||||||
|
| smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | smart_pointer.cpp:37:6:37:6 | p [inner post update] | |
|
||||||
|
| smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | smart_pointer.cpp:38:10:38:10 | p | |
|
||||||
|
| smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | smart_pointer.cpp:39:11:39:11 | p | |
|
||||||
| smart_pointer.cpp:37:5:37:17 | ... = ... | smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | |
|
| smart_pointer.cpp:37:5:37:17 | ... = ... | smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | |
|
||||||
| smart_pointer.cpp:37:6:37:6 | p | smart_pointer.cpp:37:5:37:5 | call to operator* | TAINT |
|
| smart_pointer.cpp:37:6:37:6 | p | smart_pointer.cpp:37:5:37:5 | call to operator* | |
|
||||||
|
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:37:6:37:6 | p [inner post update] | |
|
||||||
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:38:10:38:10 | p | |
|
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:38:10:38:10 | p | |
|
||||||
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | |
|
| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | |
|
||||||
| smart_pointer.cpp:37:10:37:15 | call to source | smart_pointer.cpp:37:5:37:17 | ... = ... | |
|
| smart_pointer.cpp:37:10:37:15 | call to source | smart_pointer.cpp:37:5:37:17 | ... = ... | |
|
||||||
| smart_pointer.cpp:38:10:38:10 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | |
|
| smart_pointer.cpp:38:10:38:10 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | |
|
||||||
| smart_pointer.cpp:39:11:39:11 | p | smart_pointer.cpp:39:10:39:10 | call to operator* | TAINT |
|
| smart_pointer.cpp:39:11:39:11 | p | smart_pointer.cpp:39:10:39:10 | call to operator* | |
|
||||||
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:45:6:45:6 | p | |
|
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:45:6:45:6 | p | |
|
||||||
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:46:10:46:10 | p | |
|
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:46:10:46:10 | p | |
|
||||||
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:47:11:47:11 | p | |
|
| smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:47:11:47:11 | p | |
|
||||||
|
| smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | smart_pointer.cpp:45:6:45:6 | p [inner post update] | |
|
||||||
|
| smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | smart_pointer.cpp:46:10:46:10 | p | |
|
||||||
|
| smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | smart_pointer.cpp:47:11:47:11 | p | |
|
||||||
| smart_pointer.cpp:45:5:45:17 | ... = ... | smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | |
|
| smart_pointer.cpp:45:5:45:17 | ... = ... | smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | |
|
||||||
| smart_pointer.cpp:45:6:45:6 | p | smart_pointer.cpp:45:5:45:5 | call to operator* | TAINT |
|
| smart_pointer.cpp:45:6:45:6 | p | smart_pointer.cpp:45:5:45:5 | call to operator* | |
|
||||||
|
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:45:6:45:6 | p [inner post update] | |
|
||||||
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:46:10:46:10 | p | |
|
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:46:10:46:10 | p | |
|
||||||
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | |
|
| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | |
|
||||||
| smart_pointer.cpp:45:10:45:15 | call to source | smart_pointer.cpp:45:5:45:17 | ... = ... | |
|
| smart_pointer.cpp:45:10:45:15 | call to source | smart_pointer.cpp:45:5:45:17 | ... = ... | |
|
||||||
| smart_pointer.cpp:46:10:46:10 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | |
|
| smart_pointer.cpp:46:10:46:10 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | |
|
||||||
| smart_pointer.cpp:47:11:47:11 | p | smart_pointer.cpp:47:10:47:10 | call to operator* | TAINT |
|
| smart_pointer.cpp:47:11:47:11 | p | smart_pointer.cpp:47:10:47:10 | call to operator* | |
|
||||||
| smart_pointer.cpp:51:30:51:50 | call to make_shared | smart_pointer.cpp:52:10:52:10 | p | |
|
| smart_pointer.cpp:51:30:51:50 | call to make_shared | smart_pointer.cpp:52:10:52:10 | p | |
|
||||||
| smart_pointer.cpp:51:52:51:57 | call to source | smart_pointer.cpp:51:30:51:50 | call to make_shared | TAINT |
|
| smart_pointer.cpp:51:52:51:57 | call to source | smart_pointer.cpp:51:30:51:50 | call to make_shared | TAINT |
|
||||||
| smart_pointer.cpp:52:10:52:10 | p | smart_pointer.cpp:52:12:52:14 | call to get | |
|
| smart_pointer.cpp:52:10:52:10 | p | smart_pointer.cpp:52:12:52:14 | call to get | |
|
||||||
| smart_pointer.cpp:52:12:52:14 | ref arg call to get | smart_pointer.cpp:52:10:52:10 | ref arg p | |
|
| smart_pointer.cpp:52:12:52:14 | ref arg call to get | smart_pointer.cpp:52:10:52:10 | ref arg p | TAINT |
|
||||||
| smart_pointer.cpp:56:30:56:50 | call to make_unique | smart_pointer.cpp:57:10:57:10 | p | |
|
| smart_pointer.cpp:56:30:56:50 | call to make_unique | smart_pointer.cpp:57:10:57:10 | p | |
|
||||||
| smart_pointer.cpp:56:52:56:57 | call to source | smart_pointer.cpp:56:30:56:50 | call to make_unique | TAINT |
|
| smart_pointer.cpp:56:52:56:57 | call to source | smart_pointer.cpp:56:30:56:50 | call to make_unique | TAINT |
|
||||||
| smart_pointer.cpp:57:10:57:10 | p | smart_pointer.cpp:57:12:57:14 | call to get | |
|
| smart_pointer.cpp:57:10:57:10 | p | smart_pointer.cpp:57:12:57:14 | call to get | |
|
||||||
| smart_pointer.cpp:57:12:57:14 | ref arg call to get | smart_pointer.cpp:57:10:57:10 | ref arg p | |
|
| smart_pointer.cpp:57:12:57:14 | ref arg call to get | smart_pointer.cpp:57:10:57:10 | ref arg p | TAINT |
|
||||||
| smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:66:10:66:10 | p | |
|
| smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:66:10:66:10 | p | |
|
||||||
| smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:67:10:67:10 | p | |
|
| smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:67:10:67:10 | p | |
|
||||||
| smart_pointer.cpp:65:48:65:53 | call to source | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT |
|
| smart_pointer.cpp:65:48:65:53 | call to source | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT |
|
||||||
@@ -3273,46 +3287,160 @@
|
|||||||
| smart_pointer.cpp:66:10:66:10 | p | smart_pointer.cpp:66:11:66:11 | call to operator-> | |
|
| smart_pointer.cpp:66:10:66:10 | p | smart_pointer.cpp:66:11:66:11 | call to operator-> | |
|
||||||
| smart_pointer.cpp:66:10:66:10 | ref arg p | smart_pointer.cpp:67:10:67:10 | p | |
|
| smart_pointer.cpp:66:10:66:10 | ref arg p | smart_pointer.cpp:67:10:67:10 | p | |
|
||||||
| smart_pointer.cpp:67:10:67:10 | p | smart_pointer.cpp:67:11:67:11 | call to operator-> | |
|
| smart_pointer.cpp:67:10:67:10 | p | smart_pointer.cpp:67:11:67:11 | call to operator-> | |
|
||||||
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:77:3:77:3 | p | |
|
| smart_pointer.cpp:70:37:70:39 | ptr | smart_pointer.cpp:70:37:70:39 | ptr | |
|
||||||
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:78:8:78:8 | p | |
|
| smart_pointer.cpp:70:37:70:39 | ptr | smart_pointer.cpp:71:4:71:6 | ptr | |
|
||||||
| smart_pointer.cpp:76:45:76:45 | p | smart_pointer.cpp:79:8:79:8 | p | |
|
| smart_pointer.cpp:71:3:71:3 | call to operator* [post update] | smart_pointer.cpp:70:37:70:39 | ptr | |
|
||||||
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:81:3:81:3 | q | |
|
| smart_pointer.cpp:71:3:71:3 | call to operator* [post update] | smart_pointer.cpp:71:4:71:6 | ptr [inner post update] | |
|
||||||
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:82:8:82:8 | q | |
|
| smart_pointer.cpp:71:3:71:17 | ... = ... | smart_pointer.cpp:71:3:71:3 | call to operator* [post update] | |
|
||||||
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:83:8:83:8 | q | |
|
| smart_pointer.cpp:71:4:71:6 | ptr | smart_pointer.cpp:71:3:71:3 | call to operator* | |
|
||||||
| smart_pointer.cpp:76:67:76:67 | q | smart_pointer.cpp:84:8:84:8 | q | |
|
| smart_pointer.cpp:71:4:71:6 | ref arg ptr | smart_pointer.cpp:70:37:70:39 | ptr | |
|
||||||
| smart_pointer.cpp:77:3:77:3 | p | smart_pointer.cpp:77:4:77:4 | call to operator-> | |
|
| smart_pointer.cpp:71:4:71:6 | ref arg ptr | smart_pointer.cpp:71:4:71:6 | ptr [inner post update] | |
|
||||||
| smart_pointer.cpp:77:3:77:3 | ref arg p | smart_pointer.cpp:78:8:78:8 | p | |
|
| smart_pointer.cpp:71:10:71:15 | call to source | smart_pointer.cpp:71:3:71:17 | ... = ... | |
|
||||||
| smart_pointer.cpp:77:3:77:3 | ref arg p | smart_pointer.cpp:79:8:79:8 | p | |
|
| smart_pointer.cpp:75:26:75:33 | call to shared_ptr | smart_pointer.cpp:76:13:76:13 | p | |
|
||||||
| smart_pointer.cpp:77:3:77:17 | ... = ... | smart_pointer.cpp:77:6:77:6 | x [post update] | |
|
| smart_pointer.cpp:75:26:75:33 | call to shared_ptr | smart_pointer.cpp:77:9:77:9 | p | |
|
||||||
| smart_pointer.cpp:77:3:77:17 | ... = ... | smart_pointer.cpp:78:11:78:11 | x | |
|
| smart_pointer.cpp:76:13:76:13 | p | smart_pointer.cpp:76:13:76:13 | call to shared_ptr | |
|
||||||
| smart_pointer.cpp:77:4:77:4 | call to operator-> [post update] | smart_pointer.cpp:77:3:77:3 | ref arg p | |
|
| smart_pointer.cpp:76:13:76:13 | ref arg call to shared_ptr | smart_pointer.cpp:76:13:76:13 | p [inner post update] | |
|
||||||
| smart_pointer.cpp:77:10:77:15 | call to source | smart_pointer.cpp:77:3:77:17 | ... = ... | |
|
| smart_pointer.cpp:76:13:76:13 | ref arg call to shared_ptr | smart_pointer.cpp:77:9:77:9 | p | |
|
||||||
| smart_pointer.cpp:78:8:78:8 | p | smart_pointer.cpp:78:9:78:9 | call to operator-> | |
|
| smart_pointer.cpp:76:13:76:13 | ref arg p | smart_pointer.cpp:76:13:76:13 | p [inner post update] | |
|
||||||
| smart_pointer.cpp:78:8:78:8 | ref arg p | smart_pointer.cpp:79:8:79:8 | p | |
|
| smart_pointer.cpp:76:13:76:13 | ref arg p | smart_pointer.cpp:77:9:77:9 | p | |
|
||||||
| smart_pointer.cpp:79:8:79:8 | p | smart_pointer.cpp:79:9:79:9 | call to operator-> | |
|
| smart_pointer.cpp:77:9:77:9 | p | smart_pointer.cpp:77:8:77:8 | call to operator* | |
|
||||||
| smart_pointer.cpp:81:3:81:3 | q | smart_pointer.cpp:81:4:81:4 | call to operator-> | |
|
| smart_pointer.cpp:86:45:86:45 | p | smart_pointer.cpp:86:45:86:45 | p | |
|
||||||
| smart_pointer.cpp:81:3:81:3 | ref arg q | smart_pointer.cpp:82:8:82:8 | q | |
|
| smart_pointer.cpp:86:45:86:45 | p | smart_pointer.cpp:87:3:87:3 | p | |
|
||||||
| smart_pointer.cpp:81:3:81:3 | ref arg q | smart_pointer.cpp:83:8:83:8 | q | |
|
| smart_pointer.cpp:86:45:86:45 | p | smart_pointer.cpp:88:8:88:8 | p | |
|
||||||
| smart_pointer.cpp:81:3:81:3 | ref arg q | smart_pointer.cpp:84:8:84:8 | q | |
|
| smart_pointer.cpp:86:45:86:45 | p | smart_pointer.cpp:89:8:89:8 | p | |
|
||||||
| smart_pointer.cpp:81:3:81:20 | ... = ... | smart_pointer.cpp:81:9:81:9 | x [post update] | |
|
| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:86:67:86:67 | q | |
|
||||||
| smart_pointer.cpp:81:3:81:20 | ... = ... | smart_pointer.cpp:82:14:82:14 | x | |
|
| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:91:3:91:3 | q | |
|
||||||
| smart_pointer.cpp:81:4:81:4 | call to operator-> [post update] | smart_pointer.cpp:81:3:81:3 | ref arg q | |
|
| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:92:8:92:8 | q | |
|
||||||
| smart_pointer.cpp:81:13:81:18 | call to source | smart_pointer.cpp:81:3:81:20 | ... = ... | |
|
| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:93:8:93:8 | q | |
|
||||||
| smart_pointer.cpp:82:8:82:8 | q | smart_pointer.cpp:82:9:82:9 | call to operator-> | |
|
| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:94:8:94:8 | q | |
|
||||||
| smart_pointer.cpp:82:8:82:8 | ref arg q | smart_pointer.cpp:83:8:83:8 | q | |
|
| smart_pointer.cpp:87:3:87:3 | p | smart_pointer.cpp:87:4:87:4 | call to operator-> | |
|
||||||
| smart_pointer.cpp:82:8:82:8 | ref arg q | smart_pointer.cpp:84:8:84:8 | q | |
|
| smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | |
|
||||||
| smart_pointer.cpp:83:8:83:8 | q | smart_pointer.cpp:83:9:83:9 | call to operator-> | |
|
| smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:88:8:88:8 | p | |
|
||||||
| smart_pointer.cpp:83:8:83:8 | ref arg q | smart_pointer.cpp:84:8:84:8 | q | |
|
| smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:89:8:89:8 | p | |
|
||||||
| smart_pointer.cpp:84:8:84:8 | q | smart_pointer.cpp:84:9:84:9 | call to operator-> | |
|
| smart_pointer.cpp:87:3:87:17 | ... = ... | smart_pointer.cpp:87:6:87:6 | x [post update] | |
|
||||||
| smart_pointer.cpp:87:17:87:18 | pa | smart_pointer.cpp:88:5:88:6 | pa | |
|
| smart_pointer.cpp:87:3:87:17 | ... = ... | smart_pointer.cpp:88:11:88:11 | x | |
|
||||||
| smart_pointer.cpp:88:5:88:20 | ... = ... | smart_pointer.cpp:88:9:88:9 | x [post update] | |
|
| smart_pointer.cpp:87:4:87:4 | call to operator-> [post update] | smart_pointer.cpp:87:3:87:3 | ref arg p | TAINT |
|
||||||
| smart_pointer.cpp:88:13:88:18 | call to source | smart_pointer.cpp:88:5:88:20 | ... = ... | |
|
| smart_pointer.cpp:87:10:87:15 | call to source | smart_pointer.cpp:87:3:87:17 | ... = ... | |
|
||||||
| smart_pointer.cpp:92:25:92:50 | call to unique_ptr | smart_pointer.cpp:93:11:93:11 | p | |
|
| smart_pointer.cpp:88:8:88:8 | p | smart_pointer.cpp:88:9:88:9 | call to operator-> | |
|
||||||
| smart_pointer.cpp:92:25:92:50 | call to unique_ptr | smart_pointer.cpp:94:8:94:8 | p | |
|
| smart_pointer.cpp:88:8:88:8 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | |
|
||||||
| smart_pointer.cpp:93:11:93:11 | p | smart_pointer.cpp:93:13:93:15 | call to get | |
|
| smart_pointer.cpp:88:8:88:8 | ref arg p | smart_pointer.cpp:89:8:89:8 | p | |
|
||||||
| smart_pointer.cpp:93:11:93:11 | ref arg p | smart_pointer.cpp:94:8:94:8 | p | |
|
| smart_pointer.cpp:89:8:89:8 | p | smart_pointer.cpp:89:9:89:9 | call to operator-> | |
|
||||||
| smart_pointer.cpp:93:13:93:15 | ref arg call to get | smart_pointer.cpp:93:11:93:11 | ref arg p | |
|
| smart_pointer.cpp:89:8:89:8 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | |
|
||||||
| smart_pointer.cpp:94:8:94:8 | p | smart_pointer.cpp:94:9:94:9 | call to operator-> | |
|
| smart_pointer.cpp:91:3:91:3 | q | smart_pointer.cpp:91:4:91:4 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | |
|
||||||
|
| smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:92:8:92:8 | q | |
|
||||||
|
| smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:93:8:93:8 | q | |
|
||||||
|
| smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | |
|
||||||
|
| smart_pointer.cpp:91:3:91:20 | ... = ... | smart_pointer.cpp:91:9:91:9 | x [post update] | |
|
||||||
|
| smart_pointer.cpp:91:3:91:20 | ... = ... | smart_pointer.cpp:92:14:92:14 | x | |
|
||||||
|
| smart_pointer.cpp:91:4:91:4 | call to operator-> [post update] | smart_pointer.cpp:91:3:91:3 | ref arg q | TAINT |
|
||||||
|
| smart_pointer.cpp:91:13:91:18 | call to source | smart_pointer.cpp:91:3:91:20 | ... = ... | |
|
||||||
|
| smart_pointer.cpp:92:8:92:8 | q | smart_pointer.cpp:92:9:92:9 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | |
|
||||||
|
| smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:93:8:93:8 | q | |
|
||||||
|
| smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | |
|
||||||
|
| smart_pointer.cpp:93:8:93:8 | q | smart_pointer.cpp:93:9:93:9 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:93:8:93:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | |
|
||||||
|
| smart_pointer.cpp:93:8:93:8 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | |
|
||||||
|
| smart_pointer.cpp:94:8:94:8 | q | smart_pointer.cpp:94:9:94:9 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:94:8:94:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | |
|
||||||
|
| smart_pointer.cpp:97:17:97:18 | pa | smart_pointer.cpp:98:5:98:6 | pa | |
|
||||||
|
| smart_pointer.cpp:98:5:98:20 | ... = ... | smart_pointer.cpp:98:9:98:9 | x [post update] | |
|
||||||
|
| smart_pointer.cpp:98:13:98:18 | call to source | smart_pointer.cpp:98:5:98:20 | ... = ... | |
|
||||||
|
| smart_pointer.cpp:102:25:102:50 | call to unique_ptr | smart_pointer.cpp:103:11:103:11 | p | |
|
||||||
|
| smart_pointer.cpp:102:25:102:50 | call to unique_ptr | smart_pointer.cpp:104:8:104:8 | p | |
|
||||||
|
| smart_pointer.cpp:103:11:103:11 | p | smart_pointer.cpp:103:13:103:15 | call to get | |
|
||||||
|
| smart_pointer.cpp:103:11:103:11 | ref arg p | smart_pointer.cpp:104:8:104:8 | p | |
|
||||||
|
| smart_pointer.cpp:103:13:103:15 | ref arg call to get | smart_pointer.cpp:103:11:103:11 | ref arg p | TAINT |
|
||||||
|
| smart_pointer.cpp:104:8:104:8 | p | smart_pointer.cpp:104:9:104:9 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:112:40:112:42 | ptr | smart_pointer.cpp:112:40:112:42 | ptr | |
|
||||||
|
| smart_pointer.cpp:112:40:112:42 | ptr | smart_pointer.cpp:113:2:113:4 | ptr | |
|
||||||
|
| smart_pointer.cpp:113:2:113:4 | ptr | smart_pointer.cpp:113:5:113:5 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:113:2:113:4 | ref arg ptr | smart_pointer.cpp:112:40:112:42 | ptr | |
|
||||||
|
| smart_pointer.cpp:113:2:113:18 | ... = ... | smart_pointer.cpp:113:7:113:7 | x [post update] | |
|
||||||
|
| smart_pointer.cpp:113:5:113:5 | call to operator-> [post update] | smart_pointer.cpp:113:2:113:4 | ref arg ptr | TAINT |
|
||||||
|
| smart_pointer.cpp:113:11:113:16 | call to source | smart_pointer.cpp:113:2:113:18 | ... = ... | |
|
||||||
|
| smart_pointer.cpp:116:52:116:54 | ptr | smart_pointer.cpp:116:52:116:54 | ptr | |
|
||||||
|
| smart_pointer.cpp:116:52:116:54 | ptr | smart_pointer.cpp:117:2:117:4 | ptr | |
|
||||||
|
| smart_pointer.cpp:117:2:117:4 | ptr | smart_pointer.cpp:117:5:117:5 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:117:2:117:4 | ref arg ptr | smart_pointer.cpp:116:52:116:54 | ptr | |
|
||||||
|
| smart_pointer.cpp:117:2:117:18 | ... = ... | smart_pointer.cpp:117:7:117:7 | x [post update] | |
|
||||||
|
| smart_pointer.cpp:117:5:117:5 | call to operator-> [post update] | smart_pointer.cpp:117:2:117:4 | ref arg ptr | TAINT |
|
||||||
|
| smart_pointer.cpp:117:11:117:16 | call to source | smart_pointer.cpp:117:2:117:18 | ... = ... | |
|
||||||
|
| smart_pointer.cpp:120:48:120:50 | ptr | smart_pointer.cpp:120:48:120:50 | ptr | |
|
||||||
|
| smart_pointer.cpp:120:48:120:50 | ptr | smart_pointer.cpp:121:4:121:6 | ptr | |
|
||||||
|
| smart_pointer.cpp:121:3:121:3 | call to operator* [post update] | smart_pointer.cpp:120:48:120:50 | ptr | |
|
||||||
|
| smart_pointer.cpp:121:3:121:3 | call to operator* [post update] | smart_pointer.cpp:121:4:121:6 | ptr [inner post update] | |
|
||||||
|
| smart_pointer.cpp:121:3:121:17 | ... = ... | smart_pointer.cpp:121:3:121:3 | call to operator* [post update] | |
|
||||||
|
| smart_pointer.cpp:121:4:121:6 | ptr | smart_pointer.cpp:121:3:121:3 | call to operator* | |
|
||||||
|
| smart_pointer.cpp:121:4:121:6 | ref arg ptr | smart_pointer.cpp:120:48:120:50 | ptr | |
|
||||||
|
| smart_pointer.cpp:121:4:121:6 | ref arg ptr | smart_pointer.cpp:121:4:121:6 | ptr [inner post update] | |
|
||||||
|
| smart_pointer.cpp:121:10:121:15 | call to source | smart_pointer.cpp:121:3:121:17 | ... = ... | |
|
||||||
|
| smart_pointer.cpp:124:48:124:49 | p1 | smart_pointer.cpp:124:48:124:49 | p1 | |
|
||||||
|
| smart_pointer.cpp:124:48:124:49 | p1 | smart_pointer.cpp:125:18:125:19 | p1 | |
|
||||||
|
| smart_pointer.cpp:124:48:124:49 | p1 | smart_pointer.cpp:126:8:126:9 | p1 | |
|
||||||
|
| smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:124:90:124:91 | p2 | |
|
||||||
|
| smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:128:14:128:15 | p2 | |
|
||||||
|
| smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:129:10:129:11 | p2 | |
|
||||||
|
| smart_pointer.cpp:125:18:125:19 | p1 | smart_pointer.cpp:125:20:125:20 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:125:18:125:19 | ref arg p1 | smart_pointer.cpp:124:48:124:49 | p1 | |
|
||||||
|
| smart_pointer.cpp:125:18:125:19 | ref arg p1 | smart_pointer.cpp:126:8:126:9 | p1 | |
|
||||||
|
| smart_pointer.cpp:125:18:125:22 | ref arg call to shared_ptr | smart_pointer.cpp:125:22:125:22 | q [inner post update] | |
|
||||||
|
| smart_pointer.cpp:125:20:125:20 | call to operator-> [post update] | smart_pointer.cpp:125:18:125:19 | ref arg p1 | TAINT |
|
||||||
|
| smart_pointer.cpp:125:22:125:22 | q | smart_pointer.cpp:125:18:125:22 | call to shared_ptr | |
|
||||||
|
| smart_pointer.cpp:125:22:125:22 | ref arg q | smart_pointer.cpp:125:22:125:22 | q [inner post update] | |
|
||||||
|
| smart_pointer.cpp:126:8:126:9 | p1 | smart_pointer.cpp:126:10:126:10 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:126:8:126:9 | ref arg p1 | smart_pointer.cpp:124:48:124:49 | p1 | |
|
||||||
|
| smart_pointer.cpp:126:10:126:10 | call to operator-> [post update] | smart_pointer.cpp:126:8:126:9 | ref arg p1 | TAINT |
|
||||||
|
| smart_pointer.cpp:126:12:126:12 | q | smart_pointer.cpp:126:13:126:13 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:128:13:128:13 | call to operator* | smart_pointer.cpp:128:13:128:15 | call to shared_ptr | TAINT |
|
||||||
|
| smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:124:90:124:91 | p2 | |
|
||||||
|
| smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:128:13:128:13 | call to operator* [inner post update] | |
|
||||||
|
| smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:128:14:128:15 | p2 [inner post update] | |
|
||||||
|
| smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:129:10:129:11 | p2 | |
|
||||||
|
| smart_pointer.cpp:128:13:128:15 | ref arg call to shared_ptr | smart_pointer.cpp:124:90:124:91 | p2 | |
|
||||||
|
| smart_pointer.cpp:128:13:128:15 | ref arg call to shared_ptr | smart_pointer.cpp:128:13:128:13 | call to operator* [inner post update] | |
|
||||||
|
| smart_pointer.cpp:128:13:128:15 | ref arg call to shared_ptr | smart_pointer.cpp:128:14:128:15 | p2 [inner post update] | |
|
||||||
|
| smart_pointer.cpp:128:13:128:15 | ref arg call to shared_ptr | smart_pointer.cpp:129:10:129:11 | p2 | |
|
||||||
|
| smart_pointer.cpp:128:14:128:15 | p2 | smart_pointer.cpp:128:13:128:13 | call to operator* | TAINT |
|
||||||
|
| smart_pointer.cpp:128:14:128:15 | ref arg p2 | smart_pointer.cpp:124:90:124:91 | p2 | |
|
||||||
|
| smart_pointer.cpp:128:14:128:15 | ref arg p2 | smart_pointer.cpp:128:14:128:15 | p2 [inner post update] | |
|
||||||
|
| smart_pointer.cpp:128:14:128:15 | ref arg p2 | smart_pointer.cpp:129:10:129:11 | p2 | |
|
||||||
|
| smart_pointer.cpp:129:9:129:9 | call to operator* | smart_pointer.cpp:129:8:129:8 | call to operator* | TAINT |
|
||||||
|
| smart_pointer.cpp:129:9:129:9 | ref arg call to operator* | smart_pointer.cpp:124:90:124:91 | p2 | |
|
||||||
|
| smart_pointer.cpp:129:9:129:9 | ref arg call to operator* | smart_pointer.cpp:129:10:129:11 | p2 [inner post update] | |
|
||||||
|
| smart_pointer.cpp:129:10:129:11 | p2 | smart_pointer.cpp:129:8:129:8 | call to operator* | |
|
||||||
|
| smart_pointer.cpp:129:10:129:11 | p2 | smart_pointer.cpp:129:9:129:9 | call to operator* | TAINT |
|
||||||
|
| smart_pointer.cpp:129:10:129:11 | ref arg p2 | smart_pointer.cpp:124:90:124:91 | p2 | |
|
||||||
|
| smart_pointer.cpp:129:10:129:11 | ref arg p2 | smart_pointer.cpp:129:10:129:11 | p2 [inner post update] | |
|
||||||
|
| smart_pointer.cpp:132:53:132:54 | p1 | smart_pointer.cpp:132:53:132:54 | p1 | |
|
||||||
|
| smart_pointer.cpp:132:53:132:54 | p1 | smart_pointer.cpp:133:23:133:24 | p1 | |
|
||||||
|
| smart_pointer.cpp:132:53:132:54 | p1 | smart_pointer.cpp:134:8:134:9 | p1 | |
|
||||||
|
| smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:132:95:132:96 | p2 | |
|
||||||
|
| smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:136:18:136:19 | p2 | |
|
||||||
|
| smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:137:10:137:11 | p2 | |
|
||||||
|
| smart_pointer.cpp:133:23:133:24 | p1 | smart_pointer.cpp:133:25:133:25 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:133:23:133:24 | ref arg p1 | smart_pointer.cpp:132:53:132:54 | p1 | |
|
||||||
|
| smart_pointer.cpp:133:23:133:24 | ref arg p1 | smart_pointer.cpp:134:8:134:9 | p1 | |
|
||||||
|
| smart_pointer.cpp:133:25:133:25 | call to operator-> [post update] | smart_pointer.cpp:133:23:133:24 | ref arg p1 | TAINT |
|
||||||
|
| smart_pointer.cpp:134:8:134:9 | p1 | smart_pointer.cpp:134:10:134:10 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:134:8:134:9 | ref arg p1 | smart_pointer.cpp:132:53:132:54 | p1 | |
|
||||||
|
| smart_pointer.cpp:134:10:134:10 | call to operator-> [post update] | smart_pointer.cpp:134:8:134:9 | ref arg p1 | TAINT |
|
||||||
|
| smart_pointer.cpp:134:12:134:12 | q | smart_pointer.cpp:134:13:134:13 | call to operator-> | |
|
||||||
|
| smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:132:95:132:96 | p2 | |
|
||||||
|
| smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:136:18:136:19 | p2 [inner post update] | |
|
||||||
|
| smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:137:10:137:11 | p2 | |
|
||||||
|
| smart_pointer.cpp:136:18:136:19 | p2 | smart_pointer.cpp:136:17:136:17 | call to operator* | TAINT |
|
||||||
|
| smart_pointer.cpp:136:18:136:19 | ref arg p2 | smart_pointer.cpp:132:95:132:96 | p2 | |
|
||||||
|
| smart_pointer.cpp:136:18:136:19 | ref arg p2 | smart_pointer.cpp:136:18:136:19 | p2 [inner post update] | |
|
||||||
|
| smart_pointer.cpp:136:18:136:19 | ref arg p2 | smart_pointer.cpp:137:10:137:11 | p2 | |
|
||||||
|
| smart_pointer.cpp:137:9:137:9 | call to operator* | smart_pointer.cpp:137:8:137:8 | call to operator* | TAINT |
|
||||||
|
| smart_pointer.cpp:137:9:137:9 | ref arg call to operator* | smart_pointer.cpp:132:95:132:96 | p2 | |
|
||||||
|
| smart_pointer.cpp:137:9:137:9 | ref arg call to operator* | smart_pointer.cpp:137:10:137:11 | p2 [inner post update] | |
|
||||||
|
| smart_pointer.cpp:137:10:137:11 | p2 | smart_pointer.cpp:137:8:137:8 | call to operator* | |
|
||||||
|
| smart_pointer.cpp:137:10:137:11 | p2 | smart_pointer.cpp:137:9:137:9 | call to operator* | TAINT |
|
||||||
|
| smart_pointer.cpp:137:10:137:11 | ref arg p2 | smart_pointer.cpp:132:95:132:96 | p2 | |
|
||||||
|
| smart_pointer.cpp:137:10:137:11 | ref arg p2 | smart_pointer.cpp:137:10:137:11 | p2 [inner post update] | |
|
||||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
|
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
|
||||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | |
|
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | |
|
||||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | |
|
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | |
|
||||||
@@ -3432,125 +3560,125 @@
|
|||||||
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
|
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
|
||||||
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
|
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
|
||||||
| stl.h:292:53:292:63 | 0 | stl.h:292:46:292:64 | (no string representation) | TAINT |
|
| stl.h:292:53:292:63 | 0 | stl.h:292:46:292:64 | (no string representation) | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||||
| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT |
|
| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | |
|
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | |
|
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | |
|
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | |
|
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | |
|
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | |
|
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | |
|
| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | |
|
| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | |
|
| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | |
|
| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | |
|
| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:395:3:395:6 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | |
|
| stl.h:396:3:396:6 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||||
| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | |
|
| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | |
|
||||||
| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | |
|
| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | |
|
||||||
| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | |
|
| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | |
|
||||||
| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | |
|
| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | |
|
||||||
| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | |
|
| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | |
|
||||||
| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | |
|
| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | |
|
||||||
| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | |
|
| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | |
|
||||||
| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | |
|
| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | |
|
||||||
| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | |
|
| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | |
|
||||||
| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | |
|
| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | |
|
||||||
| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | |
|
| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | |
|
||||||
| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | |
|
| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | |
|
||||||
| stl.h:395:36:395:43 | call to unknown function | stl.h:395:36:395:43 | constructor init of field first | TAINT |
|
| stl.h:396:36:396:43 | call to unknown function | stl.h:396:36:396:43 | constructor init of field first | TAINT |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | |
|
| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | |
|
||||||
| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT |
|
| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT |
|
||||||
| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT |
|
| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT |
|
||||||
| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT |
|
| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT |
|
||||||
| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT |
|
| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT |
|
||||||
| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT |
|
| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT |
|
||||||
| stl.h:395:46:395:54 | call to unknown function | stl.h:395:46:395:54 | constructor init of field second | TAINT |
|
| stl.h:396:46:396:54 | call to unknown function | stl.h:396:46:396:54 | constructor init of field second | TAINT |
|
||||||
| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT |
|
| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT |
|
||||||
| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT |
|
| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT |
|
||||||
| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT |
|
| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT |
|
||||||
| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT |
|
| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT |
|
||||||
| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT |
|
| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | |
|
||||||
| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | |
|
| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | |
|
||||||
| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | |
|
| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | |
|
||||||
| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | |
|
| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | |
|
||||||
| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | |
|
| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | |
|
||||||
| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | |
|
| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | |
|
||||||
| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | |
|
| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | |
|
||||||
| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | |
|
| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | |
|
||||||
| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | |
|
| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | |
|
||||||
| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT |
|
| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | |
|
| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | |
|
| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | |
|
| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | |
|
| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | |
|
| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | |
|
||||||
| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | |
|
| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | |
|
||||||
| string.cpp:25:12:25:17 | call to source | string.cpp:29:7:29:7 | a | |
|
| string.cpp:25:12:25:17 | call to source | string.cpp:29:7:29:7 | a | |
|
||||||
| string.cpp:26:16:26:20 | 123 | string.cpp:26:16:26:21 | call to basic_string | TAINT |
|
| string.cpp:26:16:26:20 | 123 | string.cpp:26:16:26:21 | call to basic_string | TAINT |
|
||||||
| string.cpp:26:16:26:21 | call to basic_string | string.cpp:30:7:30:7 | b | |
|
| string.cpp:26:16:26:21 | call to basic_string | string.cpp:30:7:30:7 | b | |
|
||||||
|
|||||||
@@ -35,16 +35,16 @@ void test_reverse_taint_shared() {
|
|||||||
std::shared_ptr<int> p = std::make_shared<int>();
|
std::shared_ptr<int> p = std::make_shared<int>();
|
||||||
|
|
||||||
*p = source();
|
*p = source();
|
||||||
sink(p); // $ MISSING: ast,ir
|
sink(p); // $ ast MISSING: ir
|
||||||
sink(*p); // $ MISSING: ast,ir
|
sink(*p); // $ ast MISSING: ir
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_reverse_taint_unique() {
|
void test_reverse_taint_unique() {
|
||||||
std::unique_ptr<int> p = std::unique_ptr<int>();
|
std::unique_ptr<int> p = std::unique_ptr<int>();
|
||||||
|
|
||||||
*p = source();
|
*p = source();
|
||||||
sink(p); // $ MISSING: ast,ir
|
sink(p); // $ ast MISSING: ir
|
||||||
sink(*p); // $ MISSING: ast,ir
|
sink(*p); // $ ast MISSING: ir
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_shared_get() {
|
void test_shared_get() {
|
||||||
@@ -67,6 +67,16 @@ void test_shared_field_member() {
|
|||||||
sink(p->y); // not tainted
|
sink(p->y); // not tainted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getNumber(std::shared_ptr<int> ptr) {
|
||||||
|
*ptr = source();
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_from_issue_5190() {
|
||||||
|
std::shared_ptr<int> p(new int);
|
||||||
|
getNumber(p);
|
||||||
|
sink(*p); // $ ast MISSING: ir
|
||||||
|
}
|
||||||
|
|
||||||
struct B {
|
struct B {
|
||||||
A a1;
|
A a1;
|
||||||
A a2;
|
A a2;
|
||||||
@@ -92,4 +102,37 @@ void reverse_taint_smart_pointer() {
|
|||||||
std::unique_ptr<A> p = std::unique_ptr<A>(new A);
|
std::unique_ptr<A> p = std::unique_ptr<A>(new A);
|
||||||
taint_x(p.get());
|
taint_x(p.get());
|
||||||
sink(p->x); // $ ast MISSING: ir
|
sink(p->x); // $ ast MISSING: ir
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C {
|
||||||
|
int z;
|
||||||
|
std::shared_ptr<A> q;
|
||||||
|
};
|
||||||
|
|
||||||
|
void taint_x_shared(std::shared_ptr<A> ptr) {
|
||||||
|
ptr->x = source();
|
||||||
|
}
|
||||||
|
|
||||||
|
void taint_x_shared_cref(const std::shared_ptr<A>& ptr) {
|
||||||
|
ptr->x = source();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getNumberCRef(const std::shared_ptr<int>& ptr) {
|
||||||
|
*ptr = source();
|
||||||
|
}
|
||||||
|
|
||||||
|
int nested_shared_ptr_taint(std::shared_ptr<C> p1, std::unique_ptr<std::shared_ptr<int>> p2) {
|
||||||
|
taint_x_shared(p1->q);
|
||||||
|
sink(p1->q->x); // $ ast MISSING: ir
|
||||||
|
|
||||||
|
getNumber(*p2);
|
||||||
|
sink(**p2); // $ ast MISSING: ir
|
||||||
|
}
|
||||||
|
|
||||||
|
int nested_shared_ptr_taint_cref(std::shared_ptr<C> p1, std::unique_ptr<std::shared_ptr<int>> p2) {
|
||||||
|
taint_x_shared_cref(p1->q);
|
||||||
|
sink(p1->q->x); // $ ast MISSING: ir
|
||||||
|
|
||||||
|
getNumberCRef(*p2);
|
||||||
|
sink(**p2); // $ ast MISSING: ir
|
||||||
}
|
}
|
||||||
@@ -349,6 +349,7 @@ namespace std {
|
|||||||
public:
|
public:
|
||||||
shared_ptr() noexcept;
|
shared_ptr() noexcept;
|
||||||
explicit shared_ptr(T*);
|
explicit shared_ptr(T*);
|
||||||
|
shared_ptr(const shared_ptr&) noexcept;
|
||||||
template<class U> shared_ptr(const shared_ptr<U>&) noexcept;
|
template<class U> shared_ptr(const shared_ptr<U>&) noexcept;
|
||||||
template<class U> shared_ptr(shared_ptr<U>&&) noexcept;
|
template<class U> shared_ptr(shared_ptr<U>&&) noexcept;
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ bad_asts.cpp:
|
|||||||
# 16| r16_3(int) = Constant[1] :
|
# 16| r16_3(int) = Constant[1] :
|
||||||
# 16| r16_4(int) = Call[MemberFunction] : func:r16_2, this:r16_1, 0:r16_3
|
# 16| r16_4(int) = Call[MemberFunction] : func:r16_2, this:r16_1, 0:r16_3
|
||||||
# 16| mu16_5(unknown) = ^CallSideEffect : ~m?
|
# 16| mu16_5(unknown) = ^CallSideEffect : ~m?
|
||||||
# 16| v16_6(void) = ^BufferReadSideEffect[-1] : &:r16_1, ~m?
|
# 16| v16_6(void) = ^IndirectReadSideEffect[-1] : &:r16_1, ~m?
|
||||||
# 16| mu16_7(S) = ^IndirectMayWriteSideEffect[-1] : &:r16_1
|
# 16| mu16_7(S) = ^IndirectMayWriteSideEffect[-1] : &:r16_1
|
||||||
# 17| v17_1(void) = NoOp :
|
# 17| v17_1(void) = NoOp :
|
||||||
# 14| v14_4(void) = ReturnVoid :
|
# 14| v14_4(void) = ReturnVoid :
|
||||||
@@ -3385,47 +3385,46 @@ ir.cpp:
|
|||||||
|
|
||||||
# 622| void CallMethods(String&, String*, String)
|
# 622| void CallMethods(String&, String*, String)
|
||||||
# 622| Block 0
|
# 622| Block 0
|
||||||
# 622| v622_1(void) = EnterFunction :
|
# 622| v622_1(void) = EnterFunction :
|
||||||
# 622| mu622_2(unknown) = AliasedDefinition :
|
# 622| mu622_2(unknown) = AliasedDefinition :
|
||||||
# 622| mu622_3(unknown) = InitializeNonLocal :
|
# 622| mu622_3(unknown) = InitializeNonLocal :
|
||||||
# 622| r622_4(glval<String &>) = VariableAddress[r] :
|
# 622| r622_4(glval<String &>) = VariableAddress[r] :
|
||||||
# 622| mu622_5(String &) = InitializeParameter[r] : &:r622_4
|
# 622| mu622_5(String &) = InitializeParameter[r] : &:r622_4
|
||||||
# 622| r622_6(String &) = Load[r] : &:r622_4, ~m?
|
# 622| r622_6(String &) = Load[r] : &:r622_4, ~m?
|
||||||
# 622| mu622_7(unknown) = InitializeIndirection[r] : &:r622_6
|
# 622| mu622_7(unknown) = InitializeIndirection[r] : &:r622_6
|
||||||
# 622| r622_8(glval<String *>) = VariableAddress[p] :
|
# 622| r622_8(glval<String *>) = VariableAddress[p] :
|
||||||
# 622| mu622_9(String *) = InitializeParameter[p] : &:r622_8
|
# 622| mu622_9(String *) = InitializeParameter[p] : &:r622_8
|
||||||
# 622| r622_10(String *) = Load[p] : &:r622_8, ~m?
|
# 622| r622_10(String *) = Load[p] : &:r622_8, ~m?
|
||||||
# 622| mu622_11(unknown) = InitializeIndirection[p] : &:r622_10
|
# 622| mu622_11(unknown) = InitializeIndirection[p] : &:r622_10
|
||||||
# 622| r622_12(glval<String>) = VariableAddress[s] :
|
# 622| r622_12(glval<String>) = VariableAddress[s] :
|
||||||
# 622| mu622_13(String) = InitializeParameter[s] : &:r622_12
|
# 622| mu622_13(String) = InitializeParameter[s] : &:r622_12
|
||||||
# 623| r623_1(glval<String &>) = VariableAddress[r] :
|
# 623| r623_1(glval<String &>) = VariableAddress[r] :
|
||||||
# 623| r623_2(String &) = Load[r] : &:r623_1, ~m?
|
# 623| r623_2(String &) = Load[r] : &:r623_1, ~m?
|
||||||
# 623| r623_3(glval<String>) = CopyValue : r623_2
|
# 623| r623_3(glval<String>) = CopyValue : r623_2
|
||||||
# 623| r623_4(glval<String>) = Convert : r623_3
|
# 623| r623_4(glval<String>) = Convert : r623_3
|
||||||
# 623| r623_5(glval<unknown>) = FunctionAddress[c_str] :
|
# 623| r623_5(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 623| r623_6(char *) = Call[c_str] : func:r623_5, this:r623_4
|
# 623| r623_6(char *) = Call[c_str] : func:r623_5, this:r623_4
|
||||||
# 623| mu623_7(unknown) = ^CallSideEffect : ~m?
|
# 623| mu623_7(unknown) = ^CallSideEffect : ~m?
|
||||||
# 623| v623_8(void) = ^BufferReadSideEffect[-1] : &:r623_4, ~m?
|
# 623| v623_8(void) = ^IndirectReadSideEffect[-1] : &:r623_4, ~m?
|
||||||
# 624| r624_1(glval<String *>) = VariableAddress[p] :
|
# 624| r624_1(glval<String *>) = VariableAddress[p] :
|
||||||
# 624| r624_2(String *) = Load[p] : &:r624_1, ~m?
|
# 624| r624_2(String *) = Load[p] : &:r624_1, ~m?
|
||||||
# 624| r624_3(String *) = Convert : r624_2
|
# 624| r624_3(String *) = Convert : r624_2
|
||||||
# 624| r624_4(glval<unknown>) = FunctionAddress[c_str] :
|
# 624| r624_4(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 624| r624_5(char *) = Call[c_str] : func:r624_4, this:r624_3
|
# 624| r624_5(char *) = Call[c_str] : func:r624_4, this:r624_3
|
||||||
# 624| mu624_6(unknown) = ^CallSideEffect : ~m?
|
# 624| mu624_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 624| v624_7(void) = ^BufferReadSideEffect[-1] : &:r624_3, ~m?
|
# 624| v624_7(void) = ^IndirectReadSideEffect[-1] : &:r624_3, ~m?
|
||||||
# 624| mu624_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r624_3
|
# 625| r625_1(glval<String>) = VariableAddress[s] :
|
||||||
# 625| r625_1(glval<String>) = VariableAddress[s] :
|
# 625| r625_2(glval<String>) = Convert : r625_1
|
||||||
# 625| r625_2(glval<String>) = Convert : r625_1
|
# 625| r625_3(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 625| r625_3(glval<unknown>) = FunctionAddress[c_str] :
|
# 625| r625_4(char *) = Call[c_str] : func:r625_3, this:r625_2
|
||||||
# 625| r625_4(char *) = Call[c_str] : func:r625_3, this:r625_2
|
# 625| mu625_5(unknown) = ^CallSideEffect : ~m?
|
||||||
# 625| mu625_5(unknown) = ^CallSideEffect : ~m?
|
# 625| v625_6(void) = ^IndirectReadSideEffect[-1] : &:r625_2, ~m?
|
||||||
# 625| v625_6(void) = ^BufferReadSideEffect[-1] : &:r625_2, ~m?
|
# 626| v626_1(void) = NoOp :
|
||||||
# 626| v626_1(void) = NoOp :
|
# 622| v622_14(void) = ReturnIndirection[r] : &:r622_6, ~m?
|
||||||
# 622| v622_14(void) = ReturnIndirection[r] : &:r622_6, ~m?
|
# 622| v622_15(void) = ReturnIndirection[p] : &:r622_10, ~m?
|
||||||
# 622| v622_15(void) = ReturnIndirection[p] : &:r622_10, ~m?
|
# 622| v622_16(void) = ReturnVoid :
|
||||||
# 622| v622_16(void) = ReturnVoid :
|
# 622| v622_17(void) = AliasedUse : ~m?
|
||||||
# 622| v622_17(void) = AliasedUse : ~m?
|
# 622| v622_18(void) = ExitFunction :
|
||||||
# 622| v622_18(void) = ExitFunction :
|
|
||||||
|
|
||||||
# 628| void C::~C()
|
# 628| void C::~C()
|
||||||
# 628| Block 0
|
# 628| Block 0
|
||||||
@@ -3575,7 +3574,7 @@ ir.cpp:
|
|||||||
# 653| r653_4(int) = Constant[0] :
|
# 653| r653_4(int) = Constant[0] :
|
||||||
# 653| r653_5(int) = Call[InstanceMemberFunction] : func:r653_3, this:r653_2, 0:r653_4
|
# 653| r653_5(int) = Call[InstanceMemberFunction] : func:r653_3, this:r653_2, 0:r653_4
|
||||||
# 653| mu653_6(unknown) = ^CallSideEffect : ~m?
|
# 653| mu653_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 653| v653_7(void) = ^BufferReadSideEffect[-1] : &:r653_2, ~m?
|
# 653| v653_7(void) = ^IndirectReadSideEffect[-1] : &:r653_2, ~m?
|
||||||
# 653| mu653_8(C) = ^IndirectMayWriteSideEffect[-1] : &:r653_2
|
# 653| mu653_8(C) = ^IndirectMayWriteSideEffect[-1] : &:r653_2
|
||||||
# 654| r654_1(glval<unknown>) = VariableAddress[#this] :
|
# 654| r654_1(glval<unknown>) = VariableAddress[#this] :
|
||||||
# 654| r654_2(C *) = Load[#this] : &:r654_1, ~m?
|
# 654| r654_2(C *) = Load[#this] : &:r654_1, ~m?
|
||||||
@@ -3584,7 +3583,7 @@ ir.cpp:
|
|||||||
# 654| r654_5(int) = Constant[1] :
|
# 654| r654_5(int) = Constant[1] :
|
||||||
# 654| r654_6(int) = Call[InstanceMemberFunction] : func:r654_4, this:r654_3, 0:r654_5
|
# 654| r654_6(int) = Call[InstanceMemberFunction] : func:r654_4, this:r654_3, 0:r654_5
|
||||||
# 654| mu654_7(unknown) = ^CallSideEffect : ~m?
|
# 654| mu654_7(unknown) = ^CallSideEffect : ~m?
|
||||||
# 654| v654_8(void) = ^BufferReadSideEffect[-1] : &:r654_3, ~m?
|
# 654| v654_8(void) = ^IndirectReadSideEffect[-1] : &:r654_3, ~m?
|
||||||
# 654| mu654_9(C) = ^IndirectMayWriteSideEffect[-1] : &:r654_3
|
# 654| mu654_9(C) = ^IndirectMayWriteSideEffect[-1] : &:r654_3
|
||||||
# 655| r655_1(glval<unknown>) = VariableAddress[#this] :
|
# 655| r655_1(glval<unknown>) = VariableAddress[#this] :
|
||||||
# 655| r655_2(C *) = Load[#this] : &:r655_1, ~m?
|
# 655| r655_2(C *) = Load[#this] : &:r655_1, ~m?
|
||||||
@@ -3592,7 +3591,7 @@ ir.cpp:
|
|||||||
# 655| r655_4(int) = Constant[2] :
|
# 655| r655_4(int) = Constant[2] :
|
||||||
# 655| r655_5(int) = Call[InstanceMemberFunction] : func:r655_3, this:r655_2, 0:r655_4
|
# 655| r655_5(int) = Call[InstanceMemberFunction] : func:r655_3, this:r655_2, 0:r655_4
|
||||||
# 655| mu655_6(unknown) = ^CallSideEffect : ~m?
|
# 655| mu655_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 655| v655_7(void) = ^BufferReadSideEffect[-1] : &:r655_2, ~m?
|
# 655| v655_7(void) = ^IndirectReadSideEffect[-1] : &:r655_2, ~m?
|
||||||
# 655| mu655_8(C) = ^IndirectMayWriteSideEffect[-1] : &:r655_2
|
# 655| mu655_8(C) = ^IndirectMayWriteSideEffect[-1] : &:r655_2
|
||||||
# 656| v656_1(void) = NoOp :
|
# 656| v656_1(void) = NoOp :
|
||||||
# 652| v652_8(void) = ReturnIndirection[#this] : &:r652_6, ~m?
|
# 652| v652_8(void) = ReturnIndirection[#this] : &:r652_6, ~m?
|
||||||
@@ -4006,7 +4005,7 @@ ir.cpp:
|
|||||||
#-----| r0_6(String &) = CopyValue : r745_15
|
#-----| r0_6(String &) = CopyValue : r745_15
|
||||||
# 745| r745_16(String &) = Call[operator=] : func:r745_12, this:r745_11, 0:r0_6
|
# 745| r745_16(String &) = Call[operator=] : func:r745_12, this:r745_11, 0:r0_6
|
||||||
# 745| mu745_17(unknown) = ^CallSideEffect : ~m?
|
# 745| mu745_17(unknown) = ^CallSideEffect : ~m?
|
||||||
# 745| v745_18(void) = ^BufferReadSideEffect[-1] : &:r745_11, ~m?
|
# 745| v745_18(void) = ^IndirectReadSideEffect[-1] : &:r745_11, ~m?
|
||||||
#-----| v0_7(void) = ^BufferReadSideEffect[0] : &:r0_6, ~m?
|
#-----| v0_7(void) = ^BufferReadSideEffect[0] : &:r0_6, ~m?
|
||||||
# 745| mu745_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r745_11
|
# 745| mu745_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r745_11
|
||||||
#-----| r0_8(glval<String>) = CopyValue : r745_16
|
#-----| r0_8(glval<String>) = CopyValue : r745_16
|
||||||
@@ -4113,7 +4112,7 @@ ir.cpp:
|
|||||||
#-----| r0_8(Base &) = CopyValue : r754_14
|
#-----| r0_8(Base &) = CopyValue : r754_14
|
||||||
# 754| r754_15(Base &) = Call[operator=] : func:r754_10, this:r0_5, 0:r0_8
|
# 754| r754_15(Base &) = Call[operator=] : func:r754_10, this:r0_5, 0:r0_8
|
||||||
# 754| mu754_16(unknown) = ^CallSideEffect : ~m?
|
# 754| mu754_16(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_9(void) = ^BufferReadSideEffect[-1] : &:r0_5, ~m?
|
#-----| v0_9(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m?
|
||||||
#-----| v0_10(void) = ^BufferReadSideEffect[0] : &:r0_8, ~m?
|
#-----| v0_10(void) = ^BufferReadSideEffect[0] : &:r0_8, ~m?
|
||||||
#-----| mu0_11(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_5
|
#-----| mu0_11(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_5
|
||||||
#-----| r0_12(glval<Base>) = CopyValue : r754_15
|
#-----| r0_12(glval<Base>) = CopyValue : r754_15
|
||||||
@@ -4129,7 +4128,7 @@ ir.cpp:
|
|||||||
#-----| r0_14(String &) = CopyValue : r754_24
|
#-----| r0_14(String &) = CopyValue : r754_24
|
||||||
# 754| r754_25(String &) = Call[operator=] : func:r754_21, this:r754_20, 0:r0_14
|
# 754| r754_25(String &) = Call[operator=] : func:r754_21, this:r754_20, 0:r0_14
|
||||||
# 754| mu754_26(unknown) = ^CallSideEffect : ~m?
|
# 754| mu754_26(unknown) = ^CallSideEffect : ~m?
|
||||||
# 754| v754_27(void) = ^BufferReadSideEffect[-1] : &:r754_20, ~m?
|
# 754| v754_27(void) = ^IndirectReadSideEffect[-1] : &:r754_20, ~m?
|
||||||
#-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_14, ~m?
|
#-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_14, ~m?
|
||||||
# 754| mu754_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r754_20
|
# 754| mu754_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r754_20
|
||||||
#-----| r0_16(glval<String>) = CopyValue : r754_25
|
#-----| r0_16(glval<String>) = CopyValue : r754_25
|
||||||
@@ -4220,7 +4219,7 @@ ir.cpp:
|
|||||||
#-----| r0_8(Middle &) = CopyValue : r763_14
|
#-----| r0_8(Middle &) = CopyValue : r763_14
|
||||||
# 763| r763_15(Middle &) = Call[operator=] : func:r763_10, this:r0_5, 0:r0_8
|
# 763| r763_15(Middle &) = Call[operator=] : func:r763_10, this:r0_5, 0:r0_8
|
||||||
# 763| mu763_16(unknown) = ^CallSideEffect : ~m?
|
# 763| mu763_16(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_9(void) = ^BufferReadSideEffect[-1] : &:r0_5, ~m?
|
#-----| v0_9(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m?
|
||||||
#-----| v0_10(void) = ^BufferReadSideEffect[0] : &:r0_8, ~m?
|
#-----| v0_10(void) = ^BufferReadSideEffect[0] : &:r0_8, ~m?
|
||||||
#-----| mu0_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_5
|
#-----| mu0_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_5
|
||||||
#-----| r0_12(glval<Middle>) = CopyValue : r763_15
|
#-----| r0_12(glval<Middle>) = CopyValue : r763_15
|
||||||
@@ -4236,7 +4235,7 @@ ir.cpp:
|
|||||||
#-----| r0_14(String &) = CopyValue : r763_24
|
#-----| r0_14(String &) = CopyValue : r763_24
|
||||||
# 763| r763_25(String &) = Call[operator=] : func:r763_21, this:r763_20, 0:r0_14
|
# 763| r763_25(String &) = Call[operator=] : func:r763_21, this:r763_20, 0:r0_14
|
||||||
# 763| mu763_26(unknown) = ^CallSideEffect : ~m?
|
# 763| mu763_26(unknown) = ^CallSideEffect : ~m?
|
||||||
# 763| v763_27(void) = ^BufferReadSideEffect[-1] : &:r763_20, ~m?
|
# 763| v763_27(void) = ^IndirectReadSideEffect[-1] : &:r763_20, ~m?
|
||||||
#-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_14, ~m?
|
#-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_14, ~m?
|
||||||
# 763| mu763_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r763_20
|
# 763| mu763_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r763_20
|
||||||
#-----| r0_16(glval<String>) = CopyValue : r763_25
|
#-----| r0_16(glval<String>) = CopyValue : r763_25
|
||||||
@@ -4505,7 +4504,7 @@ ir.cpp:
|
|||||||
# 808| r808_5(Base &) = CopyValue : r808_4
|
# 808| r808_5(Base &) = CopyValue : r808_4
|
||||||
# 808| r808_6(Base &) = Call[operator=] : func:r808_2, this:r808_1, 0:r808_5
|
# 808| r808_6(Base &) = Call[operator=] : func:r808_2, this:r808_1, 0:r808_5
|
||||||
# 808| mu808_7(unknown) = ^CallSideEffect : ~m?
|
# 808| mu808_7(unknown) = ^CallSideEffect : ~m?
|
||||||
# 808| v808_8(void) = ^BufferReadSideEffect[-1] : &:r808_1, ~m?
|
# 808| v808_8(void) = ^IndirectReadSideEffect[-1] : &:r808_1, ~m?
|
||||||
# 808| v808_9(void) = ^BufferReadSideEffect[0] : &:r808_5, ~m?
|
# 808| v808_9(void) = ^BufferReadSideEffect[0] : &:r808_5, ~m?
|
||||||
# 808| mu808_10(Base) = ^IndirectMayWriteSideEffect[-1] : &:r808_1
|
# 808| mu808_10(Base) = ^IndirectMayWriteSideEffect[-1] : &:r808_1
|
||||||
# 808| r808_11(glval<Base>) = CopyValue : r808_6
|
# 808| r808_11(glval<Base>) = CopyValue : r808_6
|
||||||
@@ -4525,7 +4524,7 @@ ir.cpp:
|
|||||||
# 809| r809_14(Base &) = CopyValue : r809_13
|
# 809| r809_14(Base &) = CopyValue : r809_13
|
||||||
# 809| r809_15(Base &) = Call[operator=] : func:r809_2, this:r809_1, 0:r809_14
|
# 809| r809_15(Base &) = Call[operator=] : func:r809_2, this:r809_1, 0:r809_14
|
||||||
# 809| mu809_16(unknown) = ^CallSideEffect : ~m?
|
# 809| mu809_16(unknown) = ^CallSideEffect : ~m?
|
||||||
# 809| v809_17(void) = ^BufferReadSideEffect[-1] : &:r809_1, ~m?
|
# 809| v809_17(void) = ^IndirectReadSideEffect[-1] : &:r809_1, ~m?
|
||||||
# 809| v809_18(void) = ^BufferReadSideEffect[0] : &:r809_14, ~m?
|
# 809| v809_18(void) = ^BufferReadSideEffect[0] : &:r809_14, ~m?
|
||||||
# 809| mu809_19(Base) = ^IndirectMayWriteSideEffect[-1] : &:r809_1
|
# 809| mu809_19(Base) = ^IndirectMayWriteSideEffect[-1] : &:r809_1
|
||||||
# 809| r809_20(glval<Base>) = CopyValue : r809_15
|
# 809| r809_20(glval<Base>) = CopyValue : r809_15
|
||||||
@@ -4545,7 +4544,7 @@ ir.cpp:
|
|||||||
# 810| r810_14(Base &) = CopyValue : r810_13
|
# 810| r810_14(Base &) = CopyValue : r810_13
|
||||||
# 810| r810_15(Base &) = Call[operator=] : func:r810_2, this:r810_1, 0:r810_14
|
# 810| r810_15(Base &) = Call[operator=] : func:r810_2, this:r810_1, 0:r810_14
|
||||||
# 810| mu810_16(unknown) = ^CallSideEffect : ~m?
|
# 810| mu810_16(unknown) = ^CallSideEffect : ~m?
|
||||||
# 810| v810_17(void) = ^BufferReadSideEffect[-1] : &:r810_1, ~m?
|
# 810| v810_17(void) = ^IndirectReadSideEffect[-1] : &:r810_1, ~m?
|
||||||
# 810| v810_18(void) = ^BufferReadSideEffect[0] : &:r810_14, ~m?
|
# 810| v810_18(void) = ^BufferReadSideEffect[0] : &:r810_14, ~m?
|
||||||
# 810| mu810_19(Base) = ^IndirectMayWriteSideEffect[-1] : &:r810_1
|
# 810| mu810_19(Base) = ^IndirectMayWriteSideEffect[-1] : &:r810_1
|
||||||
# 810| r810_20(glval<Base>) = CopyValue : r810_15
|
# 810| r810_20(glval<Base>) = CopyValue : r810_15
|
||||||
@@ -4577,7 +4576,7 @@ ir.cpp:
|
|||||||
# 816| r816_6(Middle &) = CopyValue : r816_5
|
# 816| r816_6(Middle &) = CopyValue : r816_5
|
||||||
# 816| r816_7(Middle &) = Call[operator=] : func:r816_2, this:r816_1, 0:r816_6
|
# 816| r816_7(Middle &) = Call[operator=] : func:r816_2, this:r816_1, 0:r816_6
|
||||||
# 816| mu816_8(unknown) = ^CallSideEffect : ~m?
|
# 816| mu816_8(unknown) = ^CallSideEffect : ~m?
|
||||||
# 816| v816_9(void) = ^BufferReadSideEffect[-1] : &:r816_1, ~m?
|
# 816| v816_9(void) = ^IndirectReadSideEffect[-1] : &:r816_1, ~m?
|
||||||
# 816| v816_10(void) = ^BufferReadSideEffect[0] : &:r816_6, ~m?
|
# 816| v816_10(void) = ^BufferReadSideEffect[0] : &:r816_6, ~m?
|
||||||
# 816| mu816_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r816_1
|
# 816| mu816_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r816_1
|
||||||
# 816| r816_12(glval<Middle>) = CopyValue : r816_7
|
# 816| r816_12(glval<Middle>) = CopyValue : r816_7
|
||||||
@@ -4589,7 +4588,7 @@ ir.cpp:
|
|||||||
# 817| r817_6(Middle &) = CopyValue : r817_5
|
# 817| r817_6(Middle &) = CopyValue : r817_5
|
||||||
# 817| r817_7(Middle &) = Call[operator=] : func:r817_2, this:r817_1, 0:r817_6
|
# 817| r817_7(Middle &) = Call[operator=] : func:r817_2, this:r817_1, 0:r817_6
|
||||||
# 817| mu817_8(unknown) = ^CallSideEffect : ~m?
|
# 817| mu817_8(unknown) = ^CallSideEffect : ~m?
|
||||||
# 817| v817_9(void) = ^BufferReadSideEffect[-1] : &:r817_1, ~m?
|
# 817| v817_9(void) = ^IndirectReadSideEffect[-1] : &:r817_1, ~m?
|
||||||
# 817| v817_10(void) = ^BufferReadSideEffect[0] : &:r817_6, ~m?
|
# 817| v817_10(void) = ^BufferReadSideEffect[0] : &:r817_6, ~m?
|
||||||
# 817| mu817_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r817_1
|
# 817| mu817_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r817_1
|
||||||
# 817| r817_12(glval<Middle>) = CopyValue : r817_7
|
# 817| r817_12(glval<Middle>) = CopyValue : r817_7
|
||||||
@@ -4616,7 +4615,7 @@ ir.cpp:
|
|||||||
# 822| r822_6(Base &) = CopyValue : r822_5
|
# 822| r822_6(Base &) = CopyValue : r822_5
|
||||||
# 822| r822_7(Base &) = Call[operator=] : func:r822_2, this:r822_1, 0:r822_6
|
# 822| r822_7(Base &) = Call[operator=] : func:r822_2, this:r822_1, 0:r822_6
|
||||||
# 822| mu822_8(unknown) = ^CallSideEffect : ~m?
|
# 822| mu822_8(unknown) = ^CallSideEffect : ~m?
|
||||||
# 822| v822_9(void) = ^BufferReadSideEffect[-1] : &:r822_1, ~m?
|
# 822| v822_9(void) = ^IndirectReadSideEffect[-1] : &:r822_1, ~m?
|
||||||
# 822| v822_10(void) = ^BufferReadSideEffect[0] : &:r822_6, ~m?
|
# 822| v822_10(void) = ^BufferReadSideEffect[0] : &:r822_6, ~m?
|
||||||
# 822| mu822_11(Base) = ^IndirectMayWriteSideEffect[-1] : &:r822_1
|
# 822| mu822_11(Base) = ^IndirectMayWriteSideEffect[-1] : &:r822_1
|
||||||
# 822| r822_12(glval<Base>) = CopyValue : r822_7
|
# 822| r822_12(glval<Base>) = CopyValue : r822_7
|
||||||
@@ -4637,7 +4636,7 @@ ir.cpp:
|
|||||||
# 823| r823_15(Base &) = CopyValue : r823_14
|
# 823| r823_15(Base &) = CopyValue : r823_14
|
||||||
# 823| r823_16(Base &) = Call[operator=] : func:r823_2, this:r823_1, 0:r823_15
|
# 823| r823_16(Base &) = Call[operator=] : func:r823_2, this:r823_1, 0:r823_15
|
||||||
# 823| mu823_17(unknown) = ^CallSideEffect : ~m?
|
# 823| mu823_17(unknown) = ^CallSideEffect : ~m?
|
||||||
# 823| v823_18(void) = ^BufferReadSideEffect[-1] : &:r823_1, ~m?
|
# 823| v823_18(void) = ^IndirectReadSideEffect[-1] : &:r823_1, ~m?
|
||||||
# 823| v823_19(void) = ^BufferReadSideEffect[0] : &:r823_15, ~m?
|
# 823| v823_19(void) = ^BufferReadSideEffect[0] : &:r823_15, ~m?
|
||||||
# 823| mu823_20(Base) = ^IndirectMayWriteSideEffect[-1] : &:r823_1
|
# 823| mu823_20(Base) = ^IndirectMayWriteSideEffect[-1] : &:r823_1
|
||||||
# 823| r823_21(glval<Base>) = CopyValue : r823_16
|
# 823| r823_21(glval<Base>) = CopyValue : r823_16
|
||||||
@@ -4658,7 +4657,7 @@ ir.cpp:
|
|||||||
# 824| r824_15(Base &) = CopyValue : r824_14
|
# 824| r824_15(Base &) = CopyValue : r824_14
|
||||||
# 824| r824_16(Base &) = Call[operator=] : func:r824_2, this:r824_1, 0:r824_15
|
# 824| r824_16(Base &) = Call[operator=] : func:r824_2, this:r824_1, 0:r824_15
|
||||||
# 824| mu824_17(unknown) = ^CallSideEffect : ~m?
|
# 824| mu824_17(unknown) = ^CallSideEffect : ~m?
|
||||||
# 824| v824_18(void) = ^BufferReadSideEffect[-1] : &:r824_1, ~m?
|
# 824| v824_18(void) = ^IndirectReadSideEffect[-1] : &:r824_1, ~m?
|
||||||
# 824| v824_19(void) = ^BufferReadSideEffect[0] : &:r824_15, ~m?
|
# 824| v824_19(void) = ^BufferReadSideEffect[0] : &:r824_15, ~m?
|
||||||
# 824| mu824_20(Base) = ^IndirectMayWriteSideEffect[-1] : &:r824_1
|
# 824| mu824_20(Base) = ^IndirectMayWriteSideEffect[-1] : &:r824_1
|
||||||
# 824| r824_21(glval<Base>) = CopyValue : r824_16
|
# 824| r824_21(glval<Base>) = CopyValue : r824_16
|
||||||
@@ -4694,7 +4693,7 @@ ir.cpp:
|
|||||||
# 830| r830_7(Derived &) = CopyValue : r830_6
|
# 830| r830_7(Derived &) = CopyValue : r830_6
|
||||||
# 830| r830_8(Derived &) = Call[operator=] : func:r830_2, this:r830_1, 0:r830_7
|
# 830| r830_8(Derived &) = Call[operator=] : func:r830_2, this:r830_1, 0:r830_7
|
||||||
# 830| mu830_9(unknown) = ^CallSideEffect : ~m?
|
# 830| mu830_9(unknown) = ^CallSideEffect : ~m?
|
||||||
# 830| v830_10(void) = ^BufferReadSideEffect[-1] : &:r830_1, ~m?
|
# 830| v830_10(void) = ^IndirectReadSideEffect[-1] : &:r830_1, ~m?
|
||||||
# 830| v830_11(void) = ^BufferReadSideEffect[0] : &:r830_7, ~m?
|
# 830| v830_11(void) = ^BufferReadSideEffect[0] : &:r830_7, ~m?
|
||||||
# 830| mu830_12(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r830_1
|
# 830| mu830_12(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r830_1
|
||||||
# 830| r830_13(glval<Derived>) = CopyValue : r830_8
|
# 830| r830_13(glval<Derived>) = CopyValue : r830_8
|
||||||
@@ -4707,7 +4706,7 @@ ir.cpp:
|
|||||||
# 831| r831_7(Derived &) = CopyValue : r831_6
|
# 831| r831_7(Derived &) = CopyValue : r831_6
|
||||||
# 831| r831_8(Derived &) = Call[operator=] : func:r831_2, this:r831_1, 0:r831_7
|
# 831| r831_8(Derived &) = Call[operator=] : func:r831_2, this:r831_1, 0:r831_7
|
||||||
# 831| mu831_9(unknown) = ^CallSideEffect : ~m?
|
# 831| mu831_9(unknown) = ^CallSideEffect : ~m?
|
||||||
# 831| v831_10(void) = ^BufferReadSideEffect[-1] : &:r831_1, ~m?
|
# 831| v831_10(void) = ^IndirectReadSideEffect[-1] : &:r831_1, ~m?
|
||||||
# 831| v831_11(void) = ^BufferReadSideEffect[0] : &:r831_7, ~m?
|
# 831| v831_11(void) = ^BufferReadSideEffect[0] : &:r831_7, ~m?
|
||||||
# 831| mu831_12(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r831_1
|
# 831| mu831_12(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r831_1
|
||||||
# 831| r831_13(glval<Derived>) = CopyValue : r831_8
|
# 831| r831_13(glval<Derived>) = CopyValue : r831_8
|
||||||
@@ -5688,7 +5687,7 @@ ir.cpp:
|
|||||||
# 1044| r1044_4(float) = Constant[1.0] :
|
# 1044| r1044_4(float) = Constant[1.0] :
|
||||||
# 1044| r1044_5(char) = Call[operator()] : func:r1044_3, this:r1044_2, 0:r1044_4
|
# 1044| r1044_5(char) = Call[operator()] : func:r1044_3, this:r1044_2, 0:r1044_4
|
||||||
# 1044| mu1044_6(unknown) = ^CallSideEffect : ~m?
|
# 1044| mu1044_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1044| v1044_7(void) = ^BufferReadSideEffect[-1] : &:r1044_2, ~m?
|
# 1044| v1044_7(void) = ^IndirectReadSideEffect[-1] : &:r1044_2, ~m?
|
||||||
# 1045| r1045_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
|
# 1045| r1045_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
|
||||||
# 1045| r1045_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1045:20] :
|
# 1045| r1045_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1045:20] :
|
||||||
# 1045| mu1045_3(decltype([...](...){...})) = Uninitialized[#temp1045:20] : &:r1045_2
|
# 1045| mu1045_3(decltype([...](...){...})) = Uninitialized[#temp1045:20] : &:r1045_2
|
||||||
@@ -5709,7 +5708,7 @@ ir.cpp:
|
|||||||
# 1046| r1046_4(float) = Constant[2.0] :
|
# 1046| r1046_4(float) = Constant[2.0] :
|
||||||
# 1046| r1046_5(char) = Call[operator()] : func:r1046_3, this:r1046_2, 0:r1046_4
|
# 1046| r1046_5(char) = Call[operator()] : func:r1046_3, this:r1046_2, 0:r1046_4
|
||||||
# 1046| mu1046_6(unknown) = ^CallSideEffect : ~m?
|
# 1046| mu1046_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1046| v1046_7(void) = ^BufferReadSideEffect[-1] : &:r1046_2, ~m?
|
# 1046| v1046_7(void) = ^IndirectReadSideEffect[-1] : &:r1046_2, ~m?
|
||||||
# 1047| r1047_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
|
# 1047| r1047_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
|
||||||
# 1047| r1047_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1047:29] :
|
# 1047| r1047_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1047:29] :
|
||||||
# 1047| mu1047_3(decltype([...](...){...})) = Uninitialized[#temp1047:29] : &:r1047_2
|
# 1047| mu1047_3(decltype([...](...){...})) = Uninitialized[#temp1047:29] : &:r1047_2
|
||||||
@@ -5727,7 +5726,7 @@ ir.cpp:
|
|||||||
# 1048| r1048_4(float) = Constant[3.0] :
|
# 1048| r1048_4(float) = Constant[3.0] :
|
||||||
# 1048| r1048_5(char) = Call[operator()] : func:r1048_3, this:r1048_2, 0:r1048_4
|
# 1048| r1048_5(char) = Call[operator()] : func:r1048_3, this:r1048_2, 0:r1048_4
|
||||||
# 1048| mu1048_6(unknown) = ^CallSideEffect : ~m?
|
# 1048| mu1048_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1048| v1048_7(void) = ^BufferReadSideEffect[-1] : &:r1048_2, ~m?
|
# 1048| v1048_7(void) = ^IndirectReadSideEffect[-1] : &:r1048_2, ~m?
|
||||||
# 1049| r1049_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
|
# 1049| r1049_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
|
||||||
# 1049| r1049_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1049:29] :
|
# 1049| r1049_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1049:29] :
|
||||||
# 1049| mu1049_3(decltype([...](...){...})) = Uninitialized[#temp1049:29] : &:r1049_2
|
# 1049| mu1049_3(decltype([...](...){...})) = Uninitialized[#temp1049:29] : &:r1049_2
|
||||||
@@ -5744,7 +5743,7 @@ ir.cpp:
|
|||||||
# 1050| r1050_4(float) = Constant[4.0] :
|
# 1050| r1050_4(float) = Constant[4.0] :
|
||||||
# 1050| r1050_5(char) = Call[operator()] : func:r1050_3, this:r1050_2, 0:r1050_4
|
# 1050| r1050_5(char) = Call[operator()] : func:r1050_3, this:r1050_2, 0:r1050_4
|
||||||
# 1050| mu1050_6(unknown) = ^CallSideEffect : ~m?
|
# 1050| mu1050_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1050| v1050_7(void) = ^BufferReadSideEffect[-1] : &:r1050_2, ~m?
|
# 1050| v1050_7(void) = ^IndirectReadSideEffect[-1] : &:r1050_2, ~m?
|
||||||
# 1051| r1051_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
|
# 1051| r1051_1(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
|
||||||
# 1051| r1051_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1051:31] :
|
# 1051| r1051_2(glval<decltype([...](...){...})>) = VariableAddress[#temp1051:31] :
|
||||||
# 1051| mu1051_3(decltype([...](...){...})) = Uninitialized[#temp1051:31] : &:r1051_2
|
# 1051| mu1051_3(decltype([...](...){...})) = Uninitialized[#temp1051:31] : &:r1051_2
|
||||||
@@ -5766,7 +5765,7 @@ ir.cpp:
|
|||||||
# 1052| r1052_4(float) = Constant[5.0] :
|
# 1052| r1052_4(float) = Constant[5.0] :
|
||||||
# 1052| r1052_5(char) = Call[operator()] : func:r1052_3, this:r1052_2, 0:r1052_4
|
# 1052| r1052_5(char) = Call[operator()] : func:r1052_3, this:r1052_2, 0:r1052_4
|
||||||
# 1052| mu1052_6(unknown) = ^CallSideEffect : ~m?
|
# 1052| mu1052_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1052| v1052_7(void) = ^BufferReadSideEffect[-1] : &:r1052_2, ~m?
|
# 1052| v1052_7(void) = ^IndirectReadSideEffect[-1] : &:r1052_2, ~m?
|
||||||
# 1053| r1053_1(glval<int>) = VariableAddress[r] :
|
# 1053| r1053_1(glval<int>) = VariableAddress[r] :
|
||||||
# 1053| r1053_2(glval<int>) = VariableAddress[x] :
|
# 1053| r1053_2(glval<int>) = VariableAddress[x] :
|
||||||
# 1053| r1053_3(int) = Load[x] : &:r1053_2, ~m?
|
# 1053| r1053_3(int) = Load[x] : &:r1053_2, ~m?
|
||||||
@@ -5804,7 +5803,7 @@ ir.cpp:
|
|||||||
# 1055| r1055_4(float) = Constant[6.0] :
|
# 1055| r1055_4(float) = Constant[6.0] :
|
||||||
# 1055| r1055_5(char) = Call[operator()] : func:r1055_3, this:r1055_2, 0:r1055_4
|
# 1055| r1055_5(char) = Call[operator()] : func:r1055_3, this:r1055_2, 0:r1055_4
|
||||||
# 1055| mu1055_6(unknown) = ^CallSideEffect : ~m?
|
# 1055| mu1055_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1055| v1055_7(void) = ^BufferReadSideEffect[-1] : &:r1055_2, ~m?
|
# 1055| v1055_7(void) = ^IndirectReadSideEffect[-1] : &:r1055_2, ~m?
|
||||||
# 1056| v1056_1(void) = NoOp :
|
# 1056| v1056_1(void) = NoOp :
|
||||||
# 1040| v1040_10(void) = ReturnIndirection[s] : &:r1040_8, ~m?
|
# 1040| v1040_10(void) = ReturnIndirection[s] : &:r1040_8, ~m?
|
||||||
# 1040| v1040_11(void) = ReturnVoid :
|
# 1040| v1040_11(void) = ReturnVoid :
|
||||||
@@ -5869,7 +5868,7 @@ ir.cpp:
|
|||||||
# 1043| r1043_16(glval<unknown>) = FunctionAddress[c_str] :
|
# 1043| r1043_16(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 1043| r1043_17(char *) = Call[c_str] : func:r1043_16, this:r1043_15
|
# 1043| r1043_17(char *) = Call[c_str] : func:r1043_16, this:r1043_15
|
||||||
# 1043| mu1043_18(unknown) = ^CallSideEffect : ~m?
|
# 1043| mu1043_18(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1043| v1043_19(void) = ^BufferReadSideEffect[-1] : &:r1043_15, ~m?
|
# 1043| v1043_19(void) = ^IndirectReadSideEffect[-1] : &:r1043_15, ~m?
|
||||||
# 1043| r1043_20(glval<unknown>) = VariableAddress[#this] :
|
# 1043| r1043_20(glval<unknown>) = VariableAddress[#this] :
|
||||||
# 1043| r1043_21(lambda [] type at line 1043, col. 21 *) = Load[#this] : &:r1043_20, ~m?
|
# 1043| r1043_21(lambda [] type at line 1043, col. 21 *) = Load[#this] : &:r1043_20, ~m?
|
||||||
# 1043| r1043_22(glval<int &>) = FieldAddress[x] : r1043_21
|
# 1043| r1043_22(glval<int &>) = FieldAddress[x] : r1043_21
|
||||||
@@ -5921,7 +5920,7 @@ ir.cpp:
|
|||||||
# 1045| r1045_14(glval<unknown>) = FunctionAddress[c_str] :
|
# 1045| r1045_14(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 1045| r1045_15(char *) = Call[c_str] : func:r1045_14, this:r1045_13
|
# 1045| r1045_15(char *) = Call[c_str] : func:r1045_14, this:r1045_13
|
||||||
# 1045| mu1045_16(unknown) = ^CallSideEffect : ~m?
|
# 1045| mu1045_16(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1045| v1045_17(void) = ^BufferReadSideEffect[-1] : &:r1045_13, ~m?
|
# 1045| v1045_17(void) = ^IndirectReadSideEffect[-1] : &:r1045_13, ~m?
|
||||||
# 1045| r1045_18(glval<unknown>) = VariableAddress[#this] :
|
# 1045| r1045_18(glval<unknown>) = VariableAddress[#this] :
|
||||||
# 1045| r1045_19(lambda [] type at line 1045, col. 21 *) = Load[#this] : &:r1045_18, ~m?
|
# 1045| r1045_19(lambda [] type at line 1045, col. 21 *) = Load[#this] : &:r1045_18, ~m?
|
||||||
# 1045| r1045_20(glval<int>) = FieldAddress[x] : r1045_19
|
# 1045| r1045_20(glval<int>) = FieldAddress[x] : r1045_19
|
||||||
@@ -5955,7 +5954,7 @@ ir.cpp:
|
|||||||
# 1047| r1047_16(glval<unknown>) = FunctionAddress[c_str] :
|
# 1047| r1047_16(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 1047| r1047_17(char *) = Call[c_str] : func:r1047_16, this:r1047_15
|
# 1047| r1047_17(char *) = Call[c_str] : func:r1047_16, this:r1047_15
|
||||||
# 1047| mu1047_18(unknown) = ^CallSideEffect : ~m?
|
# 1047| mu1047_18(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1047| v1047_19(void) = ^BufferReadSideEffect[-1] : &:r1047_15, ~m?
|
# 1047| v1047_19(void) = ^IndirectReadSideEffect[-1] : &:r1047_15, ~m?
|
||||||
# 1047| r1047_20(int) = Constant[0] :
|
# 1047| r1047_20(int) = Constant[0] :
|
||||||
# 1047| r1047_21(glval<char>) = PointerAdd[1] : r1047_17, r1047_20
|
# 1047| r1047_21(glval<char>) = PointerAdd[1] : r1047_17, r1047_20
|
||||||
# 1047| r1047_22(char) = Load[?] : &:r1047_21, ~m?
|
# 1047| r1047_22(char) = Load[?] : &:r1047_21, ~m?
|
||||||
@@ -6003,7 +6002,7 @@ ir.cpp:
|
|||||||
# 1049| r1049_14(glval<unknown>) = FunctionAddress[c_str] :
|
# 1049| r1049_14(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 1049| r1049_15(char *) = Call[c_str] : func:r1049_14, this:r1049_13
|
# 1049| r1049_15(char *) = Call[c_str] : func:r1049_14, this:r1049_13
|
||||||
# 1049| mu1049_16(unknown) = ^CallSideEffect : ~m?
|
# 1049| mu1049_16(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1049| v1049_17(void) = ^BufferReadSideEffect[-1] : &:r1049_13, ~m?
|
# 1049| v1049_17(void) = ^IndirectReadSideEffect[-1] : &:r1049_13, ~m?
|
||||||
# 1049| r1049_18(int) = Constant[0] :
|
# 1049| r1049_18(int) = Constant[0] :
|
||||||
# 1049| r1049_19(glval<char>) = PointerAdd[1] : r1049_15, r1049_18
|
# 1049| r1049_19(glval<char>) = PointerAdd[1] : r1049_15, r1049_18
|
||||||
# 1049| r1049_20(char) = Load[?] : &:r1049_19, ~m?
|
# 1049| r1049_20(char) = Load[?] : &:r1049_19, ~m?
|
||||||
@@ -6034,7 +6033,7 @@ ir.cpp:
|
|||||||
# 1051| r1051_16(glval<unknown>) = FunctionAddress[c_str] :
|
# 1051| r1051_16(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 1051| r1051_17(char *) = Call[c_str] : func:r1051_16, this:r1051_15
|
# 1051| r1051_17(char *) = Call[c_str] : func:r1051_16, this:r1051_15
|
||||||
# 1051| mu1051_18(unknown) = ^CallSideEffect : ~m?
|
# 1051| mu1051_18(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1051| v1051_19(void) = ^BufferReadSideEffect[-1] : &:r1051_15, ~m?
|
# 1051| v1051_19(void) = ^IndirectReadSideEffect[-1] : &:r1051_15, ~m?
|
||||||
# 1051| r1051_20(glval<unknown>) = VariableAddress[#this] :
|
# 1051| r1051_20(glval<unknown>) = VariableAddress[#this] :
|
||||||
# 1051| r1051_21(lambda [] type at line 1051, col. 32 *) = Load[#this] : &:r1051_20, ~m?
|
# 1051| r1051_21(lambda [] type at line 1051, col. 32 *) = Load[#this] : &:r1051_20, ~m?
|
||||||
# 1051| r1051_22(glval<int>) = FieldAddress[x] : r1051_21
|
# 1051| r1051_22(glval<int>) = FieldAddress[x] : r1051_21
|
||||||
@@ -6068,7 +6067,7 @@ ir.cpp:
|
|||||||
# 1054| r1054_16(glval<unknown>) = FunctionAddress[c_str] :
|
# 1054| r1054_16(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 1054| r1054_17(char *) = Call[c_str] : func:r1054_16, this:r1054_15
|
# 1054| r1054_17(char *) = Call[c_str] : func:r1054_16, this:r1054_15
|
||||||
# 1054| mu1054_18(unknown) = ^CallSideEffect : ~m?
|
# 1054| mu1054_18(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1054| v1054_19(void) = ^BufferReadSideEffect[-1] : &:r1054_15, ~m?
|
# 1054| v1054_19(void) = ^IndirectReadSideEffect[-1] : &:r1054_15, ~m?
|
||||||
# 1054| r1054_20(glval<unknown>) = VariableAddress[#this] :
|
# 1054| r1054_20(glval<unknown>) = VariableAddress[#this] :
|
||||||
# 1054| r1054_21(lambda [] type at line 1054, col. 23 *) = Load[#this] : &:r1054_20, ~m?
|
# 1054| r1054_21(lambda [] type at line 1054, col. 23 *) = Load[#this] : &:r1054_20, ~m?
|
||||||
# 1054| r1054_22(glval<int>) = FieldAddress[x] : r1054_21
|
# 1054| r1054_22(glval<int>) = FieldAddress[x] : r1054_21
|
||||||
@@ -6095,37 +6094,37 @@ ir.cpp:
|
|||||||
|
|
||||||
# 1077| void RangeBasedFor(vector<int> const&)
|
# 1077| void RangeBasedFor(vector<int> const&)
|
||||||
# 1077| Block 0
|
# 1077| Block 0
|
||||||
# 1077| v1077_1(void) = EnterFunction :
|
# 1077| v1077_1(void) = EnterFunction :
|
||||||
# 1077| mu1077_2(unknown) = AliasedDefinition :
|
# 1077| mu1077_2(unknown) = AliasedDefinition :
|
||||||
# 1077| mu1077_3(unknown) = InitializeNonLocal :
|
# 1077| mu1077_3(unknown) = InitializeNonLocal :
|
||||||
# 1077| r1077_4(glval<vector<int> &>) = VariableAddress[v] :
|
# 1077| r1077_4(glval<vector<int> &>) = VariableAddress[v] :
|
||||||
# 1077| mu1077_5(vector<int> &) = InitializeParameter[v] : &:r1077_4
|
# 1077| mu1077_5(vector<int> &) = InitializeParameter[v] : &:r1077_4
|
||||||
# 1077| r1077_6(vector<int> &) = Load[v] : &:r1077_4, ~m?
|
# 1077| r1077_6(vector<int> &) = Load[v] : &:r1077_4, ~m?
|
||||||
# 1077| mu1077_7(unknown) = InitializeIndirection[v] : &:r1077_6
|
# 1077| mu1077_7(unknown) = InitializeIndirection[v] : &:r1077_6
|
||||||
# 1078| r1078_1(glval<vector<int> &>) = VariableAddress[(__range)] :
|
# 1078| r1078_1(glval<vector<int> &>) = VariableAddress[(__range)] :
|
||||||
# 1078| r1078_2(glval<vector<int> &>) = VariableAddress[v] :
|
# 1078| r1078_2(glval<vector<int> &>) = VariableAddress[v] :
|
||||||
# 1078| r1078_3(vector<int> &) = Load[v] : &:r1078_2, ~m?
|
# 1078| r1078_3(vector<int> &) = Load[v] : &:r1078_2, ~m?
|
||||||
# 1078| r1078_4(glval<vector<int>>) = CopyValue : r1078_3
|
# 1078| r1078_4(glval<vector<int>>) = CopyValue : r1078_3
|
||||||
# 1078| r1078_5(vector<int> &) = CopyValue : r1078_4
|
# 1078| r1078_5(vector<int> &) = CopyValue : r1078_4
|
||||||
# 1078| mu1078_6(vector<int> &) = Store[(__range)] : &:r1078_1, r1078_5
|
# 1078| mu1078_6(vector<int> &) = Store[(__range)] : &:r1078_1, r1078_5
|
||||||
# 1078| r1078_7(glval<iterator>) = VariableAddress[(__begin)] :
|
# 1078| r1078_7(glval<iterator>) = VariableAddress[(__begin)] :
|
||||||
# 1078| r1078_8(glval<vector<int> &>) = VariableAddress[(__range)] :
|
# 1078| r1078_8(glval<vector<int> &>) = VariableAddress[(__range)] :
|
||||||
# 1078| r1078_9(vector<int> &) = Load[(__range)] : &:r1078_8, ~m?
|
# 1078| r1078_9(vector<int> &) = Load[(__range)] : &:r1078_8, ~m?
|
||||||
#-----| r0_1(glval<vector<int>>) = CopyValue : r1078_9
|
#-----| r0_1(glval<vector<int>>) = CopyValue : r1078_9
|
||||||
# 1078| r1078_10(glval<unknown>) = FunctionAddress[begin] :
|
# 1078| r1078_10(glval<unknown>) = FunctionAddress[begin] :
|
||||||
# 1078| r1078_11(iterator) = Call[begin] : func:r1078_10, this:r0_1
|
# 1078| r1078_11(iterator) = Call[begin] : func:r1078_10, this:r0_1
|
||||||
# 1078| mu1078_12(unknown) = ^CallSideEffect : ~m?
|
# 1078| mu1078_12(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_2(void) = ^BufferReadSideEffect[-1] : &:r0_1, ~m?
|
#-----| v0_2(void) = ^IndirectReadSideEffect[-1] : &:r0_1, ~m?
|
||||||
# 1078| mu1078_13(iterator) = Store[(__begin)] : &:r1078_7, r1078_11
|
# 1078| mu1078_13(iterator) = Store[(__begin)] : &:r1078_7, r1078_11
|
||||||
# 1078| r1078_14(glval<iterator>) = VariableAddress[(__end)] :
|
# 1078| r1078_14(glval<iterator>) = VariableAddress[(__end)] :
|
||||||
# 1078| r1078_15(glval<vector<int> &>) = VariableAddress[(__range)] :
|
# 1078| r1078_15(glval<vector<int> &>) = VariableAddress[(__range)] :
|
||||||
# 1078| r1078_16(vector<int> &) = Load[(__range)] : &:r1078_15, ~m?
|
# 1078| r1078_16(vector<int> &) = Load[(__range)] : &:r1078_15, ~m?
|
||||||
#-----| r0_3(glval<vector<int>>) = CopyValue : r1078_16
|
#-----| r0_3(glval<vector<int>>) = CopyValue : r1078_16
|
||||||
# 1078| r1078_17(glval<unknown>) = FunctionAddress[end] :
|
# 1078| r1078_17(glval<unknown>) = FunctionAddress[end] :
|
||||||
# 1078| r1078_18(iterator) = Call[end] : func:r1078_17, this:r0_3
|
# 1078| r1078_18(iterator) = Call[end] : func:r1078_17, this:r0_3
|
||||||
# 1078| mu1078_19(unknown) = ^CallSideEffect : ~m?
|
# 1078| mu1078_19(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_4(void) = ^BufferReadSideEffect[-1] : &:r0_3, ~m?
|
#-----| v0_4(void) = ^IndirectReadSideEffect[-1] : &:r0_3, ~m?
|
||||||
# 1078| mu1078_20(iterator) = Store[(__end)] : &:r1078_14, r1078_18
|
# 1078| mu1078_20(iterator) = Store[(__end)] : &:r1078_14, r1078_18
|
||||||
#-----| Goto -> Block 1
|
#-----| Goto -> Block 1
|
||||||
|
|
||||||
# 1078| Block 1
|
# 1078| Block 1
|
||||||
@@ -6136,26 +6135,26 @@ ir.cpp:
|
|||||||
# 1078| r1078_24(iterator) = Load[(__end)] : &:r1078_23, ~m?
|
# 1078| r1078_24(iterator) = Load[(__end)] : &:r1078_23, ~m?
|
||||||
# 1078| r1078_25(bool) = Call[operator!=] : func:r1078_22, this:r0_5, 0:r1078_24
|
# 1078| r1078_25(bool) = Call[operator!=] : func:r1078_22, this:r0_5, 0:r1078_24
|
||||||
# 1078| mu1078_26(unknown) = ^CallSideEffect : ~m?
|
# 1078| mu1078_26(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_6(void) = ^BufferReadSideEffect[-1] : &:r0_5, ~m?
|
#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m?
|
||||||
# 1078| v1078_27(void) = ConditionalBranch : r1078_25
|
# 1078| v1078_27(void) = ConditionalBranch : r1078_25
|
||||||
#-----| False -> Block 5
|
#-----| False -> Block 5
|
||||||
#-----| True -> Block 2
|
#-----| True -> Block 2
|
||||||
|
|
||||||
# 1078| Block 2
|
# 1078| Block 2
|
||||||
# 1078| r1078_28(glval<int>) = VariableAddress[e] :
|
# 1078| r1078_28(glval<int>) = VariableAddress[e] :
|
||||||
# 1078| r1078_29(glval<iterator>) = VariableAddress[(__begin)] :
|
# 1078| r1078_29(glval<iterator>) = VariableAddress[(__begin)] :
|
||||||
#-----| r0_7(glval<iterator>) = Convert : r1078_29
|
#-----| r0_7(glval<iterator>) = Convert : r1078_29
|
||||||
# 1078| r1078_30(glval<unknown>) = FunctionAddress[operator*] :
|
# 1078| r1078_30(glval<unknown>) = FunctionAddress[operator*] :
|
||||||
# 1078| r1078_31(int &) = Call[operator*] : func:r1078_30, this:r0_7
|
# 1078| r1078_31(int &) = Call[operator*] : func:r1078_30, this:r0_7
|
||||||
# 1078| mu1078_32(unknown) = ^CallSideEffect : ~m?
|
# 1078| mu1078_32(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_8(void) = ^BufferReadSideEffect[-1] : &:r0_7, ~m?
|
#-----| v0_8(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m?
|
||||||
# 1078| r1078_33(int) = Load[?] : &:r1078_31, ~m?
|
# 1078| r1078_33(int) = Load[?] : &:r1078_31, ~m?
|
||||||
# 1078| mu1078_34(int) = Store[e] : &:r1078_28, r1078_33
|
# 1078| mu1078_34(int) = Store[e] : &:r1078_28, r1078_33
|
||||||
# 1079| r1079_1(glval<int>) = VariableAddress[e] :
|
# 1079| r1079_1(glval<int>) = VariableAddress[e] :
|
||||||
# 1079| r1079_2(int) = Load[e] : &:r1079_1, ~m?
|
# 1079| r1079_2(int) = Load[e] : &:r1079_1, ~m?
|
||||||
# 1079| r1079_3(int) = Constant[0] :
|
# 1079| r1079_3(int) = Constant[0] :
|
||||||
# 1079| r1079_4(bool) = CompareGT : r1079_2, r1079_3
|
# 1079| r1079_4(bool) = CompareGT : r1079_2, r1079_3
|
||||||
# 1079| v1079_5(void) = ConditionalBranch : r1079_4
|
# 1079| v1079_5(void) = ConditionalBranch : r1079_4
|
||||||
#-----| False -> Block 4
|
#-----| False -> Block 4
|
||||||
#-----| True -> Block 3
|
#-----| True -> Block 3
|
||||||
|
|
||||||
@@ -6169,36 +6168,36 @@ ir.cpp:
|
|||||||
# 1078| r1078_37(glval<unknown>) = FunctionAddress[operator++] :
|
# 1078| r1078_37(glval<unknown>) = FunctionAddress[operator++] :
|
||||||
# 1078| r1078_38(iterator &) = Call[operator++] : func:r1078_37, this:r1078_36
|
# 1078| r1078_38(iterator &) = Call[operator++] : func:r1078_37, this:r1078_36
|
||||||
# 1078| mu1078_39(unknown) = ^CallSideEffect : ~m?
|
# 1078| mu1078_39(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1078| v1078_40(void) = ^BufferReadSideEffect[-1] : &:r1078_36, ~m?
|
# 1078| v1078_40(void) = ^IndirectReadSideEffect[-1] : &:r1078_36, ~m?
|
||||||
# 1078| mu1078_41(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1078_36
|
# 1078| mu1078_41(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1078_36
|
||||||
# 1078| r1078_42(glval<iterator>) = CopyValue : r1078_38
|
# 1078| r1078_42(glval<iterator>) = CopyValue : r1078_38
|
||||||
#-----| Goto (back edge) -> Block 1
|
#-----| Goto (back edge) -> Block 1
|
||||||
|
|
||||||
# 1084| Block 5
|
# 1084| Block 5
|
||||||
# 1084| r1084_1(glval<vector<int> &>) = VariableAddress[(__range)] :
|
# 1084| r1084_1(glval<vector<int> &>) = VariableAddress[(__range)] :
|
||||||
# 1084| r1084_2(glval<vector<int> &>) = VariableAddress[v] :
|
# 1084| r1084_2(glval<vector<int> &>) = VariableAddress[v] :
|
||||||
# 1084| r1084_3(vector<int> &) = Load[v] : &:r1084_2, ~m?
|
# 1084| r1084_3(vector<int> &) = Load[v] : &:r1084_2, ~m?
|
||||||
# 1084| r1084_4(glval<vector<int>>) = CopyValue : r1084_3
|
# 1084| r1084_4(glval<vector<int>>) = CopyValue : r1084_3
|
||||||
# 1084| r1084_5(vector<int> &) = CopyValue : r1084_4
|
# 1084| r1084_5(vector<int> &) = CopyValue : r1084_4
|
||||||
# 1084| mu1084_6(vector<int> &) = Store[(__range)] : &:r1084_1, r1084_5
|
# 1084| mu1084_6(vector<int> &) = Store[(__range)] : &:r1084_1, r1084_5
|
||||||
# 1084| r1084_7(glval<iterator>) = VariableAddress[(__begin)] :
|
# 1084| r1084_7(glval<iterator>) = VariableAddress[(__begin)] :
|
||||||
# 1084| r1084_8(glval<vector<int> &>) = VariableAddress[(__range)] :
|
# 1084| r1084_8(glval<vector<int> &>) = VariableAddress[(__range)] :
|
||||||
# 1084| r1084_9(vector<int> &) = Load[(__range)] : &:r1084_8, ~m?
|
# 1084| r1084_9(vector<int> &) = Load[(__range)] : &:r1084_8, ~m?
|
||||||
#-----| r0_9(glval<vector<int>>) = CopyValue : r1084_9
|
#-----| r0_9(glval<vector<int>>) = CopyValue : r1084_9
|
||||||
# 1084| r1084_10(glval<unknown>) = FunctionAddress[begin] :
|
# 1084| r1084_10(glval<unknown>) = FunctionAddress[begin] :
|
||||||
# 1084| r1084_11(iterator) = Call[begin] : func:r1084_10, this:r0_9
|
# 1084| r1084_11(iterator) = Call[begin] : func:r1084_10, this:r0_9
|
||||||
# 1084| mu1084_12(unknown) = ^CallSideEffect : ~m?
|
# 1084| mu1084_12(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_10(void) = ^BufferReadSideEffect[-1] : &:r0_9, ~m?
|
#-----| v0_10(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~m?
|
||||||
# 1084| mu1084_13(iterator) = Store[(__begin)] : &:r1084_7, r1084_11
|
# 1084| mu1084_13(iterator) = Store[(__begin)] : &:r1084_7, r1084_11
|
||||||
# 1084| r1084_14(glval<iterator>) = VariableAddress[(__end)] :
|
# 1084| r1084_14(glval<iterator>) = VariableAddress[(__end)] :
|
||||||
# 1084| r1084_15(glval<vector<int> &>) = VariableAddress[(__range)] :
|
# 1084| r1084_15(glval<vector<int> &>) = VariableAddress[(__range)] :
|
||||||
# 1084| r1084_16(vector<int> &) = Load[(__range)] : &:r1084_15, ~m?
|
# 1084| r1084_16(vector<int> &) = Load[(__range)] : &:r1084_15, ~m?
|
||||||
#-----| r0_11(glval<vector<int>>) = CopyValue : r1084_16
|
#-----| r0_11(glval<vector<int>>) = CopyValue : r1084_16
|
||||||
# 1084| r1084_17(glval<unknown>) = FunctionAddress[end] :
|
# 1084| r1084_17(glval<unknown>) = FunctionAddress[end] :
|
||||||
# 1084| r1084_18(iterator) = Call[end] : func:r1084_17, this:r0_11
|
# 1084| r1084_18(iterator) = Call[end] : func:r1084_17, this:r0_11
|
||||||
# 1084| mu1084_19(unknown) = ^CallSideEffect : ~m?
|
# 1084| mu1084_19(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_12(void) = ^BufferReadSideEffect[-1] : &:r0_11, ~m?
|
#-----| v0_12(void) = ^IndirectReadSideEffect[-1] : &:r0_11, ~m?
|
||||||
# 1084| mu1084_20(iterator) = Store[(__end)] : &:r1084_14, r1084_18
|
# 1084| mu1084_20(iterator) = Store[(__end)] : &:r1084_14, r1084_18
|
||||||
#-----| Goto -> Block 6
|
#-----| Goto -> Block 6
|
||||||
|
|
||||||
# 1084| Block 6
|
# 1084| Block 6
|
||||||
@@ -6209,7 +6208,7 @@ ir.cpp:
|
|||||||
# 1084| r1084_24(iterator) = Load[(__end)] : &:r1084_23, ~m?
|
# 1084| r1084_24(iterator) = Load[(__end)] : &:r1084_23, ~m?
|
||||||
# 1084| r1084_25(bool) = Call[operator!=] : func:r1084_22, this:r0_13, 0:r1084_24
|
# 1084| r1084_25(bool) = Call[operator!=] : func:r1084_22, this:r0_13, 0:r1084_24
|
||||||
# 1084| mu1084_26(unknown) = ^CallSideEffect : ~m?
|
# 1084| mu1084_26(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_13, ~m?
|
#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_13, ~m?
|
||||||
# 1084| v1084_27(void) = ConditionalBranch : r1084_25
|
# 1084| v1084_27(void) = ConditionalBranch : r1084_25
|
||||||
#-----| False -> Block 10
|
#-----| False -> Block 10
|
||||||
#-----| True -> Block 8
|
#-----| True -> Block 8
|
||||||
@@ -6219,29 +6218,29 @@ ir.cpp:
|
|||||||
# 1084| r1084_29(glval<unknown>) = FunctionAddress[operator++] :
|
# 1084| r1084_29(glval<unknown>) = FunctionAddress[operator++] :
|
||||||
# 1084| r1084_30(iterator &) = Call[operator++] : func:r1084_29, this:r1084_28
|
# 1084| r1084_30(iterator &) = Call[operator++] : func:r1084_29, this:r1084_28
|
||||||
# 1084| mu1084_31(unknown) = ^CallSideEffect : ~m?
|
# 1084| mu1084_31(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1084| v1084_32(void) = ^BufferReadSideEffect[-1] : &:r1084_28, ~m?
|
# 1084| v1084_32(void) = ^IndirectReadSideEffect[-1] : &:r1084_28, ~m?
|
||||||
# 1084| mu1084_33(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1084_28
|
# 1084| mu1084_33(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1084_28
|
||||||
# 1084| r1084_34(glval<iterator>) = CopyValue : r1084_30
|
# 1084| r1084_34(glval<iterator>) = CopyValue : r1084_30
|
||||||
#-----| Goto (back edge) -> Block 6
|
#-----| Goto (back edge) -> Block 6
|
||||||
|
|
||||||
# 1084| Block 8
|
# 1084| Block 8
|
||||||
# 1084| r1084_35(glval<int &>) = VariableAddress[e] :
|
# 1084| r1084_35(glval<int &>) = VariableAddress[e] :
|
||||||
# 1084| r1084_36(glval<iterator>) = VariableAddress[(__begin)] :
|
# 1084| r1084_36(glval<iterator>) = VariableAddress[(__begin)] :
|
||||||
#-----| r0_15(glval<iterator>) = Convert : r1084_36
|
#-----| r0_15(glval<iterator>) = Convert : r1084_36
|
||||||
# 1084| r1084_37(glval<unknown>) = FunctionAddress[operator*] :
|
# 1084| r1084_37(glval<unknown>) = FunctionAddress[operator*] :
|
||||||
# 1084| r1084_38(int &) = Call[operator*] : func:r1084_37, this:r0_15
|
# 1084| r1084_38(int &) = Call[operator*] : func:r1084_37, this:r0_15
|
||||||
# 1084| mu1084_39(unknown) = ^CallSideEffect : ~m?
|
# 1084| mu1084_39(unknown) = ^CallSideEffect : ~m?
|
||||||
#-----| v0_16(void) = ^BufferReadSideEffect[-1] : &:r0_15, ~m?
|
#-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~m?
|
||||||
# 1084| r1084_40(glval<int>) = CopyValue : r1084_38
|
# 1084| r1084_40(glval<int>) = CopyValue : r1084_38
|
||||||
# 1084| r1084_41(glval<int>) = Convert : r1084_40
|
# 1084| r1084_41(glval<int>) = Convert : r1084_40
|
||||||
# 1084| r1084_42(int &) = CopyValue : r1084_41
|
# 1084| r1084_42(int &) = CopyValue : r1084_41
|
||||||
# 1084| mu1084_43(int &) = Store[e] : &:r1084_35, r1084_42
|
# 1084| mu1084_43(int &) = Store[e] : &:r1084_35, r1084_42
|
||||||
# 1085| r1085_1(glval<int &>) = VariableAddress[e] :
|
# 1085| r1085_1(glval<int &>) = VariableAddress[e] :
|
||||||
# 1085| r1085_2(int &) = Load[e] : &:r1085_1, ~m?
|
# 1085| r1085_2(int &) = Load[e] : &:r1085_1, ~m?
|
||||||
# 1085| r1085_3(int) = Load[?] : &:r1085_2, ~m?
|
# 1085| r1085_3(int) = Load[?] : &:r1085_2, ~m?
|
||||||
# 1085| r1085_4(int) = Constant[5] :
|
# 1085| r1085_4(int) = Constant[5] :
|
||||||
# 1085| r1085_5(bool) = CompareLT : r1085_3, r1085_4
|
# 1085| r1085_5(bool) = CompareLT : r1085_3, r1085_4
|
||||||
# 1085| v1085_6(void) = ConditionalBranch : r1085_5
|
# 1085| v1085_6(void) = ConditionalBranch : r1085_5
|
||||||
#-----| False -> Block 7
|
#-----| False -> Block 7
|
||||||
#-----| True -> Block 9
|
#-----| True -> Block 9
|
||||||
|
|
||||||
@@ -7525,7 +7524,7 @@ ir.cpp:
|
|||||||
# 1373| r1373_8(glval<unknown>) = FunctionAddress[c_str] :
|
# 1373| r1373_8(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 1373| r1373_9(char *) = Call[c_str] : func:r1373_8, this:r1373_7
|
# 1373| r1373_9(char *) = Call[c_str] : func:r1373_8, this:r1373_7
|
||||||
# 1373| mu1373_10(unknown) = ^CallSideEffect : ~m?
|
# 1373| mu1373_10(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1373| v1373_11(void) = ^BufferReadSideEffect[-1] : &:r1373_7, ~m?
|
# 1373| v1373_11(void) = ^IndirectReadSideEffect[-1] : &:r1373_7, ~m?
|
||||||
# 1374| r1374_1(glval<String>) = VariableAddress[#temp1374:5] :
|
# 1374| r1374_1(glval<String>) = VariableAddress[#temp1374:5] :
|
||||||
# 1374| r1374_2(glval<unknown>) = FunctionAddress[returnValue] :
|
# 1374| r1374_2(glval<unknown>) = FunctionAddress[returnValue] :
|
||||||
# 1374| r1374_3(String) = Call[returnValue] : func:r1374_2
|
# 1374| r1374_3(String) = Call[returnValue] : func:r1374_2
|
||||||
@@ -7535,7 +7534,7 @@ ir.cpp:
|
|||||||
# 1374| r1374_7(glval<unknown>) = FunctionAddress[c_str] :
|
# 1374| r1374_7(glval<unknown>) = FunctionAddress[c_str] :
|
||||||
# 1374| r1374_8(char *) = Call[c_str] : func:r1374_7, this:r1374_6
|
# 1374| r1374_8(char *) = Call[c_str] : func:r1374_7, this:r1374_6
|
||||||
# 1374| mu1374_9(unknown) = ^CallSideEffect : ~m?
|
# 1374| mu1374_9(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1374| v1374_10(void) = ^BufferReadSideEffect[-1] : &:r1374_6, ~m?
|
# 1374| v1374_10(void) = ^IndirectReadSideEffect[-1] : &:r1374_6, ~m?
|
||||||
# 1376| r1376_1(glval<String>) = VariableAddress[#temp1376:5] :
|
# 1376| r1376_1(glval<String>) = VariableAddress[#temp1376:5] :
|
||||||
# 1376| r1376_2(glval<unknown>) = FunctionAddress[defaultConstruct] :
|
# 1376| r1376_2(glval<unknown>) = FunctionAddress[defaultConstruct] :
|
||||||
# 1376| r1376_3(String) = Call[defaultConstruct] : func:r1376_2
|
# 1376| r1376_3(String) = Call[defaultConstruct] : func:r1376_2
|
||||||
@@ -7589,7 +7588,7 @@ ir.cpp:
|
|||||||
# 1385| r1385_4(glval<unknown>) = FunctionAddress[method] :
|
# 1385| r1385_4(glval<unknown>) = FunctionAddress[method] :
|
||||||
# 1385| v1385_5(void) = Call[method] : func:r1385_4, this:r1385_1
|
# 1385| v1385_5(void) = Call[method] : func:r1385_4, this:r1385_1
|
||||||
# 1385| mu1385_6(unknown) = ^CallSideEffect : ~m?
|
# 1385| mu1385_6(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1385| v1385_7(void) = ^BufferReadSideEffect[-1] : &:r1385_1, ~m?
|
# 1385| v1385_7(void) = ^IndirectReadSideEffect[-1] : &:r1385_1, ~m?
|
||||||
# 1385| mu1385_8(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1385_1
|
# 1385| mu1385_8(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1385_1
|
||||||
# 1386| r1386_1(glval<destructor_only>) = VariableAddress[#temp1386:5] :
|
# 1386| r1386_1(glval<destructor_only>) = VariableAddress[#temp1386:5] :
|
||||||
# 1386| r1386_2(glval<unknown>) = FunctionAddress[returnValue] :
|
# 1386| r1386_2(glval<unknown>) = FunctionAddress[returnValue] :
|
||||||
@@ -7599,7 +7598,7 @@ ir.cpp:
|
|||||||
# 1386| r1386_6(glval<unknown>) = FunctionAddress[method] :
|
# 1386| r1386_6(glval<unknown>) = FunctionAddress[method] :
|
||||||
# 1386| v1386_7(void) = Call[method] : func:r1386_6, this:r1386_1
|
# 1386| v1386_7(void) = Call[method] : func:r1386_6, this:r1386_1
|
||||||
# 1386| mu1386_8(unknown) = ^CallSideEffect : ~m?
|
# 1386| mu1386_8(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1386| v1386_9(void) = ^BufferReadSideEffect[-1] : &:r1386_1, ~m?
|
# 1386| v1386_9(void) = ^IndirectReadSideEffect[-1] : &:r1386_1, ~m?
|
||||||
# 1386| mu1386_10(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1386_1
|
# 1386| mu1386_10(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1386_1
|
||||||
# 1388| r1388_1(glval<destructor_only>) = VariableAddress[#temp1388:5] :
|
# 1388| r1388_1(glval<destructor_only>) = VariableAddress[#temp1388:5] :
|
||||||
# 1388| r1388_2(glval<unknown>) = FunctionAddress[defaultConstruct] :
|
# 1388| r1388_2(glval<unknown>) = FunctionAddress[defaultConstruct] :
|
||||||
@@ -7667,7 +7666,7 @@ ir.cpp:
|
|||||||
# 1397| r1397_7(glval<unknown>) = FunctionAddress[method] :
|
# 1397| r1397_7(glval<unknown>) = FunctionAddress[method] :
|
||||||
# 1397| v1397_8(void) = Call[method] : func:r1397_7, this:r1397_1
|
# 1397| v1397_8(void) = Call[method] : func:r1397_7, this:r1397_1
|
||||||
# 1397| mu1397_9(unknown) = ^CallSideEffect : ~m?
|
# 1397| mu1397_9(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1397| v1397_10(void) = ^BufferReadSideEffect[-1] : &:r1397_1, ~m?
|
# 1397| v1397_10(void) = ^IndirectReadSideEffect[-1] : &:r1397_1, ~m?
|
||||||
# 1397| mu1397_11(copy_constructor) = ^IndirectMayWriteSideEffect[-1] : &:r1397_1
|
# 1397| mu1397_11(copy_constructor) = ^IndirectMayWriteSideEffect[-1] : &:r1397_1
|
||||||
# 1398| r1398_1(glval<copy_constructor>) = VariableAddress[#temp1398:5] :
|
# 1398| r1398_1(glval<copy_constructor>) = VariableAddress[#temp1398:5] :
|
||||||
# 1398| r1398_2(glval<unknown>) = FunctionAddress[returnValue] :
|
# 1398| r1398_2(glval<unknown>) = FunctionAddress[returnValue] :
|
||||||
@@ -7677,7 +7676,7 @@ ir.cpp:
|
|||||||
# 1398| r1398_6(glval<unknown>) = FunctionAddress[method] :
|
# 1398| r1398_6(glval<unknown>) = FunctionAddress[method] :
|
||||||
# 1398| v1398_7(void) = Call[method] : func:r1398_6, this:r1398_1
|
# 1398| v1398_7(void) = Call[method] : func:r1398_6, this:r1398_1
|
||||||
# 1398| mu1398_8(unknown) = ^CallSideEffect : ~m?
|
# 1398| mu1398_8(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1398| v1398_9(void) = ^BufferReadSideEffect[-1] : &:r1398_1, ~m?
|
# 1398| v1398_9(void) = ^IndirectReadSideEffect[-1] : &:r1398_1, ~m?
|
||||||
# 1398| mu1398_10(copy_constructor) = ^IndirectMayWriteSideEffect[-1] : &:r1398_1
|
# 1398| mu1398_10(copy_constructor) = ^IndirectMayWriteSideEffect[-1] : &:r1398_1
|
||||||
# 1399| r1399_1(glval<copy_constructor>) = VariableAddress[#temp1399:5] :
|
# 1399| r1399_1(glval<copy_constructor>) = VariableAddress[#temp1399:5] :
|
||||||
# 1399| r1399_2(glval<unknown>) = FunctionAddress[defaultConstruct] :
|
# 1399| r1399_2(glval<unknown>) = FunctionAddress[defaultConstruct] :
|
||||||
@@ -7851,7 +7850,7 @@ ir.cpp:
|
|||||||
# 1447| r1447_9(glval<unknown>) = FunctionAddress[f] :
|
# 1447| r1447_9(glval<unknown>) = FunctionAddress[f] :
|
||||||
# 1447| r1447_10(float) = Call[f] : func:r1447_9, this:r1447_8
|
# 1447| r1447_10(float) = Call[f] : func:r1447_9, this:r1447_8
|
||||||
# 1447| mu1447_11(unknown) = ^CallSideEffect : ~m?
|
# 1447| mu1447_11(unknown) = ^CallSideEffect : ~m?
|
||||||
# 1447| v1447_12(void) = ^BufferReadSideEffect[-1] : &:r1447_8, ~m?
|
# 1447| v1447_12(void) = ^IndirectReadSideEffect[-1] : &:r1447_8, ~m?
|
||||||
# 1447| mu1447_13(float) = Store[f] : &:r1447_1, r1447_10
|
# 1447| mu1447_13(float) = Store[f] : &:r1447_1, r1447_10
|
||||||
# 1448| v1448_1(void) = NoOp :
|
# 1448| v1448_1(void) = NoOp :
|
||||||
# 1443| v1443_4(void) = ReturnVoid :
|
# 1443| v1443_4(void) = ReturnVoid :
|
||||||
|
|||||||
@@ -1059,7 +1059,7 @@ ssa.cpp:
|
|||||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||||
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
||||||
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
||||||
# 241| v241_6(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m240_9
|
# 241| v241_6(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_9
|
||||||
# 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
# 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||||
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
||||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||||
@@ -1067,7 +1067,7 @@ ssa.cpp:
|
|||||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||||
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
||||||
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
||||||
# 242| v242_6(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m241_8
|
# 242| v242_6(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_8
|
||||||
# 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
# 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||||
# 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7
|
# 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7
|
||||||
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
||||||
@@ -1084,7 +1084,7 @@ ssa.cpp:
|
|||||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||||
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
||||||
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
||||||
# 244| v244_6(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m243_9
|
# 244| v244_6(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_9
|
||||||
# 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
# 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||||
# 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7
|
# 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7
|
||||||
# 245| v245_1(void) = NoOp :
|
# 245| v245_1(void) = NoOp :
|
||||||
|
|||||||
@@ -1054,7 +1054,7 @@ ssa.cpp:
|
|||||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||||
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
||||||
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
||||||
# 241| v241_6(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m240_9
|
# 241| v241_6(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_9
|
||||||
# 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
# 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||||
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
||||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||||
@@ -1062,7 +1062,7 @@ ssa.cpp:
|
|||||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||||
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
||||||
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
||||||
# 242| v242_6(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m241_8
|
# 242| v242_6(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_8
|
||||||
# 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
# 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||||
# 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7
|
# 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7
|
||||||
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
||||||
@@ -1079,7 +1079,7 @@ ssa.cpp:
|
|||||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||||
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
||||||
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
||||||
# 244| v244_6(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m243_9
|
# 244| v244_6(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_9
|
||||||
# 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
# 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||||
# 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7
|
# 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7
|
||||||
# 245| v245_1(void) = NoOp :
|
# 245| v245_1(void) = NoOp :
|
||||||
|
|||||||
@@ -983,13 +983,13 @@ ssa.cpp:
|
|||||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||||
# 241| mu241_4(unknown) = ^CallSideEffect : ~m?
|
# 241| mu241_4(unknown) = ^CallSideEffect : ~m?
|
||||||
# 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m?
|
# 241| v241_5(void) = ^IndirectReadSideEffect[-1] : &:r241_1, ~m?
|
||||||
# 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
# 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||||
# 242| mu242_4(unknown) = ^CallSideEffect : ~m?
|
# 242| mu242_4(unknown) = ^CallSideEffect : ~m?
|
||||||
# 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m?
|
# 242| v242_5(void) = ^IndirectReadSideEffect[-1] : &:r242_1, ~m?
|
||||||
# 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
# 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||||
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
||||||
# 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
# 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||||
@@ -1002,7 +1002,7 @@ ssa.cpp:
|
|||||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||||
# 244| mu244_4(unknown) = ^CallSideEffect : ~m?
|
# 244| mu244_4(unknown) = ^CallSideEffect : ~m?
|
||||||
# 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m?
|
# 244| v244_5(void) = ^IndirectReadSideEffect[-1] : &:r244_1, ~m?
|
||||||
# 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
# 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||||
# 245| v245_1(void) = NoOp :
|
# 245| v245_1(void) = NoOp :
|
||||||
# 239| v239_4(void) = ReturnVoid :
|
# 239| v239_4(void) = ReturnVoid :
|
||||||
|
|||||||
@@ -983,13 +983,13 @@ ssa.cpp:
|
|||||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||||
# 241| mu241_4(unknown) = ^CallSideEffect : ~m?
|
# 241| mu241_4(unknown) = ^CallSideEffect : ~m?
|
||||||
# 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m?
|
# 241| v241_5(void) = ^IndirectReadSideEffect[-1] : &:r241_1, ~m?
|
||||||
# 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
# 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||||
# 242| mu242_4(unknown) = ^CallSideEffect : ~m?
|
# 242| mu242_4(unknown) = ^CallSideEffect : ~m?
|
||||||
# 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m?
|
# 242| v242_5(void) = ^IndirectReadSideEffect[-1] : &:r242_1, ~m?
|
||||||
# 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
# 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||||
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
||||||
# 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
# 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||||
@@ -1002,7 +1002,7 @@ ssa.cpp:
|
|||||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||||
# 244| mu244_4(unknown) = ^CallSideEffect : ~m?
|
# 244| mu244_4(unknown) = ^CallSideEffect : ~m?
|
||||||
# 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m?
|
# 244| v244_5(void) = ^IndirectReadSideEffect[-1] : &:r244_1, ~m?
|
||||||
# 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
# 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||||
# 245| v245_1(void) = NoOp :
|
# 245| v245_1(void) = NoOp :
|
||||||
# 239| v239_4(void) = ReturnVoid :
|
# 239| v239_4(void) = ReturnVoid :
|
||||||
|
|||||||
@@ -189,3 +189,30 @@ int *&conversionInFlow() {
|
|||||||
int *&pRef = p; // has conversion in the middle of data flow
|
int *&pRef = p; // has conversion in the middle of data flow
|
||||||
return pRef; // BAD [NOT DETECTED]
|
return pRef; // BAD [NOT DETECTED]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template<typename T>
|
||||||
|
class shared_ptr {
|
||||||
|
public:
|
||||||
|
shared_ptr() noexcept;
|
||||||
|
explicit shared_ptr(T*);
|
||||||
|
shared_ptr(const shared_ptr&) noexcept;
|
||||||
|
template<class U> shared_ptr(const shared_ptr<U>&) noexcept;
|
||||||
|
template<class U> shared_ptr(shared_ptr<U>&&) noexcept;
|
||||||
|
|
||||||
|
shared_ptr<T>& operator=(const shared_ptr<T>&) noexcept;
|
||||||
|
shared_ptr<T>& operator=(shared_ptr<T>&&) noexcept;
|
||||||
|
|
||||||
|
T& operator*() const noexcept;
|
||||||
|
T* operator->() const noexcept;
|
||||||
|
|
||||||
|
T* get() const noexcept;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto make_read_port()
|
||||||
|
{
|
||||||
|
auto port = std::shared_ptr<int>(new int);
|
||||||
|
auto ptr = port.get();
|
||||||
|
return ptr; // GOOD
|
||||||
|
}
|
||||||
@@ -4,5 +4,4 @@
|
|||||||
| test.c:59:3:59:5 | sc6 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:58:9:58:16 | 127 | Extreme value |
|
| test.c:59:3:59:5 | sc6 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:58:9:58:16 | 127 | Extreme value |
|
||||||
| test.c:63:3:63:5 | sc8 | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:62:9:62:16 | - ... | Extreme value |
|
| test.c:63:3:63:5 | sc8 | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:62:9:62:16 | - ... | Extreme value |
|
||||||
| test.c:75:3:75:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value |
|
| test.c:75:3:75:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value |
|
||||||
| test.c:76:3:76:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value |
|
|
||||||
| test.c:124:9:124:9 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:118:17:118:23 | 2147483647 | Extreme value |
|
| test.c:124:9:124:9 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:118:17:118:23 | 2147483647 | Extreme value |
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ void test_negatives() {
|
|||||||
|
|
||||||
sc1 = CHAR_MAX;
|
sc1 = CHAR_MAX;
|
||||||
sc1 += 0; // GOOD [FALSE POSITIVE]
|
sc1 += 0; // GOOD [FALSE POSITIVE]
|
||||||
sc1 += -1; // GOOD [FALSE POSITIVE]
|
sc1 += -1; // GOOD
|
||||||
sc2 = CHAR_MIN;
|
sc2 = CHAR_MIN;
|
||||||
sc2 += -1; // BAD [NOT DETECTED]
|
sc2 += -1; // BAD [NOT DETECTED]
|
||||||
sc3 = CHAR_MIN;
|
sc3 = CHAR_MIN;
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
| test2.cpp:14:11:14:11 | v | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
| test2.cpp:14:11:14:11 | v | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||||
| test2.cpp:14:11:14:11 | v | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
| test2.cpp:14:11:14:11 | v | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||||
| test3.c:15:10:15:10 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value |
|
|
||||||
| test3.c:15:14:15:14 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value |
|
|
||||||
| test3.c:15:18:15:18 | z | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value |
|
|
||||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
| test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||||
| test5.cpp:19:6:19:6 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
| test5.cpp:19:6:19:6 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||||
| test5.cpp:19:6:19:6 | y | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
| test5.cpp:19:6:19:6 | y | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||||
|
|||||||
@@ -976,13 +976,11 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
|
|||||||
TestAutobuilderScript(autobuilder, 0, 9);
|
TestAutobuilderScript(autobuilder, 0, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
private void TestDotnetVersionWindows(Action action, int commandsRun)
|
||||||
public void TestDotnetVersionWindows()
|
|
||||||
{
|
{
|
||||||
actions.RunProcess["cmd.exe /C dotnet --list-sdks"] = 0;
|
actions.RunProcess["cmd.exe /C dotnet --list-sdks"] = 0;
|
||||||
actions.RunProcessOut["cmd.exe /C dotnet --list-sdks"] = "2.1.3 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]";
|
actions.RunProcessOut["cmd.exe /C dotnet --list-sdks"] = "2.1.3 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]";
|
||||||
actions.RunProcess[@"cmd.exe /C powershell -NoProfile -ExecutionPolicy unrestricted -file C:\Project\install-dotnet.ps1 -Version 2.1.3 -InstallDir C:\Project\.dotnet"] = 0;
|
action();
|
||||||
actions.RunProcess[@"cmd.exe /C del C:\Project\install-dotnet.ps1"] = 0;
|
|
||||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0;
|
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0;
|
||||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean C:\Project\test.csproj"] = 0;
|
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean C:\Project\test.csproj"] = 0;
|
||||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore C:\Project\test.csproj"] = 0;
|
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore C:\Project\test.csproj"] = 0;
|
||||||
@@ -1005,7 +1003,28 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
|
|||||||
actions.LoadXml[@"C:\Project\test.csproj"] = xml;
|
actions.LoadXml[@"C:\Project\test.csproj"] = xml;
|
||||||
|
|
||||||
var autobuilder = CreateAutoBuilder(true, dotnetVersion: "2.1.3");
|
var autobuilder = CreateAutoBuilder(true, dotnetVersion: "2.1.3");
|
||||||
TestAutobuilderScript(autobuilder, 0, 7);
|
TestAutobuilderScript(autobuilder, 0, commandsRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestDotnetVersionWindowsWithPwsh()
|
||||||
|
{
|
||||||
|
TestDotnetVersionWindows(() =>
|
||||||
|
{
|
||||||
|
actions.RunProcess[@"cmd.exe /C pwsh -NoProfile -ExecutionPolicy unrestricted -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version 2.1.3 -InstallDir C:\Project\.dotnet"""] = 0;
|
||||||
|
},
|
||||||
|
6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestDotnetVersionWindowsWithoutPwsh()
|
||||||
|
{
|
||||||
|
TestDotnetVersionWindows(() =>
|
||||||
|
{
|
||||||
|
actions.RunProcess[@"cmd.exe /C pwsh -NoProfile -ExecutionPolicy unrestricted -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version 2.1.3 -InstallDir C:\Project\.dotnet"""] = 1;
|
||||||
|
actions.RunProcess[@"cmd.exe /C powershell -NoProfile -ExecutionPolicy unrestricted -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version 2.1.3 -InstallDir C:\Project\.dotnet"""] = 0;
|
||||||
|
},
|
||||||
|
7);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
@@ -179,53 +179,20 @@ namespace Semmle.Autobuild.CSharp
|
|||||||
|
|
||||||
if (builder.Actions.IsWindows())
|
if (builder.Actions.IsWindows())
|
||||||
{
|
{
|
||||||
var psScript = @"param([string]$Version, [string]$InstallDir)
|
|
||||||
|
|
||||||
add-type @""
|
var psCommand = $"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version {version} -InstallDir {path}";
|
||||||
using System.Net;
|
|
||||||
using System.Security.Cryptography.X509Certificates;
|
|
||||||
public class TrustAllCertsPolicy : ICertificatePolicy
|
|
||||||
{
|
|
||||||
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
""@
|
|
||||||
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
|
|
||||||
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
|
|
||||||
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
|
|
||||||
$Script = Invoke-WebRequest -useb 'https://dot.net/v1/dotnet-install.ps1'
|
|
||||||
|
|
||||||
$arguments = @{
|
BuildScript GetInstall(string pwsh) =>
|
||||||
Channel = 'release'
|
new CommandBuilder(builder.Actions).
|
||||||
Version = $Version
|
RunCommand(pwsh).
|
||||||
InstallDir = $InstallDir
|
|
||||||
}
|
|
||||||
|
|
||||||
$ScriptBlock = [scriptblock]::create("".{$($Script)} $(&{$args} @arguments)"")
|
|
||||||
|
|
||||||
Invoke-Command -ScriptBlock $ScriptBlock";
|
|
||||||
var psScriptFile = builder.Actions.PathCombine(builder.Options.RootDirectory, "install-dotnet.ps1");
|
|
||||||
builder.Actions.WriteAllText(psScriptFile, psScript);
|
|
||||||
|
|
||||||
var install = new CommandBuilder(builder.Actions).
|
|
||||||
RunCommand("powershell").
|
|
||||||
Argument("-NoProfile").
|
Argument("-NoProfile").
|
||||||
Argument("-ExecutionPolicy").
|
Argument("-ExecutionPolicy").
|
||||||
Argument("unrestricted").
|
Argument("unrestricted").
|
||||||
Argument("-file").
|
Argument("-Command").
|
||||||
Argument(psScriptFile).
|
Argument("\"" + psCommand + "\"").
|
||||||
Argument("-Version").
|
Script;
|
||||||
Argument(version).
|
|
||||||
Argument("-InstallDir").
|
|
||||||
Argument(path);
|
|
||||||
|
|
||||||
var removeScript = new CommandBuilder(builder.Actions).
|
return GetInstall("pwsh") | GetInstall("powershell");
|
||||||
RunCommand("del").
|
|
||||||
Argument(psScriptFile);
|
|
||||||
|
|
||||||
return install.Script & BuildScript.Try(removeScript.Script);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
2
csharp/change-notes/2021-04-14-customizations.md
Normal file
2
csharp/change-notes/2021-04-14-customizations.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
lgtm,codescanning
|
||||||
|
* A new library, `Customizations.qll`, has been added, which allows for global customizations that affect all queries.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
lgtm,codescanning
|
||||||
|
* `System.Console.Read` methods have been added as data flow sources of local user input.
|
||||||
@@ -193,6 +193,16 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
return Default.CreateGenerated(cx, parent, childIndex, location, parameter.Type.IsReferenceType ? ValueAsString(null) : null);
|
return Default.CreateGenerated(cx, parent, childIndex, location, parameter.Type.IsReferenceType ? ValueAsString(null) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameter.Type.SpecialType == SpecialType.System_Object)
|
||||||
|
{
|
||||||
|
// this can happen in VB.NET
|
||||||
|
cx.ExtractionError($"Extracting default argument value 'object {parameter.Name} = default' instead of 'object {parameter.Name} = {defaultValue}'. The latter is not supported in C#.",
|
||||||
|
null, null, severity: Util.Logging.Severity.Warning);
|
||||||
|
|
||||||
|
// we're generating a default expression:
|
||||||
|
return Default.CreateGenerated(cx, parent, childIndex, location, ValueAsString(null));
|
||||||
|
}
|
||||||
|
|
||||||
// const literal:
|
// const literal:
|
||||||
return Literal.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, location);
|
return Literal.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, location);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,36 +18,6 @@ import csharp
|
|||||||
import Dispose
|
import Dispose
|
||||||
import semmle.code.csharp.frameworks.System
|
import semmle.code.csharp.frameworks.System
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets an exception type that may be thrown during the execution of method `m`.
|
|
||||||
* Assumes any exception may be thrown by library types.
|
|
||||||
*/
|
|
||||||
Class getAThrownException(Method m) {
|
|
||||||
m.fromLibrary() and
|
|
||||||
result = any(SystemExceptionClass sc)
|
|
||||||
or
|
|
||||||
exists(ControlFlowElement cfe |
|
|
||||||
cfe = any(ThrowElement te | result = te.getExpr().getType()) or
|
|
||||||
cfe = any(MethodCall mc | result = getAThrownException(mc.getARuntimeTarget()))
|
|
||||||
|
|
|
||||||
cfe.getEnclosingCallable() = m and
|
|
||||||
not isTriedAgainstException(cfe, result)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if control flow element is tried against throwing an exception of type
|
|
||||||
* `ec`.
|
|
||||||
*/
|
|
||||||
pragma[noinline]
|
|
||||||
predicate isTriedAgainstException(ControlFlowElement cfe, ExceptionClass ec) {
|
|
||||||
(cfe instanceof ThrowElement or cfe instanceof MethodCall) and
|
|
||||||
exists(TryStmt ts |
|
|
||||||
ts.getATriedElement() = cfe and
|
|
||||||
exists(ts.getAnExceptionHandler(ec))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DisposeCall extends MethodCall {
|
private class DisposeCall extends MethodCall {
|
||||||
DisposeCall() { this.getTarget() instanceof DisposeMethod }
|
DisposeCall() { this.getTarget() instanceof DisposeMethod }
|
||||||
}
|
}
|
||||||
@@ -78,8 +48,17 @@ predicate disposeReachableFromDisposableCreation(DisposeCall disposeCall, Expr d
|
|||||||
reachesDisposeCall(disposeCall, DataFlow::exprNode(disposableCreation))
|
reachesDisposeCall(disposeCall, DataFlow::exprNode(disposableCreation))
|
||||||
}
|
}
|
||||||
|
|
||||||
class MethodCallThatMayThrow extends MethodCall {
|
/**
|
||||||
MethodCallThatMayThrow() { exists(getAThrownException(this.getARuntimeTarget())) }
|
* Holds if control flow element is tried against throwing an exception of type
|
||||||
|
* `ec`.
|
||||||
|
*/
|
||||||
|
pragma[noinline]
|
||||||
|
predicate isTriedAgainstException(ControlFlowElement cfe, ExceptionClass ec) {
|
||||||
|
(cfe instanceof ThrowElement or cfe instanceof MethodCall) and
|
||||||
|
exists(TryStmt ts |
|
||||||
|
ts.getATriedElement() = cfe and
|
||||||
|
exists(ts.getAnExceptionHandler(ec))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlowElement getACatchOrFinallyClauseChild() {
|
ControlFlowElement getACatchOrFinallyClauseChild() {
|
||||||
@@ -88,15 +67,71 @@ ControlFlowElement getACatchOrFinallyClauseChild() {
|
|||||||
result = getACatchOrFinallyClauseChild().getAChild()
|
result = getACatchOrFinallyClauseChild().getAChild()
|
||||||
}
|
}
|
||||||
|
|
||||||
from DisposeCall disposeCall, Expr disposableCreation, MethodCallThatMayThrow callThatThrows
|
private predicate candidate(DisposeCall disposeCall, Call call, Expr disposableCreation) {
|
||||||
where
|
|
||||||
disposeReachableFromDisposableCreation(disposeCall, disposableCreation) and
|
disposeReachableFromDisposableCreation(disposeCall, disposableCreation) and
|
||||||
// The dispose call is not, itself, within a dispose method.
|
// The dispose call is not, itself, within a dispose method.
|
||||||
not disposeCall.getEnclosingCallable() instanceof DisposeMethod and
|
not disposeCall.getEnclosingCallable() instanceof DisposeMethod and
|
||||||
// Dispose call not within a finally or catch block
|
// Dispose call not within a finally or catch block
|
||||||
not getACatchOrFinallyClauseChild() = disposeCall and
|
not getACatchOrFinallyClauseChild() = disposeCall and
|
||||||
// At least one method call exists between the allocation and disposal that could throw
|
// At least one method call exists between the allocation and disposal that could throw
|
||||||
disposableCreation.getAReachableElement() = callThatThrows and
|
disposableCreation.getAReachableElement() = call and
|
||||||
callThatThrows.getAReachableElement() = disposeCall
|
call.getAReachableElement() = disposeCall
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RelevantMethod extends Method {
|
||||||
|
RelevantMethod() {
|
||||||
|
exists(Call call |
|
||||||
|
candidate(_, call, _) and
|
||||||
|
this = call.getARuntimeTarget()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(RelevantMethod other | other.calls(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private RelevantMethod callsNoTry() {
|
||||||
|
exists(MethodCall mc |
|
||||||
|
result = mc.getARuntimeTarget() and
|
||||||
|
not isTriedAgainstException(mc, _) and
|
||||||
|
mc.getEnclosingCallable() = this
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private RelevantMethod callsInTry(MethodCall mc) {
|
||||||
|
result = mc.getARuntimeTarget() and
|
||||||
|
isTriedAgainstException(mc, _) and
|
||||||
|
mc.getEnclosingCallable() = this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an exception type that may be thrown during the execution of this method.
|
||||||
|
* Assumes any exception may be thrown by library types.
|
||||||
|
*/
|
||||||
|
Class getAThrownException() {
|
||||||
|
this.fromLibrary() and
|
||||||
|
result instanceof SystemExceptionClass
|
||||||
|
or
|
||||||
|
exists(ControlFlowElement cfe |
|
||||||
|
result = cfe.(ThrowElement).getExpr().getType() and
|
||||||
|
cfe.getEnclosingCallable() = this
|
||||||
|
or
|
||||||
|
result = this.callsInTry(cfe).getAThrownException()
|
||||||
|
|
|
||||||
|
not isTriedAgainstException(cfe, result)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
result = this.callsNoTry().getAThrownException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MethodCallThatMayThrow extends MethodCall {
|
||||||
|
MethodCallThatMayThrow() {
|
||||||
|
exists(this.getARuntimeTarget().(RelevantMethod).getAThrownException())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from DisposeCall disposeCall, Expr disposableCreation, MethodCallThatMayThrow callThatThrows
|
||||||
|
where candidate(disposeCall, callThatThrows, disposableCreation)
|
||||||
select disposeCall, "Dispose missed if exception is thrown by $@.", callThatThrows,
|
select disposeCall, "Dispose missed if exception is thrown by $@.", callThatThrows,
|
||||||
callThatThrows.toString()
|
callThatThrows.toString()
|
||||||
|
|||||||
12
csharp/ql/src/Customizations.qll
Normal file
12
csharp/ql/src/Customizations.qll
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Contains customizations to the standard library.
|
||||||
|
*
|
||||||
|
* This module is imported by `csharp.qll`, so any customizations defined here automatically
|
||||||
|
* apply to all queries.
|
||||||
|
*
|
||||||
|
* Typical examples of customizations include adding new subclasses of abstract classes such as
|
||||||
|
* the `RemoteFlowSource` and `SummarizedCallable` classes associated with the security queries
|
||||||
|
* to model frameworks that are not covered by the standard library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import csharp
|
||||||
11
csharp/ql/src/Metrics/Summaries/LinesOfCode.ql
Normal file
11
csharp/ql/src/Metrics/Summaries/LinesOfCode.ql
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* @id cs/summary/lines-of-code
|
||||||
|
* @name Total lines of code in the database
|
||||||
|
* @description The total number of lines of code across all files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments.
|
||||||
|
* @kind metric
|
||||||
|
* @tags summary
|
||||||
|
*/
|
||||||
|
|
||||||
|
import csharp
|
||||||
|
|
||||||
|
select sum(File f | f.fromSource() | f.getNumberOfLinesOfCode())
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
* The default C# QL library.
|
* The default C# QL library.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import Customizations
|
||||||
import semmle.code.csharp.Attribute
|
import semmle.code.csharp.Attribute
|
||||||
import semmle.code.csharp.Callable
|
import semmle.code.csharp.Callable
|
||||||
import semmle.code.csharp.Comments
|
import semmle.code.csharp.Comments
|
||||||
|
|||||||
@@ -187,5 +187,11 @@ cached
|
|||||||
Declaration definitionOf(Use use, string kind) {
|
Declaration definitionOf(Use use, string kind) {
|
||||||
result = use.getDefinition() and
|
result = use.getDefinition() and
|
||||||
result.fromSource() and
|
result.fromSource() and
|
||||||
kind = use.getUseType()
|
kind = use.getUseType() and
|
||||||
|
// Some entities have many locations. This can arise for files that
|
||||||
|
// are duplicated multiple times in the database at different
|
||||||
|
// locations. Rather than letting the result set explode, we just
|
||||||
|
// exclude results that are "too ambiguous" -- we could also arbitrarily
|
||||||
|
// pick one location later on.
|
||||||
|
strictcount(result.getLocation()) < 10
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ private Element getRealParent(Expr expr) { result = expr.getParent() }
|
|||||||
*/
|
*/
|
||||||
predicate isIRConstant(Expr expr) { exists(expr.getValue()) }
|
predicate isIRConstant(Expr expr) { exists(expr.getValue()) }
|
||||||
|
|
||||||
// Pulled out to work around QL-796
|
// Pulled out for performance. See
|
||||||
|
// https://github.com/github/codeql-coreql-team/issues/1044.
|
||||||
private predicate isOrphan(Expr expr) { not exists(getRealParent(expr)) }
|
private predicate isOrphan(Expr expr) { not exists(getRealParent(expr)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -316,6 +316,15 @@ private module SsaDefReaches {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the reference to `def` at index `i` in basic block `bb` is the
|
||||||
|
* last reference to `v` inside `bb`.
|
||||||
|
*/
|
||||||
|
pragma[noinline]
|
||||||
|
predicate lastSsaRef(Definition def, SourceVariable v, BasicBlock bb, int i) {
|
||||||
|
ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v)
|
||||||
|
}
|
||||||
|
|
||||||
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
||||||
exists(ssaDefRank(def, v, bb, _, _))
|
exists(ssaDefRank(def, v, bb, _, _))
|
||||||
}
|
}
|
||||||
@@ -351,8 +360,7 @@ private module SsaDefReaches {
|
|||||||
*/
|
*/
|
||||||
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
||||||
varBlockReaches(def, bb1, bb2) and
|
varBlockReaches(def, bb1, bb2) and
|
||||||
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and
|
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1
|
||||||
variableRead(bb2, i2, _, _)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,15 +442,22 @@ predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2
|
|||||||
bb2 = bb1
|
bb2 = bb1
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(SourceVariable v | ssaDefRank(def, v, bb1, i1, _) = maxSsaRefRank(bb1, v)) and
|
lastSsaRef(def, _, bb1, i1) and
|
||||||
defAdjacentRead(def, bb1, bb2, i2)
|
defAdjacentRead(def, bb1, bb2, i2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate adjacentDefRead(
|
||||||
|
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2, SourceVariable v
|
||||||
|
) {
|
||||||
|
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
||||||
|
v = def.getSourceVariable()
|
||||||
|
}
|
||||||
|
|
||||||
private predicate adjacentDefReachesRead(
|
private predicate adjacentDefReachesRead(
|
||||||
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
||||||
) {
|
) {
|
||||||
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
exists(SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) |
|
||||||
exists(SourceVariable v | v = def.getSourceVariable() |
|
|
||||||
ssaRef(bb1, i1, v, SsaDef())
|
ssaRef(bb1, i1, v, SsaDef())
|
||||||
or
|
or
|
||||||
variableRead(bb1, i1, v, true)
|
variableRead(bb1, i1, v, true)
|
||||||
@@ -475,17 +490,19 @@ predicate adjacentDefNoUncertainReads(Definition def, BasicBlock bb1, int i1, Ba
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
||||||
exists(int rnk, SourceVariable v, int j | rnk = ssaDefRank(def, v, bb, i, _) |
|
exists(SourceVariable v |
|
||||||
// Next reference to `v` inside `bb` is a write
|
// Next reference to `v` inside `bb` is a write
|
||||||
next.definesAt(v, bb, j) and
|
exists(int rnk, int j |
|
||||||
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
rnk = ssaDefRank(def, v, bb, i, _) and
|
||||||
|
next.definesAt(v, bb, j) and
|
||||||
|
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
||||||
|
)
|
||||||
or
|
or
|
||||||
// Can reach a write using one or more steps
|
// Can reach a write using one or more steps
|
||||||
rnk = maxSsaRefRank(bb, v) and
|
lastSsaRef(def, v, bb, i) and
|
||||||
exists(BasicBlock bb2 |
|
exists(BasicBlock bb2 |
|
||||||
varBlockReaches(def, bb, bb2) and
|
varBlockReaches(def, bb, bb2) and
|
||||||
next.definesAt(v, bb2, j) and
|
1 = ssaDefRank(next, v, bb2, _, SsaDef())
|
||||||
1 = ssaRefRank(bb2, j, v, SsaDef())
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -539,7 +556,8 @@ pragma[nomagic]
|
|||||||
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
||||||
lastRefRedef(def, bb, i, _)
|
lastRefRedef(def, bb, i, _)
|
||||||
or
|
or
|
||||||
exists(SourceVariable v | ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) |
|
lastSsaRef(def, _, bb, i) and
|
||||||
|
(
|
||||||
// Can reach exit directly
|
// Can reach exit directly
|
||||||
bb instanceof ExitBasicBlock
|
bb instanceof ExitBasicBlock
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ module Stages {
|
|||||||
|
|
||||||
cached
|
cached
|
||||||
module DataFlowStage {
|
module DataFlowStage {
|
||||||
|
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
|
||||||
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
|
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
|
||||||
private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon
|
private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon
|
||||||
private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate
|
private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate
|
||||||
@@ -78,6 +79,8 @@ module Stages {
|
|||||||
or
|
or
|
||||||
exists(CallContext cc)
|
exists(CallContext cc)
|
||||||
or
|
or
|
||||||
|
exists(any(DataFlowCall c).getEnclosingCallable())
|
||||||
|
or
|
||||||
forceCachingInSameStageRev()
|
forceCachingInSameStageRev()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ class File extends Container, @file {
|
|||||||
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
|
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
|
||||||
|
|
||||||
/** Holds if this file contains source code. */
|
/** Holds if this file contains source code. */
|
||||||
predicate fromSource() { this.getNumberOfLinesOfCode() > 0 }
|
predicate fromSource() { files(this, _, _, "cs", _) }
|
||||||
|
|
||||||
/** Holds if this file is a library. */
|
/** Holds if this file is a library. */
|
||||||
predicate fromLibrary() {
|
predicate fromLibrary() {
|
||||||
|
|||||||
@@ -316,6 +316,15 @@ private module SsaDefReaches {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the reference to `def` at index `i` in basic block `bb` is the
|
||||||
|
* last reference to `v` inside `bb`.
|
||||||
|
*/
|
||||||
|
pragma[noinline]
|
||||||
|
predicate lastSsaRef(Definition def, SourceVariable v, BasicBlock bb, int i) {
|
||||||
|
ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v)
|
||||||
|
}
|
||||||
|
|
||||||
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
||||||
exists(ssaDefRank(def, v, bb, _, _))
|
exists(ssaDefRank(def, v, bb, _, _))
|
||||||
}
|
}
|
||||||
@@ -351,8 +360,7 @@ private module SsaDefReaches {
|
|||||||
*/
|
*/
|
||||||
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
||||||
varBlockReaches(def, bb1, bb2) and
|
varBlockReaches(def, bb1, bb2) and
|
||||||
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and
|
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1
|
||||||
variableRead(bb2, i2, _, _)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,15 +442,22 @@ predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2
|
|||||||
bb2 = bb1
|
bb2 = bb1
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(SourceVariable v | ssaDefRank(def, v, bb1, i1, _) = maxSsaRefRank(bb1, v)) and
|
lastSsaRef(def, _, bb1, i1) and
|
||||||
defAdjacentRead(def, bb1, bb2, i2)
|
defAdjacentRead(def, bb1, bb2, i2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate adjacentDefRead(
|
||||||
|
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2, SourceVariable v
|
||||||
|
) {
|
||||||
|
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
||||||
|
v = def.getSourceVariable()
|
||||||
|
}
|
||||||
|
|
||||||
private predicate adjacentDefReachesRead(
|
private predicate adjacentDefReachesRead(
|
||||||
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
||||||
) {
|
) {
|
||||||
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
exists(SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) |
|
||||||
exists(SourceVariable v | v = def.getSourceVariable() |
|
|
||||||
ssaRef(bb1, i1, v, SsaDef())
|
ssaRef(bb1, i1, v, SsaDef())
|
||||||
or
|
or
|
||||||
variableRead(bb1, i1, v, true)
|
variableRead(bb1, i1, v, true)
|
||||||
@@ -475,17 +490,19 @@ predicate adjacentDefNoUncertainReads(Definition def, BasicBlock bb1, int i1, Ba
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
||||||
exists(int rnk, SourceVariable v, int j | rnk = ssaDefRank(def, v, bb, i, _) |
|
exists(SourceVariable v |
|
||||||
// Next reference to `v` inside `bb` is a write
|
// Next reference to `v` inside `bb` is a write
|
||||||
next.definesAt(v, bb, j) and
|
exists(int rnk, int j |
|
||||||
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
rnk = ssaDefRank(def, v, bb, i, _) and
|
||||||
|
next.definesAt(v, bb, j) and
|
||||||
|
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
||||||
|
)
|
||||||
or
|
or
|
||||||
// Can reach a write using one or more steps
|
// Can reach a write using one or more steps
|
||||||
rnk = maxSsaRefRank(bb, v) and
|
lastSsaRef(def, v, bb, i) and
|
||||||
exists(BasicBlock bb2 |
|
exists(BasicBlock bb2 |
|
||||||
varBlockReaches(def, bb, bb2) and
|
varBlockReaches(def, bb, bb2) and
|
||||||
next.definesAt(v, bb2, j) and
|
1 = ssaDefRank(next, v, bb2, _, SsaDef())
|
||||||
1 = ssaRefRank(bb2, j, v, SsaDef())
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -539,7 +556,8 @@ pragma[nomagic]
|
|||||||
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
||||||
lastRefRedef(def, bb, i, _)
|
lastRefRedef(def, bb, i, _)
|
||||||
or
|
or
|
||||||
exists(SourceVariable v | ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) |
|
lastSsaRef(def, _, bb, i) and
|
||||||
|
(
|
||||||
// Can reach exit directly
|
// Can reach exit directly
|
||||||
bb instanceof ExitBasicBlock
|
bb instanceof ExitBasicBlock
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ private import dotnet
|
|||||||
private import DataFlowPublic
|
private import DataFlowPublic
|
||||||
private import DataFlowPrivate
|
private import DataFlowPrivate
|
||||||
private import FlowSummaryImpl as FlowSummaryImpl
|
private import FlowSummaryImpl as FlowSummaryImpl
|
||||||
|
private import semmle.code.csharp.Caching
|
||||||
private import semmle.code.csharp.dataflow.FlowSummary
|
private import semmle.code.csharp.dataflow.FlowSummary
|
||||||
private import semmle.code.csharp.dispatch.Dispatch
|
private import semmle.code.csharp.dispatch.Dispatch
|
||||||
private import semmle.code.csharp.frameworks.system.Collections
|
private import semmle.code.csharp.frameworks.system.Collections
|
||||||
@@ -69,8 +70,6 @@ private predicate transitiveCapturedCallTarget(ControlFlow::Nodes::ElementNode c
|
|||||||
|
|
||||||
cached
|
cached
|
||||||
private module Cached {
|
private module Cached {
|
||||||
private import semmle.code.csharp.Caching
|
|
||||||
|
|
||||||
cached
|
cached
|
||||||
newtype TReturnKind =
|
newtype TReturnKind =
|
||||||
TNormalReturnKind() { Stages::DataFlowStage::forceCachingInSameStage() } or
|
TNormalReturnKind() { Stages::DataFlowStage::forceCachingInSameStage() } or
|
||||||
@@ -247,6 +246,7 @@ abstract class DataFlowCall extends TDataFlowCall {
|
|||||||
abstract DataFlow::Node getNode();
|
abstract DataFlow::Node getNode();
|
||||||
|
|
||||||
/** Gets the enclosing callable of this call. */
|
/** Gets the enclosing callable of this call. */
|
||||||
|
cached
|
||||||
abstract DataFlowCallable getEnclosingCallable();
|
abstract DataFlowCallable getEnclosingCallable();
|
||||||
|
|
||||||
/** Gets the underlying expression, if any. */
|
/** Gets the underlying expression, if any. */
|
||||||
@@ -280,7 +280,10 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
|
|||||||
|
|
||||||
override DataFlow::ExprNode getNode() { result.getControlFlowNode() = cfn }
|
override DataFlow::ExprNode getNode() { result.getControlFlowNode() = cfn }
|
||||||
|
|
||||||
override DataFlowCallable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
|
override DataFlowCallable getEnclosingCallable() {
|
||||||
|
Stages::DataFlowStage::forceCachingInSameStage() and
|
||||||
|
result = cfn.getEnclosingCallable()
|
||||||
|
}
|
||||||
|
|
||||||
override string toString() { result = cfn.toString() }
|
override string toString() { result = cfn.toString() }
|
||||||
|
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -2133,11 +2133,8 @@ private module Stage4 {
|
|||||||
|
|
||||||
bindingset[node, cc, config]
|
bindingset[node, cc, config]
|
||||||
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
|
||||||
exists(Cc cc0 |
|
localFlowEntry(node, config) and
|
||||||
cc = pragma[only_bind_into](cc0) and
|
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
|
||||||
localFlowEntry(node, config) and
|
|
||||||
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localStep(
|
private predicate localStep(
|
||||||
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
|||||||
conf = mid.getConfiguration() and
|
conf = mid.getConfiguration() and
|
||||||
cc = mid.getCallContext() and
|
cc = mid.getCallContext() and
|
||||||
sc = mid.getSummaryCtx() and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
|
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
|
||||||
ap0 = mid.getAp()
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
|
|||||||
@@ -21,9 +21,11 @@ private import semmle.code.csharp.frameworks.system.threading.Tasks
|
|||||||
|
|
||||||
abstract class NodeImpl extends Node {
|
abstract class NodeImpl extends Node {
|
||||||
/** Do not call: use `getEnclosingCallable()` instead. */
|
/** Do not call: use `getEnclosingCallable()` instead. */
|
||||||
|
cached
|
||||||
abstract DataFlowCallable getEnclosingCallableImpl();
|
abstract DataFlowCallable getEnclosingCallableImpl();
|
||||||
|
|
||||||
/** Do not call: use `getType()` instead. */
|
/** Do not call: use `getType()` instead. */
|
||||||
|
cached
|
||||||
abstract DotNet::Type getTypeImpl();
|
abstract DotNet::Type getTypeImpl();
|
||||||
|
|
||||||
/** Gets the type of this node used for type pruning. */
|
/** Gets the type of this node used for type pruning. */
|
||||||
@@ -39,27 +41,39 @@ abstract class NodeImpl extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Do not call: use `getControlFlowNode()` instead. */
|
/** Do not call: use `getControlFlowNode()` instead. */
|
||||||
|
cached
|
||||||
abstract ControlFlow::Node getControlFlowNodeImpl();
|
abstract ControlFlow::Node getControlFlowNodeImpl();
|
||||||
|
|
||||||
/** Do not call: use `getLocation()` instead. */
|
/** Do not call: use `getLocation()` instead. */
|
||||||
|
cached
|
||||||
abstract Location getLocationImpl();
|
abstract Location getLocationImpl();
|
||||||
|
|
||||||
/** Do not call: use `toString()` instead. */
|
/** Do not call: use `toString()` instead. */
|
||||||
|
cached
|
||||||
abstract string toStringImpl();
|
abstract string toStringImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ExprNodeImpl extends ExprNode, NodeImpl {
|
private class ExprNodeImpl extends ExprNode, NodeImpl {
|
||||||
override DataFlowCallable getEnclosingCallableImpl() {
|
override DataFlowCallable getEnclosingCallableImpl() {
|
||||||
|
Stages::DataFlowStage::forceCachingInSameStage() and
|
||||||
result = this.getExpr().getEnclosingCallable()
|
result = this.getExpr().getEnclosingCallable()
|
||||||
}
|
}
|
||||||
|
|
||||||
override DotNet::Type getTypeImpl() { result = this.getExpr().getType() }
|
override DotNet::Type getTypeImpl() {
|
||||||
|
Stages::DataFlowStage::forceCachingInSameStage() and
|
||||||
|
result = this.getExpr().getType()
|
||||||
|
}
|
||||||
|
|
||||||
override ControlFlow::Nodes::ElementNode getControlFlowNodeImpl() { this = TExprNode(result) }
|
override ControlFlow::Nodes::ElementNode getControlFlowNodeImpl() {
|
||||||
|
Stages::DataFlowStage::forceCachingInSameStage() and this = TExprNode(result)
|
||||||
|
}
|
||||||
|
|
||||||
override Location getLocationImpl() { result = this.getExpr().getLocation() }
|
override Location getLocationImpl() {
|
||||||
|
Stages::DataFlowStage::forceCachingInSameStage() and result = this.getExpr().getLocation()
|
||||||
|
}
|
||||||
|
|
||||||
override string toStringImpl() {
|
override string toStringImpl() {
|
||||||
|
Stages::DataFlowStage::forceCachingInSameStage() and
|
||||||
result = this.getControlFlowNode().toString()
|
result = this.getControlFlowNode().toString()
|
||||||
or
|
or
|
||||||
exists(CIL::Expr e |
|
exists(CIL::Expr e |
|
||||||
@@ -967,6 +981,16 @@ private module Cached {
|
|||||||
or
|
or
|
||||||
n.asExpr() = any(WithExpr we).getInitializer()
|
n.asExpr() = any(WithExpr we).getInitializer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
|
predicate parameterNode(Node n, DataFlowCallable c, int i) {
|
||||||
|
n.(ParameterNodeImpl).isParameterOf(c, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
|
predicate argumentNode(Node n, DataFlowCall call, int pos) {
|
||||||
|
n.(ArgumentNodeImpl).argumentOf(call, pos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import Cached
|
import Cached
|
||||||
@@ -992,8 +1016,6 @@ class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class ParameterNodeImpl extends NodeImpl {
|
abstract class ParameterNodeImpl extends NodeImpl {
|
||||||
abstract DotNet::Parameter getParameter();
|
|
||||||
|
|
||||||
abstract predicate isParameterOf(DataFlowCallable c, int i);
|
abstract predicate isParameterOf(DataFlowCallable c, int i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1010,11 +1032,9 @@ private module ParameterNodes {
|
|||||||
/** Gets the SSA definition corresponding to this parameter, if any. */
|
/** Gets the SSA definition corresponding to this parameter, if any. */
|
||||||
Ssa::ExplicitDefinition getSsaDefinition() {
|
Ssa::ExplicitDefinition getSsaDefinition() {
|
||||||
result.getADefinition().(AssignableDefinitions::ImplicitParameterDefinition).getParameter() =
|
result.getADefinition().(AssignableDefinitions::ImplicitParameterDefinition).getParameter() =
|
||||||
this.getParameter()
|
parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
override DotNet::Parameter getParameter() { result = parameter }
|
|
||||||
|
|
||||||
override predicate isParameterOf(DataFlowCallable c, int i) { c.getParameter(i) = parameter }
|
override predicate isParameterOf(DataFlowCallable c, int i) { c.getParameter(i) = parameter }
|
||||||
|
|
||||||
override DataFlowCallable getEnclosingCallableImpl() { result = parameter.getCallable() }
|
override DataFlowCallable getEnclosingCallableImpl() { result = parameter.getCallable() }
|
||||||
@@ -1037,8 +1057,6 @@ private module ParameterNodes {
|
|||||||
/** Gets the callable containing this implicit instance parameter. */
|
/** Gets the callable containing this implicit instance parameter. */
|
||||||
Callable getCallable() { result = callable }
|
Callable getCallable() { result = callable }
|
||||||
|
|
||||||
override DotNet::Parameter getParameter() { none() }
|
|
||||||
|
|
||||||
override predicate isParameterOf(DataFlowCallable c, int pos) { callable = c and pos = -1 }
|
override predicate isParameterOf(DataFlowCallable c, int pos) { callable = c and pos = -1 }
|
||||||
|
|
||||||
override DataFlowCallable getEnclosingCallableImpl() { result = callable }
|
override DataFlowCallable getEnclosingCallableImpl() { result = callable }
|
||||||
@@ -1113,8 +1131,6 @@ private module ParameterNodes {
|
|||||||
/** Gets the captured variable that this implicit parameter models. */
|
/** Gets the captured variable that this implicit parameter models. */
|
||||||
LocalScopeVariable getVariable() { result = def.getVariable() }
|
LocalScopeVariable getVariable() { result = def.getVariable() }
|
||||||
|
|
||||||
override DotNet::Parameter getParameter() { none() }
|
|
||||||
|
|
||||||
override predicate isParameterOf(DataFlowCallable c, int i) {
|
override predicate isParameterOf(DataFlowCallable c, int i) {
|
||||||
i = getParameterPosition(def) and
|
i = getParameterPosition(def) and
|
||||||
c = this.getEnclosingCallable()
|
c = this.getEnclosingCallable()
|
||||||
@@ -1125,13 +1141,15 @@ private module ParameterNodes {
|
|||||||
import ParameterNodes
|
import ParameterNodes
|
||||||
|
|
||||||
/** A data-flow node that represents a call argument. */
|
/** A data-flow node that represents a call argument. */
|
||||||
abstract class ArgumentNode extends Node {
|
class ArgumentNode extends Node {
|
||||||
/** Holds if this argument occurs at the given position in the given call. */
|
ArgumentNode() { argumentNode(this, _, _) }
|
||||||
cached
|
|
||||||
abstract predicate argumentOf(DataFlowCall call, int pos);
|
|
||||||
|
|
||||||
/** Gets the call in which this node is an argument. */
|
/** Holds if this argument occurs at the given position in the given call. */
|
||||||
final DataFlowCall getCall() { this.argumentOf(result, _) }
|
final predicate argumentOf(DataFlowCall call, int pos) { argumentNode(this, call, pos) }
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract private class ArgumentNodeImpl extends Node {
|
||||||
|
abstract predicate argumentOf(DataFlowCall call, int pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private module ArgumentNodes {
|
private module ArgumentNodes {
|
||||||
@@ -1149,7 +1167,7 @@ private module ArgumentNodes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A data-flow node that represents an explicit call argument. */
|
/** A data-flow node that represents an explicit call argument. */
|
||||||
class ExplicitArgumentNode extends ArgumentNode {
|
class ExplicitArgumentNode extends ArgumentNodeImpl {
|
||||||
ExplicitArgumentNode() {
|
ExplicitArgumentNode() {
|
||||||
this.asExpr() instanceof Argument
|
this.asExpr() instanceof Argument
|
||||||
or
|
or
|
||||||
@@ -1157,7 +1175,6 @@ private module ArgumentNodes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override predicate argumentOf(DataFlowCall call, int pos) {
|
override predicate argumentOf(DataFlowCall call, int pos) {
|
||||||
Stages::DataFlowStage::forceCachingInSameStage() and
|
|
||||||
exists(ArgumentConfiguration x, Expr c, Argument arg |
|
exists(ArgumentConfiguration x, Expr c, Argument arg |
|
||||||
arg = this.asExpr() and
|
arg = this.asExpr() and
|
||||||
c = call.getExpr() and
|
c = call.getExpr() and
|
||||||
@@ -1189,7 +1206,8 @@ private module ArgumentNodes {
|
|||||||
* } }
|
* } }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class ImplicitCapturedArgumentNode extends ArgumentNode, NodeImpl, TImplicitCapturedArgumentNode {
|
class ImplicitCapturedArgumentNode extends ArgumentNodeImpl, NodeImpl,
|
||||||
|
TImplicitCapturedArgumentNode {
|
||||||
private LocalScopeVariable v;
|
private LocalScopeVariable v;
|
||||||
private ControlFlow::Nodes::ElementNode cfn;
|
private ControlFlow::Nodes::ElementNode cfn;
|
||||||
|
|
||||||
@@ -1231,7 +1249,7 @@ private module ArgumentNodes {
|
|||||||
* A node that corresponds to the value of an object creation (`new C()`) before
|
* A node that corresponds to the value of an object creation (`new C()`) before
|
||||||
* the constructor has run.
|
* the constructor has run.
|
||||||
*/
|
*/
|
||||||
class MallocNode extends ArgumentNode, NodeImpl, TMallocNode {
|
class MallocNode extends ArgumentNodeImpl, NodeImpl, TMallocNode {
|
||||||
private ControlFlow::Nodes::ElementNode cfn;
|
private ControlFlow::Nodes::ElementNode cfn;
|
||||||
|
|
||||||
MallocNode() { this = TMallocNode(cfn) }
|
MallocNode() { this = TMallocNode(cfn) }
|
||||||
@@ -1266,7 +1284,7 @@ private module ArgumentNodes {
|
|||||||
* and that argument is itself a compatible array, for example
|
* and that argument is itself a compatible array, for example
|
||||||
* `Foo(new[] { "a", "b", "c" })`.
|
* `Foo(new[] { "a", "b", "c" })`.
|
||||||
*/
|
*/
|
||||||
class ParamsArgumentNode extends ArgumentNode, NodeImpl, TParamsArgumentNode {
|
class ParamsArgumentNode extends ArgumentNodeImpl, NodeImpl, TParamsArgumentNode {
|
||||||
private ControlFlow::Node callCfn;
|
private ControlFlow::Node callCfn;
|
||||||
|
|
||||||
ParamsArgumentNode() { this = TParamsArgumentNode(callCfn) }
|
ParamsArgumentNode() { this = TParamsArgumentNode(callCfn) }
|
||||||
@@ -1291,7 +1309,7 @@ private module ArgumentNodes {
|
|||||||
override string toStringImpl() { result = "[implicit array creation] " + callCfn }
|
override string toStringImpl() { result = "[implicit array creation] " + callCfn }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SummaryArgumentNode extends SummaryNode, ArgumentNode {
|
private class SummaryArgumentNode extends SummaryNode, ArgumentNodeImpl {
|
||||||
private DataFlowCall c;
|
private DataFlowCall c;
|
||||||
private int i;
|
private int i;
|
||||||
|
|
||||||
@@ -1324,10 +1342,7 @@ private module ReturnNodes {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override NormalReturnKind getKind() {
|
override NormalReturnKind getKind() { exists(result) }
|
||||||
any(DotNet::Callable c).canReturn(this.getExpr()) and
|
|
||||||
exists(result)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1744,7 +1759,10 @@ class DataFlowType extends Gvn::GvnType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the type of `n` used for type pruning. */
|
/** Gets the type of `n` used for type pruning. */
|
||||||
DataFlowType getNodeType(NodeImpl n) { result = n.getDataFlowType() }
|
pragma[inline]
|
||||||
|
Gvn::GvnType getNodeType(NodeImpl n) {
|
||||||
|
pragma[only_bind_into](result) = pragma[only_bind_out](n).getDataFlowType()
|
||||||
|
}
|
||||||
|
|
||||||
/** Gets a string representation of a `DataFlowType`. */
|
/** Gets a string representation of a `DataFlowType`. */
|
||||||
string ppReprType(DataFlowType t) { result = t.toString() }
|
string ppReprType(DataFlowType t) { result = t.toString() }
|
||||||
@@ -1819,7 +1837,8 @@ private module PostUpdateNodes {
|
|||||||
* Such a node acts as both a post-update node for the `MallocNode`, as well as
|
* Such a node acts as both a post-update node for the `MallocNode`, as well as
|
||||||
* a pre-update node for the `ObjectCreationNode`.
|
* a pre-update node for the `ObjectCreationNode`.
|
||||||
*/
|
*/
|
||||||
class ObjectInitializerNode extends PostUpdateNode, NodeImpl, ArgumentNode, TObjectInitializerNode {
|
class ObjectInitializerNode extends PostUpdateNode, NodeImpl, ArgumentNodeImpl,
|
||||||
|
TObjectInitializerNode {
|
||||||
private ObjectCreation oc;
|
private ObjectCreation oc;
|
||||||
private ControlFlow::Nodes::ElementNode cfn;
|
private ControlFlow::Nodes::ElementNode cfn;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ private import cil
|
|||||||
private import dotnet
|
private import dotnet
|
||||||
private import DataFlowDispatch
|
private import DataFlowDispatch
|
||||||
private import DataFlowPrivate
|
private import DataFlowPrivate
|
||||||
private import semmle.code.csharp.Caching
|
|
||||||
private import semmle.code.csharp.controlflow.Guards
|
private import semmle.code.csharp.controlflow.Guards
|
||||||
private import semmle.code.csharp.Unification
|
private import semmle.code.csharp.Unification
|
||||||
|
|
||||||
@@ -38,38 +37,21 @@ class Node extends TNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the type of this node. */
|
/** Gets the type of this node. */
|
||||||
cached
|
final DotNet::Type getType() { result = this.(NodeImpl).getTypeImpl() }
|
||||||
final DotNet::Type getType() {
|
|
||||||
Stages::DataFlowStage::forceCachingInSameStage() and result = this.(NodeImpl).getTypeImpl()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the enclosing callable of this node. */
|
/** Gets the enclosing callable of this node. */
|
||||||
cached
|
|
||||||
final DataFlowCallable getEnclosingCallable() {
|
final DataFlowCallable getEnclosingCallable() {
|
||||||
Stages::DataFlowStage::forceCachingInSameStage() and
|
|
||||||
result = this.(NodeImpl).getEnclosingCallableImpl()
|
result = this.(NodeImpl).getEnclosingCallableImpl()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the control flow node corresponding to this node, if any. */
|
/** Gets the control flow node corresponding to this node, if any. */
|
||||||
cached
|
final ControlFlow::Node getControlFlowNode() { result = this.(NodeImpl).getControlFlowNodeImpl() }
|
||||||
final ControlFlow::Node getControlFlowNode() {
|
|
||||||
Stages::DataFlowStage::forceCachingInSameStage() and
|
|
||||||
result = this.(NodeImpl).getControlFlowNodeImpl()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a textual representation of this node. */
|
/** Gets a textual representation of this node. */
|
||||||
cached
|
final string toString() { result = this.(NodeImpl).toStringImpl() }
|
||||||
final string toString() {
|
|
||||||
Stages::DataFlowStage::forceCachingInSameStage() and
|
|
||||||
result = this.(NodeImpl).toStringImpl()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the location of this node. */
|
/** Gets the location of this node. */
|
||||||
cached
|
final Location getLocation() { result = this.(NodeImpl).getLocationImpl() }
|
||||||
final Location getLocation() {
|
|
||||||
Stages::DataFlowStage::forceCachingInSameStage() and
|
|
||||||
result = this.(NodeImpl).getLocationImpl()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this element is at the specified location.
|
* Holds if this element is at the specified location.
|
||||||
@@ -81,7 +63,7 @@ class Node extends TNode {
|
|||||||
predicate hasLocationInfo(
|
predicate hasLocationInfo(
|
||||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||||
) {
|
) {
|
||||||
getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,18 +99,18 @@ class ExprNode extends Node {
|
|||||||
* flow graph.
|
* flow graph.
|
||||||
*/
|
*/
|
||||||
class ParameterNode extends Node {
|
class ParameterNode extends Node {
|
||||||
private ParameterNodeImpl p;
|
ParameterNode() { parameterNode(this, _, _) }
|
||||||
|
|
||||||
ParameterNode() { this = p }
|
|
||||||
|
|
||||||
/** Gets the parameter corresponding to this node, if any. */
|
/** Gets the parameter corresponding to this node, if any. */
|
||||||
DotNet::Parameter getParameter() { result = p.getParameter() }
|
DotNet::Parameter getParameter() {
|
||||||
|
exists(DataFlowCallable c, int i | this.isParameterOf(c, i) and result = c.getParameter(i))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this node is the parameter of callable `c` at the specified
|
* Holds if this node is the parameter of callable `c` at the specified
|
||||||
* (zero-based) position.
|
* (zero-based) position.
|
||||||
*/
|
*/
|
||||||
predicate isParameterOf(DataFlowCallable c, int i) { p.isParameterOf(c, i) }
|
predicate isParameterOf(DataFlowCallable c, int i) { parameterNode(this, c, i) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A definition, viewed as a node in a data flow graph. */
|
/** A definition, viewed as a node in a data flow graph. */
|
||||||
@@ -166,6 +148,7 @@ predicate localFlowStep = localFlowStepImpl/2;
|
|||||||
* Holds if data flows from `source` to `sink` in zero or more local
|
* Holds if data flows from `source` to `sink` in zero or more local
|
||||||
* (intra-procedural) steps.
|
* (intra-procedural) steps.
|
||||||
*/
|
*/
|
||||||
|
pragma[inline]
|
||||||
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
|
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -446,7 +446,19 @@ module Private {
|
|||||||
summary(c, inputContents, outputContents, preservesValue) and
|
summary(c, inputContents, outputContents, preservesValue) and
|
||||||
pred = summaryNodeInputState(c, inputContents) and
|
pred = summaryNodeInputState(c, inputContents) and
|
||||||
succ = summaryNodeOutputState(c, outputContents)
|
succ = summaryNodeOutputState(c, outputContents)
|
||||||
|
|
|
||||||
|
preservesValue = true
|
||||||
|
or
|
||||||
|
preservesValue = false and not summary(c, inputContents, outputContents, true)
|
||||||
)
|
)
|
||||||
|
or
|
||||||
|
// If flow through a method updates a parameter from some input A, and that
|
||||||
|
// parameter also is returned through B, then we'd like a combined flow from A
|
||||||
|
// to B as well. As an example, this simplifies modeling of fluent methods:
|
||||||
|
// for `StringBuilder.append(x)` with a specified value flow from qualifier to
|
||||||
|
// return value and taint flow from argument 0 to the qualifier, then this
|
||||||
|
// allows us to infer taint flow from argument 0 to the return value.
|
||||||
|
summaryPostUpdateNode(pred, succ) and preservesValue = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -268,56 +268,146 @@ private module CallGraph {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple flow step that does not take flow through fields or flow out
|
||||||
|
* of callables into account.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
private predicate delegateFlowStep(Expr pred, Expr succ) {
|
private predicate delegateFlowStep(Expr pred, Expr succ) {
|
||||||
Steps::stepClosed(pred, succ)
|
Steps::stepClosed(pred, succ)
|
||||||
or
|
or
|
||||||
exists(Call call, Callable callable |
|
|
||||||
callable.getUnboundDeclaration().canReturn(pred) and
|
|
||||||
call = succ
|
|
||||||
|
|
|
||||||
callable = call.getTarget() or
|
|
||||||
callable = call.getTarget().(Method).getAnOverrider+() or
|
|
||||||
callable = call.getTarget().(Method).getAnUltimateImplementor() or
|
|
||||||
callable = getARuntimeDelegateTarget(call, false)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
pred = succ.(DelegateCreation).getArgument()
|
pred = succ.(DelegateCreation).getArgument()
|
||||||
or
|
or
|
||||||
exists(AssignableDefinition def, Assignable a |
|
|
||||||
a instanceof Field or
|
|
||||||
a instanceof Property
|
|
||||||
|
|
|
||||||
a = def.getTarget() and
|
|
||||||
succ.(AssignableRead) = a.getAnAccess() and
|
|
||||||
pred = def.getSource()
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(AddEventExpr ae | succ.(EventAccess).getTarget() = ae.getTarget() |
|
exists(AddEventExpr ae | succ.(EventAccess).getTarget() = ae.getTarget() |
|
||||||
pred = ae.getRValue()
|
pred = ae.getRValue()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate reachesDelegateCall(Expr e) {
|
private predicate delegateCreationReaches(Callable c, Expr e) {
|
||||||
delegateCall(_, e, _)
|
delegateCreation(e, c, _)
|
||||||
or
|
or
|
||||||
exists(Expr mid | reachesDelegateCall(mid) | delegateFlowStep(e, mid))
|
exists(Expr mid |
|
||||||
|
delegateCreationReaches(c, mid) and
|
||||||
|
delegateFlowStep(mid, e)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
private predicate reachesDelegateCall(Expr e, Call c, boolean libraryDelegateCall) {
|
||||||
private predicate delegateFlowStepReaches(Expr pred, Expr succ) {
|
delegateCall(c, e, libraryDelegateCall)
|
||||||
delegateFlowStep(pred, succ) and
|
or
|
||||||
reachesDelegateCall(succ)
|
exists(Expr mid |
|
||||||
|
reachesDelegateCall(mid, c, libraryDelegateCall) and
|
||||||
|
delegateFlowStep(e, mid)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expr delegateCallSource(Callable c) {
|
/**
|
||||||
delegateCreation(result, c, _)
|
* A "busy" flow element, that is, a node in the data-flow graph that typically
|
||||||
or
|
* has a large fan-in or a large fan-out (or both).
|
||||||
delegateFlowStepReaches(delegateCallSource(c), result)
|
*
|
||||||
|
* For such busy elements, we do not track flow directly from all delegate
|
||||||
|
* creations, but instead we first perform a flow analysis between busy elements,
|
||||||
|
* and then only in the end join up with delegate creations and delegate calls.
|
||||||
|
*/
|
||||||
|
abstract private class BusyFlowElement extends Element {
|
||||||
|
pragma[nomagic]
|
||||||
|
abstract Expr getAnInput();
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
abstract Expr getAnOutput();
|
||||||
|
|
||||||
|
/** Holds if this element can be reached from expression `e`. */
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate exprReaches(Expr e) {
|
||||||
|
this.reachesCall(_) and
|
||||||
|
e = this.getAnInput()
|
||||||
|
or
|
||||||
|
exists(Expr mid |
|
||||||
|
this.exprReaches(mid) and
|
||||||
|
delegateFlowStep(e, mid)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this element can reach a delegate call `c` directly without
|
||||||
|
* passing through another busy element.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
predicate delegateCall(Call c, boolean libraryDelegateCall) {
|
||||||
|
reachesDelegateCall(this.getAnOutput(), c, libraryDelegateCall)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private BusyFlowElement getASuccessor() { result.exprReaches(this.getAnOutput()) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this element reaches another busy element `other`,
|
||||||
|
* which can reach a delegate call directly without passing
|
||||||
|
* through another busy element.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate reachesCall(BusyFlowElement other) {
|
||||||
|
this = other and
|
||||||
|
other.delegateCall(_, _)
|
||||||
|
or
|
||||||
|
this.getASuccessor().reachesCall(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if this element is reached by a delegate creation for `c`. */
|
||||||
|
pragma[nomagic]
|
||||||
|
predicate isReachedBy(Callable c) {
|
||||||
|
exists(BusyFlowElement pred |
|
||||||
|
pred.reachesCall(this) and
|
||||||
|
delegateCreationReaches(c, pred.getAnInput())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TFieldOrProperty = @field or @property;
|
||||||
|
|
||||||
|
private class FieldOrPropertyFlow extends BusyFlowElement, Assignable, TFieldOrProperty {
|
||||||
|
final override Expr getAnInput() {
|
||||||
|
exists(Assignable target |
|
||||||
|
target = this.getUnboundDeclaration() and
|
||||||
|
result = target.getAnAssignedValue()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
final override AssignableRead getAnOutput() {
|
||||||
|
exists(Assignable target |
|
||||||
|
target = this.getUnboundDeclaration() and
|
||||||
|
result = target.getAnAccess()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CallOutputFlow extends BusyFlowElement, Callable {
|
||||||
|
final override Expr getAnInput() { this.canReturn(result) }
|
||||||
|
|
||||||
|
final override Call getAnOutput() {
|
||||||
|
exists(Callable target | this = target.getUnboundDeclaration() |
|
||||||
|
target = result.getTarget() or
|
||||||
|
target = result.getTarget().(Method).getAnOverrider+() or
|
||||||
|
target = result.getTarget().(Method).getAnUltimateImplementor() or
|
||||||
|
target = getARuntimeDelegateTarget(result, false)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a run-time target for the delegate call `c`. */
|
/** Gets a run-time target for the delegate call `c`. */
|
||||||
|
pragma[nomagic]
|
||||||
Callable getARuntimeDelegateTarget(Call c, boolean libraryDelegateCall) {
|
Callable getARuntimeDelegateTarget(Call c, boolean libraryDelegateCall) {
|
||||||
delegateCall(c, delegateCallSource(result), libraryDelegateCall)
|
// directly resolvable without going through a "busy" element
|
||||||
|
exists(Expr e |
|
||||||
|
delegateCreationReaches(result, e) and
|
||||||
|
delegateCall(c, e, libraryDelegateCall)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// resolvable by going through one or more "busy" elements
|
||||||
|
exists(BusyFlowElement busy |
|
||||||
|
busy.isReachedBy(result) and
|
||||||
|
busy.delegateCall(c, libraryDelegateCall)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -316,6 +316,15 @@ private module SsaDefReaches {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the reference to `def` at index `i` in basic block `bb` is the
|
||||||
|
* last reference to `v` inside `bb`.
|
||||||
|
*/
|
||||||
|
pragma[noinline]
|
||||||
|
predicate lastSsaRef(Definition def, SourceVariable v, BasicBlock bb, int i) {
|
||||||
|
ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v)
|
||||||
|
}
|
||||||
|
|
||||||
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
||||||
exists(ssaDefRank(def, v, bb, _, _))
|
exists(ssaDefRank(def, v, bb, _, _))
|
||||||
}
|
}
|
||||||
@@ -351,8 +360,7 @@ private module SsaDefReaches {
|
|||||||
*/
|
*/
|
||||||
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
||||||
varBlockReaches(def, bb1, bb2) and
|
varBlockReaches(def, bb1, bb2) and
|
||||||
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and
|
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1
|
||||||
variableRead(bb2, i2, _, _)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,15 +442,22 @@ predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2
|
|||||||
bb2 = bb1
|
bb2 = bb1
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(SourceVariable v | ssaDefRank(def, v, bb1, i1, _) = maxSsaRefRank(bb1, v)) and
|
lastSsaRef(def, _, bb1, i1) and
|
||||||
defAdjacentRead(def, bb1, bb2, i2)
|
defAdjacentRead(def, bb1, bb2, i2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate adjacentDefRead(
|
||||||
|
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2, SourceVariable v
|
||||||
|
) {
|
||||||
|
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
||||||
|
v = def.getSourceVariable()
|
||||||
|
}
|
||||||
|
|
||||||
private predicate adjacentDefReachesRead(
|
private predicate adjacentDefReachesRead(
|
||||||
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
||||||
) {
|
) {
|
||||||
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
exists(SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) |
|
||||||
exists(SourceVariable v | v = def.getSourceVariable() |
|
|
||||||
ssaRef(bb1, i1, v, SsaDef())
|
ssaRef(bb1, i1, v, SsaDef())
|
||||||
or
|
or
|
||||||
variableRead(bb1, i1, v, true)
|
variableRead(bb1, i1, v, true)
|
||||||
@@ -475,17 +490,19 @@ predicate adjacentDefNoUncertainReads(Definition def, BasicBlock bb1, int i1, Ba
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
||||||
exists(int rnk, SourceVariable v, int j | rnk = ssaDefRank(def, v, bb, i, _) |
|
exists(SourceVariable v |
|
||||||
// Next reference to `v` inside `bb` is a write
|
// Next reference to `v` inside `bb` is a write
|
||||||
next.definesAt(v, bb, j) and
|
exists(int rnk, int j |
|
||||||
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
rnk = ssaDefRank(def, v, bb, i, _) and
|
||||||
|
next.definesAt(v, bb, j) and
|
||||||
|
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
||||||
|
)
|
||||||
or
|
or
|
||||||
// Can reach a write using one or more steps
|
// Can reach a write using one or more steps
|
||||||
rnk = maxSsaRefRank(bb, v) and
|
lastSsaRef(def, v, bb, i) and
|
||||||
exists(BasicBlock bb2 |
|
exists(BasicBlock bb2 |
|
||||||
varBlockReaches(def, bb, bb2) and
|
varBlockReaches(def, bb, bb2) and
|
||||||
next.definesAt(v, bb2, j) and
|
1 = ssaDefRank(next, v, bb2, _, SsaDef())
|
||||||
1 = ssaRefRank(bb2, j, v, SsaDef())
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -539,7 +556,8 @@ pragma[nomagic]
|
|||||||
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
||||||
lastRefRedef(def, bb, i, _)
|
lastRefRedef(def, bb, i, _)
|
||||||
or
|
or
|
||||||
exists(SourceVariable v | ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) |
|
lastSsaRef(def, _, bb, i) and
|
||||||
|
(
|
||||||
// Can reach exit directly
|
// Can reach exit directly
|
||||||
bb instanceof ExitBasicBlock
|
bb instanceof ExitBasicBlock
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -316,6 +316,15 @@ private module SsaDefReaches {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the reference to `def` at index `i` in basic block `bb` is the
|
||||||
|
* last reference to `v` inside `bb`.
|
||||||
|
*/
|
||||||
|
pragma[noinline]
|
||||||
|
predicate lastSsaRef(Definition def, SourceVariable v, BasicBlock bb, int i) {
|
||||||
|
ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v)
|
||||||
|
}
|
||||||
|
|
||||||
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
||||||
exists(ssaDefRank(def, v, bb, _, _))
|
exists(ssaDefRank(def, v, bb, _, _))
|
||||||
}
|
}
|
||||||
@@ -351,8 +360,7 @@ private module SsaDefReaches {
|
|||||||
*/
|
*/
|
||||||
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
||||||
varBlockReaches(def, bb1, bb2) and
|
varBlockReaches(def, bb1, bb2) and
|
||||||
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and
|
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1
|
||||||
variableRead(bb2, i2, _, _)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,15 +442,22 @@ predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2
|
|||||||
bb2 = bb1
|
bb2 = bb1
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(SourceVariable v | ssaDefRank(def, v, bb1, i1, _) = maxSsaRefRank(bb1, v)) and
|
lastSsaRef(def, _, bb1, i1) and
|
||||||
defAdjacentRead(def, bb1, bb2, i2)
|
defAdjacentRead(def, bb1, bb2, i2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate adjacentDefRead(
|
||||||
|
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2, SourceVariable v
|
||||||
|
) {
|
||||||
|
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
||||||
|
v = def.getSourceVariable()
|
||||||
|
}
|
||||||
|
|
||||||
private predicate adjacentDefReachesRead(
|
private predicate adjacentDefReachesRead(
|
||||||
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
||||||
) {
|
) {
|
||||||
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
exists(SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) |
|
||||||
exists(SourceVariable v | v = def.getSourceVariable() |
|
|
||||||
ssaRef(bb1, i1, v, SsaDef())
|
ssaRef(bb1, i1, v, SsaDef())
|
||||||
or
|
or
|
||||||
variableRead(bb1, i1, v, true)
|
variableRead(bb1, i1, v, true)
|
||||||
@@ -475,17 +490,19 @@ predicate adjacentDefNoUncertainReads(Definition def, BasicBlock bb1, int i1, Ba
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
||||||
exists(int rnk, SourceVariable v, int j | rnk = ssaDefRank(def, v, bb, i, _) |
|
exists(SourceVariable v |
|
||||||
// Next reference to `v` inside `bb` is a write
|
// Next reference to `v` inside `bb` is a write
|
||||||
next.definesAt(v, bb, j) and
|
exists(int rnk, int j |
|
||||||
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
rnk = ssaDefRank(def, v, bb, i, _) and
|
||||||
|
next.definesAt(v, bb, j) and
|
||||||
|
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
||||||
|
)
|
||||||
or
|
or
|
||||||
// Can reach a write using one or more steps
|
// Can reach a write using one or more steps
|
||||||
rnk = maxSsaRefRank(bb, v) and
|
lastSsaRef(def, v, bb, i) and
|
||||||
exists(BasicBlock bb2 |
|
exists(BasicBlock bb2 |
|
||||||
varBlockReaches(def, bb, bb2) and
|
varBlockReaches(def, bb, bb2) and
|
||||||
next.definesAt(v, bb2, j) and
|
1 = ssaDefRank(next, v, bb2, _, SsaDef())
|
||||||
1 = ssaRefRank(bb2, j, v, SsaDef())
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -539,7 +556,8 @@ pragma[nomagic]
|
|||||||
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
||||||
lastRefRedef(def, bb, i, _)
|
lastRefRedef(def, bb, i, _)
|
||||||
or
|
or
|
||||||
exists(SourceVariable v | ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) |
|
lastSsaRef(def, _, bb, i) and
|
||||||
|
(
|
||||||
// Can reach exit directly
|
// Can reach exit directly
|
||||||
bb instanceof ExitBasicBlock
|
bb instanceof ExitBasicBlock
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -233,71 +233,61 @@ private module Internal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private predicate hasOverrider(OverridableCallable oc, ValueOrRefType t) {
|
private predicate hasOverrider(OverridableCallable oc, Gvn::GvnType t) {
|
||||||
exists(oc.getAnOverrider(t))
|
exists(oc.getAnOverrider(any(ValueOrRefType t0 | Gvn::getGlobalValueNumber(t0) = t)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private predicate hasCallable(OverridableCallable source, ValueOrRefType t, OverridableCallable c) {
|
private predicate hasCallable(OverridableCallable source, Gvn::GvnType t, OverridableCallable c) {
|
||||||
c.getUnboundDeclaration() = source and
|
c.getUnboundDeclaration() = source and
|
||||||
t.hasCallable(c) and
|
any(ValueOrRefType t0 | Gvn::getGlobalValueNumber(t0) = t).hasCallable(c) and
|
||||||
hasOverrider(c, t) and
|
hasOverrider(c, t) and
|
||||||
hasQualifierTypeOverridden0(t, _) and
|
source = any(DispatchMethodOrAccessorCall call).getAStaticTargetExt()
|
||||||
hasQualifierTypeOverridden1(source, _)
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[noinline]
|
|
||||||
private Unification::ConstrainedTypeParameter getAConstrainedTypeParameterQualifierType(
|
|
||||||
DispatchMethodOrAccessorCall call
|
|
||||||
) {
|
|
||||||
result = getAPossibleType(call.getQualifier(), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[noinline]
|
|
||||||
private predicate constrainedTypeParameterQualifierTypeSubsumes(
|
|
||||||
ValueOrRefType t, Unification::ConstrainedTypeParameter tp
|
|
||||||
) {
|
|
||||||
tp = getAConstrainedTypeParameterQualifierType(_) and
|
|
||||||
tp.subsumes(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[noinline]
|
|
||||||
private predicate hasQualifierTypeOverridden0(ValueOrRefType t, DispatchMethodOrAccessorCall call) {
|
|
||||||
hasOverrider(_, t) and
|
|
||||||
(
|
|
||||||
exists(Type t0, Type t1 |
|
|
||||||
t0 = getAPossibleType(call.getQualifier(), false) and
|
|
||||||
t1 = [t0, t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()]
|
|
||||||
|
|
|
||||||
t = t1
|
|
||||||
or
|
|
||||||
Unification::subsumes(t1, t)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
constrainedTypeParameterQualifierTypeSubsumes(t,
|
|
||||||
getAConstrainedTypeParameterQualifierType(call))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[noinline]
|
|
||||||
private predicate hasQualifierTypeOverridden1(
|
|
||||||
OverridableCallable c, DispatchMethodOrAccessorCall call
|
|
||||||
) {
|
|
||||||
exists(OverridableCallable target | call.getAStaticTarget() = target |
|
|
||||||
c = target.getUnboundDeclaration()
|
|
||||||
or
|
|
||||||
c = target.getAnUltimateImplementor().getUnboundDeclaration()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract private class DispatchMethodOrAccessorCall extends DispatchCallImpl {
|
abstract private class DispatchMethodOrAccessorCall extends DispatchCallImpl {
|
||||||
|
pragma[noinline]
|
||||||
|
OverridableCallable getAStaticTargetExt() {
|
||||||
|
exists(OverridableCallable target | this.getAStaticTarget() = target |
|
||||||
|
result = target.getUnboundDeclaration()
|
||||||
|
or
|
||||||
|
result = target.getAnUltimateImplementor().getUnboundDeclaration()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate hasQualifierTypeInherited(Type t) { t = getAPossibleType(this.getQualifier(), _) }
|
predicate hasQualifierTypeInherited(Type t) { t = getAPossibleType(this.getQualifier(), _) }
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate hasSubsumedQualifierType(Gvn::GvnType t) {
|
||||||
|
hasOverrider(_, t) and
|
||||||
|
exists(Type t0 |
|
||||||
|
t0 = getAPossibleType(this.getQualifier(), false) and
|
||||||
|
not t0 instanceof TypeParameter
|
||||||
|
|
|
||||||
|
t = Gvn::getGlobalValueNumber(t0)
|
||||||
|
or
|
||||||
|
Gvn::subsumes(Gvn::getGlobalValueNumber(t0), t)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate hasConstrainedTypeParameterQualifierType(
|
||||||
|
Unification::ConstrainedTypeParameter tp
|
||||||
|
) {
|
||||||
|
tp = getAPossibleType(this.getQualifier(), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate hasUnconstrainedTypeParameterQualifierType() {
|
||||||
|
getAPossibleType(this.getQualifier(), false) instanceof
|
||||||
|
Unification::UnconstrainedTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate hasQualifierTypeOverridden(ValueOrRefType t, OverridableCallable c) {
|
predicate hasSubsumedQualifierTypeOverridden(Gvn::GvnType t, OverridableCallable c) {
|
||||||
hasQualifierTypeOverridden0(t, this) and
|
this.hasSubsumedQualifierType(t) and
|
||||||
hasCallable(any(OverridableCallable oc | hasQualifierTypeOverridden1(oc, this)), t, c)
|
hasCallable(any(OverridableCallable oc | oc = this.getAStaticTargetExt()), t, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -357,12 +347,33 @@ private module Internal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private Callable getASubsumedStaticTarget0(Type t) {
|
private predicate contextArgHasConstrainedTypeParameterType(
|
||||||
|
DispatchCall ctx, Unification::ConstrainedTypeParameter tp
|
||||||
|
) {
|
||||||
|
this.contextArgHasType(ctx, tp, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate contextArgHasUnconstrainedTypeParameterType(DispatchCall ctx) {
|
||||||
|
this.contextArgHasType(ctx, any(Unification::UnconstrainedTypeParameter t), false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate contextArgHasNonTypeParameterType(DispatchCall ctx, Gvn::GvnType t) {
|
||||||
|
exists(Type t0 |
|
||||||
|
this.contextArgHasType(ctx, t0, false) and
|
||||||
|
not t0 instanceof TypeParameter and
|
||||||
|
t = Gvn::getGlobalValueNumber(t0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private Callable getASubsumedStaticTarget0(Gvn::GvnType t) {
|
||||||
exists(Callable staticTarget, Type declType |
|
exists(Callable staticTarget, Type declType |
|
||||||
staticTarget = this.getAStaticTarget() and
|
staticTarget = this.getAStaticTarget() and
|
||||||
declType = staticTarget.getDeclaringType() and
|
declType = staticTarget.getDeclaringType() and
|
||||||
result = staticTarget.getUnboundDeclaration() and
|
result = staticTarget.getUnboundDeclaration() and
|
||||||
Unification::subsumes(declType, t)
|
Gvn::subsumes(Gvn::getGlobalValueNumber(declType), t)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +386,8 @@ private module Internal {
|
|||||||
private Callable getASubsumedStaticTarget() {
|
private Callable getASubsumedStaticTarget() {
|
||||||
result = this.getAStaticTarget()
|
result = this.getAStaticTarget()
|
||||||
or
|
or
|
||||||
result.getUnboundDeclaration() = this.getASubsumedStaticTarget0(result.getDeclaringType())
|
result.getUnboundDeclaration() =
|
||||||
|
this.getASubsumedStaticTarget0(Gvn::getGlobalValueNumber(result.getDeclaringType()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -426,6 +438,12 @@ private module Internal {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
NonConstructedOverridableCallable getAViableOverrider0() {
|
||||||
|
getAPossibleType(this.getQualifier(), false) instanceof TypeParameter and
|
||||||
|
result.getAConstructingCallableOrSelf() = this.getAStaticTargetExt()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a callable that is defined in a subtype of the qualifier type of this
|
* Gets a callable that is defined in a subtype of the qualifier type of this
|
||||||
* call, and which overrides a static target of this call.
|
* call, and which overrides a static target of this call.
|
||||||
@@ -468,9 +486,22 @@ private module Internal {
|
|||||||
*/
|
*/
|
||||||
private RuntimeCallable getAViableOverrider() {
|
private RuntimeCallable getAViableOverrider() {
|
||||||
exists(ValueOrRefType t, NonConstructedOverridableCallable c |
|
exists(ValueOrRefType t, NonConstructedOverridableCallable c |
|
||||||
this.hasQualifierTypeOverridden(t, c.getAConstructingCallableOrSelf()) and
|
this.hasSubsumedQualifierTypeOverridden(Gvn::getGlobalValueNumber(t),
|
||||||
|
c.getAConstructingCallableOrSelf()) and
|
||||||
result = c.getAnOverrider(t)
|
result = c.getAnOverrider(t)
|
||||||
)
|
)
|
||||||
|
or
|
||||||
|
exists(NonConstructedOverridableCallable c |
|
||||||
|
c = this.getAViableOverrider0() and
|
||||||
|
result = c.getAnOverrider(_)
|
||||||
|
|
|
||||||
|
this.hasUnconstrainedTypeParameterQualifierType()
|
||||||
|
or
|
||||||
|
exists(Unification::ConstrainedTypeParameter tp |
|
||||||
|
this.hasConstrainedTypeParameterQualifierType(tp) and
|
||||||
|
tp.subsumes(result.getDeclaringType())
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override RuntimeCallable getADynamicTarget() {
|
override RuntimeCallable getADynamicTarget() {
|
||||||
@@ -510,36 +541,40 @@ private module Internal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private RuntimeCallable getAViableOverriderInCallContext0(
|
private RuntimeCallable getAViableOverriderInCallContext0(Gvn::GvnType t) {
|
||||||
NonConstructedOverridableCallable c, ValueOrRefType t
|
exists(NonConstructedOverridableCallable c |
|
||||||
) {
|
result = this.getAViableOverrider() and
|
||||||
result = this.getAViableOverrider() and
|
this.contextArgHasType(_, _, false) and
|
||||||
this.contextArgHasType(_, _, false) and
|
result = c.getAnOverrider(any(Type t0 | t = Gvn::getGlobalValueNumber(t0))) and
|
||||||
result = c.getAnOverrider(t)
|
this.getAStaticTarget() = c.getAConstructingCallableOrSelf()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private RuntimeCallable getAViableOverriderInCallContext1(
|
private predicate contextArgHasSubsumedType(DispatchCall ctx, Gvn::GvnType t) {
|
||||||
NonConstructedOverridableCallable c, DispatchCall ctx
|
hasOverrider(_, t) and
|
||||||
) {
|
exists(Gvn::GvnType t0 | this.contextArgHasNonTypeParameterType(ctx, t0) |
|
||||||
exists(ValueOrRefType t |
|
t = t0
|
||||||
result = this.getAViableOverriderInCallContext0(c, t) and
|
or
|
||||||
exists(Type t0, Type t1 |
|
Gvn::subsumes(t0, t)
|
||||||
this.contextArgHasType(ctx, t0, false) and
|
|
||||||
t1 = [t0, t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()]
|
|
||||||
|
|
|
||||||
t = t1
|
|
||||||
or
|
|
||||||
Unification::subsumes(t1, t)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private RuntimeCallable getAViableOverriderInCallContext(DispatchCall ctx) {
|
private RuntimeCallable getAViableOverriderInCallContext(DispatchCall ctx) {
|
||||||
exists(NonConstructedOverridableCallable c |
|
exists(Gvn::GvnType t |
|
||||||
result = this.getAViableOverriderInCallContext1(c, ctx) and
|
result = this.getAViableOverriderInCallContext0(t) and
|
||||||
this.getAStaticTarget() = c.getAConstructingCallableOrSelf()
|
this.contextArgHasSubsumedType(ctx, t)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
result = this.getAViableOverrider() and
|
||||||
|
(
|
||||||
|
this.contextArgHasUnconstrainedTypeParameterType(ctx)
|
||||||
|
or
|
||||||
|
exists(Unification::ConstrainedTypeParameter tp |
|
||||||
|
this.contextArgHasConstrainedTypeParameterType(ctx, tp) and
|
||||||
|
tp.subsumes(result.getDeclaringType())
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user