mirror of
https://github.com/github/codeql.git
synced 2026-05-18 05:07:06 +02:00
Compare commits
360 Commits
codeql-cli
...
smowton/ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
463db799ba | ||
|
|
d2636aad68 | ||
|
|
5adc9f8ff0 | ||
|
|
8c27437628 | ||
|
|
12ee93042b | ||
|
|
bac356c9a1 | ||
|
|
68c1a3d389 | ||
|
|
05bef12ddd | ||
|
|
1df3adf021 | ||
|
|
e26c199426 | ||
|
|
1203da1b66 | ||
|
|
f79bd3f4cf | ||
|
|
476df7de73 | ||
|
|
29e01748b7 | ||
|
|
11003e685d | ||
|
|
e4daeec2ca | ||
|
|
81977f11a1 | ||
|
|
32fe12a6dd | ||
|
|
83adf793e4 | ||
|
|
52dc58172d | ||
|
|
544931f73f | ||
|
|
2d02908e7f | ||
|
|
4fcf3fbff8 | ||
|
|
6f40ac15b4 | ||
|
|
55ea55a44f | ||
|
|
36fa0a22f9 | ||
|
|
3f08ff88a4 | ||
|
|
5e6e64b2b7 | ||
|
|
4973523404 | ||
|
|
2d61fc5309 | ||
|
|
8e39ed079e | ||
|
|
389cd5d648 | ||
|
|
092d25451f | ||
|
|
32b86eca50 | ||
|
|
40a58135c2 | ||
|
|
7ef96e3f3c | ||
|
|
5531ef9bc1 | ||
|
|
cbc2dbc14d | ||
|
|
208cf716dc | ||
|
|
d72d8b63ed | ||
|
|
1791c1f1f9 | ||
|
|
d5c4a19efa | ||
|
|
6fbf727309 | ||
|
|
e00390d23a | ||
|
|
d079671ec8 | ||
|
|
cbbc057dd3 | ||
|
|
9fc2a54712 | ||
|
|
d0e30d19c4 | ||
|
|
8de37fec17 | ||
|
|
e712e62f14 | ||
|
|
30b30d65c8 | ||
|
|
6d67e419ff | ||
|
|
29930fa6bf | ||
|
|
a57c6cde30 | ||
|
|
b16f1d3778 | ||
|
|
73d06f26cb | ||
|
|
fedb9464af | ||
|
|
99b498b891 | ||
|
|
95afe615b5 | ||
|
|
8b03608a4f | ||
|
|
1a6b2b9b82 | ||
|
|
57c2208f7a | ||
|
|
5f1fd57f84 | ||
|
|
6b78313701 | ||
|
|
38fcc61817 | ||
|
|
0db542e9f0 | ||
|
|
4a04f7b66f | ||
|
|
0567864a83 | ||
|
|
18576838d4 | ||
|
|
fe0634574d | ||
|
|
9a00c75460 | ||
|
|
5204255615 | ||
|
|
0222159df5 | ||
|
|
454d13b485 | ||
|
|
16670511de | ||
|
|
ad2aa6d4f8 | ||
|
|
3e0719609f | ||
|
|
1aba0b20cd | ||
|
|
1b5ed129ac | ||
|
|
5f079c1d51 | ||
|
|
5ba3b679dd | ||
|
|
8c0baefd3b | ||
|
|
78495035a6 | ||
|
|
a3885cd8b2 | ||
|
|
b4cb2c3f13 | ||
|
|
ef6332c581 | ||
|
|
ad6f800022 | ||
|
|
e5f52f086c | ||
|
|
18a2aca42f | ||
|
|
e7a0fc7140 | ||
|
|
f14ccd8c81 | ||
|
|
e54d7c7c73 | ||
|
|
813d4639ca | ||
|
|
76fe3fa502 | ||
|
|
8b936c5dbe | ||
|
|
34800d1519 | ||
|
|
1644376cc9 | ||
|
|
1b1c9c680c | ||
|
|
61a53fadc0 | ||
|
|
2f29c905c3 | ||
|
|
e1cf0a15ed | ||
|
|
52c510bfea | ||
|
|
b2f878229d | ||
|
|
3dd6b3fb69 | ||
|
|
c316d51d41 | ||
|
|
25647badbd | ||
|
|
6445fd805d | ||
|
|
a35e7b27af | ||
|
|
ab495fa843 | ||
|
|
2320d502db | ||
|
|
31867a56fb | ||
|
|
86d9c349ec | ||
|
|
59fa01e386 | ||
|
|
a6f8af0de5 | ||
|
|
f6f5b7e1e9 | ||
|
|
275724000b | ||
|
|
939f3e83aa | ||
|
|
d69fe20d7d | ||
|
|
9f5de6b4f2 | ||
|
|
6d60595d73 | ||
|
|
e1f3d5b374 | ||
|
|
5cdfb77504 | ||
|
|
8ee35231c2 | ||
|
|
55525279ca | ||
|
|
4d7c84178a | ||
|
|
eb37255c4b | ||
|
|
164cae845d | ||
|
|
b8d01ed21b | ||
|
|
cc25d30fed | ||
|
|
07e5479aff | ||
|
|
bc419fd35c | ||
|
|
772503bad8 | ||
|
|
beff080ee7 | ||
|
|
f4edff9452 | ||
|
|
4503c625b4 | ||
|
|
28fec0c129 | ||
|
|
445cca1432 | ||
|
|
497135593c | ||
|
|
2214a944bb | ||
|
|
a0c35516bd | ||
|
|
42cbe0734e | ||
|
|
516b84b59a | ||
|
|
4f1ad0ff5d | ||
|
|
ccc4d8ae3f | ||
|
|
2cb0e81da0 | ||
|
|
aae5333325 | ||
|
|
fa59a8ae24 | ||
|
|
4526afc29f | ||
|
|
1c5a9053f9 | ||
|
|
5a08adc06c | ||
|
|
0b8b75ac25 | ||
|
|
b7125a009e | ||
|
|
97a0b9f0ca | ||
|
|
46a5035543 | ||
|
|
bb71790a53 | ||
|
|
db3f22a2e8 | ||
|
|
3d445be926 | ||
|
|
ede05b54ea | ||
|
|
9a94d0474c | ||
|
|
9e9d57bac5 | ||
|
|
8e3c373548 | ||
|
|
5bfeede364 | ||
|
|
f49531b3ca | ||
|
|
0f4f0b880a | ||
|
|
e0a7889b71 | ||
|
|
bd09aad7d5 | ||
|
|
980c4cf5f4 | ||
|
|
544015d0a6 | ||
|
|
b974a84bef | ||
|
|
aed0e688f5 | ||
|
|
13a5249a9d | ||
|
|
91752e5307 | ||
|
|
330505c524 | ||
|
|
73850f1b56 | ||
|
|
2bd4ccee45 | ||
|
|
df09f02981 | ||
|
|
732c60c07c | ||
|
|
0f6bae0ae1 | ||
|
|
93dad867cd | ||
|
|
3b1e062985 | ||
|
|
0adece7cde | ||
|
|
739748c29b | ||
|
|
47d9e8a357 | ||
|
|
7024b07dd2 | ||
|
|
c975ae5231 | ||
|
|
c4e0dda178 | ||
|
|
b11b091559 | ||
|
|
4ce04e4749 | ||
|
|
01cc19cffc | ||
|
|
793d2c79de | ||
|
|
f76211c64a | ||
|
|
ffa700c825 | ||
|
|
bd8a127565 | ||
|
|
c488086135 | ||
|
|
452d307fd5 | ||
|
|
7100ca4262 | ||
|
|
a7fecaaa1b | ||
|
|
45e0a929a8 | ||
|
|
8e7d62600d | ||
|
|
f1f4ddb76c | ||
|
|
fafc2ddc0b | ||
|
|
f837d90060 | ||
|
|
fdc5ae375b | ||
|
|
e250c711aa | ||
|
|
cabcb83b2f | ||
|
|
e36080061d | ||
|
|
6c2a3a68b6 | ||
|
|
a556152b9d | ||
|
|
e58a8330cd | ||
|
|
949fc3745a | ||
|
|
a326ce34a8 | ||
|
|
9018401722 | ||
|
|
6c2e0f7658 | ||
|
|
dc26a57548 | ||
|
|
82e2afc93c | ||
|
|
7ed1c0a2ee | ||
|
|
ecd247bf16 | ||
|
|
ad590f30c1 | ||
|
|
075041f1ae | ||
|
|
7e674f3227 | ||
|
|
573ab025b4 | ||
|
|
7bdf2ab9d2 | ||
|
|
8f6f7d0985 | ||
|
|
3d7049265f | ||
|
|
ccd07b8a63 | ||
|
|
55abc52c61 | ||
|
|
e40f896b17 | ||
|
|
d05901ad3f | ||
|
|
7f00a7f67e | ||
|
|
b08c972cc3 | ||
|
|
15980cb1da | ||
|
|
75bd4a7a12 | ||
|
|
da2f77d615 | ||
|
|
3dbfb9fa4b | ||
|
|
699ed50432 | ||
|
|
f484d95081 | ||
|
|
ffaf1c0a24 | ||
|
|
201512525b | ||
|
|
b8581e89bf | ||
|
|
7d34f6e262 | ||
|
|
67b52e29e0 | ||
|
|
3d6765ba1c | ||
|
|
fa9677d615 | ||
|
|
9d645508ea | ||
|
|
114db99dca | ||
|
|
8ce2618b7d | ||
|
|
e8ef58d381 | ||
|
|
f8d0a0d509 | ||
|
|
80d543ecae | ||
|
|
65ca8849f2 | ||
|
|
73eb3e262d | ||
|
|
60ee92d834 | ||
|
|
d89967ce8e | ||
|
|
dd415386ea | ||
|
|
64a7d7d836 | ||
|
|
5e536fb121 | ||
|
|
7bd62087a4 | ||
|
|
656ebab776 | ||
|
|
e1089c8d89 | ||
|
|
11566ee256 | ||
|
|
e4ec79255b | ||
|
|
c30dffc7b9 | ||
|
|
1d461ff5ad | ||
|
|
6ae1ea73f7 | ||
|
|
0b9691aca2 | ||
|
|
9a9e9ac23c | ||
|
|
5414bd2716 | ||
|
|
048afc2c88 | ||
|
|
f76d85c9c6 | ||
|
|
fa926456ef | ||
|
|
1c38fb6ad6 | ||
|
|
b3b30a15b8 | ||
|
|
4ca508d420 | ||
|
|
fbcb65a5d9 | ||
|
|
701569bb20 | ||
|
|
b35271a2ca | ||
|
|
28047fe625 | ||
|
|
e7044061fb | ||
|
|
f8f5094452 | ||
|
|
51b1ea84d3 | ||
|
|
49ced5fd9d | ||
|
|
d6d2855626 | ||
|
|
c37ab8f98e | ||
|
|
1fd60c7671 | ||
|
|
82e9ea2da0 | ||
|
|
a299174f4d | ||
|
|
fdefb4d23a | ||
|
|
d2da49220b | ||
|
|
4b9c9e7a5a | ||
|
|
df8029ff87 | ||
|
|
4140121e96 | ||
|
|
7d6a1f72d5 | ||
|
|
c6500e2759 | ||
|
|
470bc7d6da | ||
|
|
d1175276ca | ||
|
|
d125e224ac | ||
|
|
dc3b7aaab0 | ||
|
|
8d5eb407ad | ||
|
|
224e5dece4 | ||
|
|
dd73399238 | ||
|
|
8e6f920ae2 | ||
|
|
75cab960e2 | ||
|
|
6fe76b3b11 | ||
|
|
ff6e598f72 | ||
|
|
fc5d5b4fcc | ||
|
|
50fdc99b8c | ||
|
|
48475e66af | ||
|
|
93b3f65388 | ||
|
|
a0311c0ea3 | ||
|
|
930b17a2e2 | ||
|
|
efe413cbd0 | ||
|
|
7ff1c12e8f | ||
|
|
7ae2b7698e | ||
|
|
d183dcd6fc | ||
|
|
c11b464492 | ||
|
|
b3631545d4 | ||
|
|
c47a9ddf83 | ||
|
|
4e478c3629 | ||
|
|
7aca94b1ca | ||
|
|
c70633a0f7 | ||
|
|
58a3260c96 | ||
|
|
a11b271d6e | ||
|
|
48254800b1 | ||
|
|
07ac8a5d81 | ||
|
|
2b31928c7b | ||
|
|
948623e767 | ||
|
|
fd309d6e49 | ||
|
|
33fc2bab33 | ||
|
|
beb7750c21 | ||
|
|
86198e3c43 | ||
|
|
bd1c6e6352 | ||
|
|
3d988e8e94 | ||
|
|
812fdbe412 | ||
|
|
ab432ec2e9 | ||
|
|
5942edf2d9 | ||
|
|
f0135e93c5 | ||
|
|
4ba89230db | ||
|
|
0bf0cbae8f | ||
|
|
b061c4d083 | ||
|
|
98949937dd | ||
|
|
78b88d3a44 | ||
|
|
9ab29f9be0 | ||
|
|
dabc5d54c9 | ||
|
|
03d6528687 | ||
|
|
1b117900c2 | ||
|
|
d6ca1ca846 | ||
|
|
196f6e1931 | ||
|
|
657e26a375 | ||
|
|
4f4baee888 | ||
|
|
aa058c2cca | ||
|
|
a18f3b6859 | ||
|
|
67ab0fee83 | ||
|
|
6e3fd25b09 | ||
|
|
157487d8f2 | ||
|
|
1ac3706e75 | ||
|
|
6fc963177c | ||
|
|
ac55cf9544 | ||
|
|
6fbae45d49 | ||
|
|
6a1e26c566 | ||
|
|
384e17a4ef |
1
.github/workflows/ql-for-ql-build.yml
vendored
1
.github/workflows/ql-for-ql-build.yml
vendored
@@ -27,6 +27,7 @@ jobs:
|
||||
uses: github/codeql-action/init@main
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
tools: nightly
|
||||
- uses: ./.github/actions/os-version
|
||||
id: os_version
|
||||
### Build the extractor ###
|
||||
|
||||
2
.github/workflows/ql-for-ql-tests.yml
vendored
2
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -30,6 +30,7 @@ jobs:
|
||||
uses: github/codeql-action/init@main
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
tools: nightly
|
||||
- uses: ./.github/actions/os-version
|
||||
id: os_version
|
||||
- uses: actions/cache@v3
|
||||
@@ -75,6 +76,7 @@ jobs:
|
||||
uses: github/codeql-action/init@main
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
tools: nightly
|
||||
- uses: ./.github/actions/os-version
|
||||
id: os_version
|
||||
- uses: actions/cache@v3
|
||||
|
||||
17
MODULE.bazel
17
MODULE.bazel
@@ -24,7 +24,7 @@ bazel_dep(name = "bazel_skylib", version = "1.8.1")
|
||||
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl")
|
||||
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
|
||||
bazel_dep(name = "fmt", version = "12.1.0-codeql.1")
|
||||
bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1")
|
||||
bazel_dep(name = "rules_kotlin", version = "2.2.0-codeql.1")
|
||||
bazel_dep(name = "gazelle", version = "0.40.0")
|
||||
bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.1")
|
||||
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
|
||||
@@ -221,10 +221,6 @@ use_repo(
|
||||
kotlin_extractor_deps,
|
||||
"codeql_kotlin_defaults",
|
||||
"codeql_kotlin_embeddable",
|
||||
"kotlin-compiler-1.6.0",
|
||||
"kotlin-compiler-1.6.20",
|
||||
"kotlin-compiler-1.7.0",
|
||||
"kotlin-compiler-1.7.20",
|
||||
"kotlin-compiler-1.8.0",
|
||||
"kotlin-compiler-1.9.0-Beta",
|
||||
"kotlin-compiler-1.9.20-Beta",
|
||||
@@ -234,10 +230,7 @@ use_repo(
|
||||
"kotlin-compiler-2.1.20-Beta1",
|
||||
"kotlin-compiler-2.2.0-Beta1",
|
||||
"kotlin-compiler-2.2.20-Beta2",
|
||||
"kotlin-compiler-embeddable-1.6.0",
|
||||
"kotlin-compiler-embeddable-1.6.20",
|
||||
"kotlin-compiler-embeddable-1.7.0",
|
||||
"kotlin-compiler-embeddable-1.7.20",
|
||||
"kotlin-compiler-2.3.0",
|
||||
"kotlin-compiler-embeddable-1.8.0",
|
||||
"kotlin-compiler-embeddable-1.9.0-Beta",
|
||||
"kotlin-compiler-embeddable-1.9.20-Beta",
|
||||
@@ -247,10 +240,7 @@ use_repo(
|
||||
"kotlin-compiler-embeddable-2.1.20-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.0-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.20-Beta2",
|
||||
"kotlin-stdlib-1.6.0",
|
||||
"kotlin-stdlib-1.6.20",
|
||||
"kotlin-stdlib-1.7.0",
|
||||
"kotlin-stdlib-1.7.20",
|
||||
"kotlin-compiler-embeddable-2.3.0",
|
||||
"kotlin-stdlib-1.8.0",
|
||||
"kotlin-stdlib-1.9.0-Beta",
|
||||
"kotlin-stdlib-1.9.20-Beta",
|
||||
@@ -260,6 +250,7 @@ use_repo(
|
||||
"kotlin-stdlib-2.1.20-Beta1",
|
||||
"kotlin-stdlib-2.2.0-Beta1",
|
||||
"kotlin-stdlib-2.2.20-Beta2",
|
||||
"kotlin-stdlib-2.3.0",
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.4.27
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a crash when analysing a `${{ ... }}` expression over around 300 characters in length.
|
||||
|
||||
## 0.4.26
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
5
actions/ql/lib/change-notes/released/0.4.27.md
Normal file
5
actions/ql/lib/change-notes/released/0.4.27.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.4.27
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a crash when analysing a `${{ ... }}` expression over around 300 characters in length.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.26
|
||||
lastReleaseVersion: 0.4.27
|
||||
|
||||
@@ -27,8 +27,8 @@ string getADelimitedExpression(YamlString s, int offset) {
|
||||
// not just the last (greedy match) or first (reluctant match).
|
||||
result =
|
||||
s.getValue()
|
||||
.regexpFind("\\$\\{\\{(?:[^}]|}(?!}))*\\}\\}", _, offset)
|
||||
.regexpCapture("(\\$\\{\\{(?:[^}]|}(?!}))*\\}\\})", 1)
|
||||
.regexpFind("\\$\\{\\{(?:[^}]|}(?!}))*+\\}\\}", _, offset)
|
||||
.regexpCapture("(\\$\\{\\{(?:[^}]|}(?!}))*+\\}\\})", 1)
|
||||
.trim()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.26
|
||||
version: 0.4.28-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.6.19
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.18
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
actions/ql/src/change-notes/released/0.6.19.md
Normal file
3
actions/ql/src/change-notes/released/0.6.19.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.19
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.18
|
||||
lastReleaseVersion: 0.6.19
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.18
|
||||
version: 0.6.20-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
1002
actions/ql/test/library-tests/very-long-expression/.github/workflows/very_long_expression_node.yml
vendored
Normal file
1002
actions/ql/test/library-tests/very-long-expression/.github/workflows/very_long_expression_node.yml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
| 97418 |
|
||||
@@ -0,0 +1,5 @@
|
||||
import codeql.actions.ast.internal.Ast
|
||||
|
||||
int getAnExpressionLength() { result = any(ExpressionImpl e).toString().length() }
|
||||
|
||||
select max(getAnExpressionLength())
|
||||
2483
cpp/downgrades/83100310bf73eefc37c1d8d0ac98b2ca3019c7b6/old.dbscheme
Normal file
2483
cpp/downgrades/83100310bf73eefc37c1d8d0ac98b2ca3019c7b6/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Sections for databaseMetadata and overlayChangedFiles
|
||||
compatibility: full
|
||||
2489
cpp/downgrades/9439176c1d1312787926458dd54d65a849069118/old.dbscheme
Normal file
2489
cpp/downgrades/9439176c1d1312787926458dd54d65a849069118/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
class PreprocessorDirective extends @preprocdirect {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_default {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from PreprocessorDirective ppd, int kind, int kind_new, Location l
|
||||
where
|
||||
preprocdirects(ppd, kind, l) and
|
||||
if kind = 17 then kind_new = /* ppd_warning */ 18 else kind_new = kind
|
||||
select ppd, kind_new, l
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Support embed preprocessor directive
|
||||
compatibility: partial
|
||||
embeds.rel: delete
|
||||
preprocdirects.rel: run preprocdirects.qlo
|
||||
@@ -1,3 +1,21 @@
|
||||
## 7.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a subclass `Embed` of `PreprocessorDirective` for C23 and C++26 `#embed` preprocessor directives.
|
||||
* Added modules `DataFlow::ParameterizedBarrierGuard` and `DataFlow::ParameterizedInstructionBarrierGuard`. These modules provide the same features as `DataFlow::BarrierGuard` and `DataFlow::InstructionBarrierGuard`, but allow for an additional parameter to support properly using them in dataflow configurations that uses flow states.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `Buffer.qll` library will no longer report incorrect buffer sizes on certain malformed databases. As a result, the queries `cpp/static-buffer-overflow`, `cpp/overflow-buffer`, `cpp/badly-bounded-write`, `cpp/overrunning-write`, `cpp/overrunning-write-with-float`, and `cpp/very-likely-overrunning-write` will report fewer false positives on such databases.
|
||||
* Added `taint` summary models and `sql-injection` barrier models for the MySQL `mysql_real_escape_string` and `mysql_real_escape_string_quote` escaping functions.
|
||||
* The predicate `SummarizedCallable.propagatesFlow` has been extended with the columns `Provenance p` and `boolean isExact`, and as a consequence the predicates `SummarizedCallable.hasProvenance` and `SummarizedCallable.hasExactModel` have been removed.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a bug in the `GuardCondition` library which sometimes prevented binary logical operators from being recognized as guard conditions. As a result, queries using `GuardCondition` may see improved results.
|
||||
* Fixed a bug which caused `Node.asDefinition()` to not have a result for certain assignments.
|
||||
|
||||
## 7.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added remote flow source models for the `winhttp.h` windows header and the Azure SDK core library for C/C++.
|
||||
17
cpp/ql/lib/change-notes/released/7.1.0.md
Normal file
17
cpp/ql/lib/change-notes/released/7.1.0.md
Normal file
@@ -0,0 +1,17 @@
|
||||
## 7.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a subclass `Embed` of `PreprocessorDirective` for C23 and C++26 `#embed` preprocessor directives.
|
||||
* Added modules `DataFlow::ParameterizedBarrierGuard` and `DataFlow::ParameterizedInstructionBarrierGuard`. These modules provide the same features as `DataFlow::BarrierGuard` and `DataFlow::InstructionBarrierGuard`, but allow for an additional parameter to support properly using them in dataflow configurations that uses flow states.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `Buffer.qll` library will no longer report incorrect buffer sizes on certain malformed databases. As a result, the queries `cpp/static-buffer-overflow`, `cpp/overflow-buffer`, `cpp/badly-bounded-write`, `cpp/overrunning-write`, `cpp/overrunning-write-with-float`, and `cpp/very-likely-overrunning-write` will report fewer false positives on such databases.
|
||||
* Added `taint` summary models and `sql-injection` barrier models for the MySQL `mysql_real_escape_string` and `mysql_real_escape_string_quote` escaping functions.
|
||||
* The predicate `SummarizedCallable.propagatesFlow` has been extended with the columns `Provenance p` and `boolean isExact`, and as a consequence the predicates `SummarizedCallable.hasProvenance` and `SummarizedCallable.hasExactModel` have been removed.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a bug in the `GuardCondition` library which sometimes prevented binary logical operators from being recognized as guard conditions. As a result, queries using `GuardCondition` may see improved results.
|
||||
* Fixed a bug which caused `Node.asDefinition()` to not have a result for certain assignments.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 7.0.0
|
||||
lastReleaseVersion: 7.1.0
|
||||
|
||||
14
cpp/ql/lib/ext/MySql.model.yml
Normal file
14
cpp/ql/lib/ext/MySql.model.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
# partial model of the MySQL api
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["", "", False, "mysql_real_escape_string", "", "", "Argument[*2]", "Argument[*1]", "taint", "manual"]
|
||||
- ["", "", False, "mysql_real_escape_string_quote", "", "", "Argument[*2]", "Argument[*1]", "taint", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: barrierModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
|
||||
- ["", "", False, "mysql_real_escape_string", "", "", "Argument[*1]", "sql-injection", "manual"]
|
||||
- ["", "", False, "mysql_real_escape_string_quote", "", "", "Argument[*1]", "sql-injection", "manual"]
|
||||
@@ -24,6 +24,13 @@ extensions:
|
||||
- ["", "", False, "MapViewOfFileNuma2", "", "", "ReturnValue[*]", "local", "manual"]
|
||||
# ntifs.h
|
||||
- ["", "", False, "NtReadFile", "", "", "Argument[*5]", "local", "manual"]
|
||||
# winhttp.h
|
||||
- ["", "", False, "WinHttpReadData", "", "", "Argument[*1]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpReadDataEx", "", "", "Argument[*1]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeaders", "", "", "Argument[*3]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*5]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*6]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[**8]", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
@@ -46,4 +53,6 @@ extensions:
|
||||
- ["", "", False, "RtlMoveMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
# winternl.h
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
# winhttp.h
|
||||
- ["", "", False, "WinHttpCrackUrl", "", "", "Argument[*0]", "Argument[*3]", "taint", "manual"]
|
||||
41
cpp/ql/lib/ext/azure.core.model.yml
Normal file
41
cpp/ql/lib/ext/azure.core.model.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: sourceModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
|
||||
- ["Azure::Core::Http", "RawResponse", True, "GetHeaders", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "RawResponse", True, "GetBody", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "RawResponse", True, "ExtractBodyStream", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetHeaders", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetHeader", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetBodyStream", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["Azure::Core", "Url", True, "Url", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetScheme", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetHost", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetPort", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetQueryParameters", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "AppendPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "AppendQueryParameter", "", "", "Argument[*1]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetHost", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetPath", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetPort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetScheme", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetRelativeUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetAbsoluteUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "Decode", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "Encode", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "Read", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "ReadToCount", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "ReadToEnd", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "Nullable", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
|
||||
- ["Azure", "Nullable", True, "Value", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator->", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator*", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 7.0.0
|
||||
version: 7.1.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -192,6 +192,15 @@ class Element extends ElementBase {
|
||||
*/
|
||||
predicate isAffectedByMacro() { affectedByMacro(this) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Holds if this element is affected by the expansion of `mi`.
|
||||
*/
|
||||
predicate isAffectedByMacro(MacroInvocation mi) {
|
||||
affectedbymacroexpansion(underlyingElement(this), unresolveElement(mi))
|
||||
}
|
||||
|
||||
private Element getEnclosingElementPref() {
|
||||
enclosingfunction(underlyingElement(this), unresolveElement(result)) or
|
||||
result.(Function) = stmtEnclosingElement(this) or
|
||||
|
||||
@@ -239,6 +239,9 @@ class MacroInvocation extends MacroAccess {
|
||||
macro_argument_unexpanded(underlyingElement(this), i, result)
|
||||
}
|
||||
|
||||
/** Gets the number of arguments for this macro invocation. */
|
||||
int getNumberOfArguments() { result = count(int i | exists(this.getUnexpandedArgument(i)) | i) }
|
||||
|
||||
/**
|
||||
* Gets the `i`th _expanded_ argument of this macro invocation, where the
|
||||
* first argument has `i = 0`. The result has been expanded for macros _and_
|
||||
|
||||
@@ -328,3 +328,27 @@ class PreprocessorPragma extends PreprocessorDirective, @ppd_pragma {
|
||||
class PreprocessorLine extends PreprocessorDirective, @ppd_line {
|
||||
override string toString() { result = "#line " + this.getHead() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C23 or C++26 `#embed` preprocessor directive. For example, the following code
|
||||
* contains one `Embed` directive:
|
||||
* ```cpp
|
||||
* char arr[] = {
|
||||
* #embed "bin"
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class Embed extends PreprocessorDirective, @ppd_embed {
|
||||
override string toString() { result = "#embed " + this.getIncludeText() }
|
||||
|
||||
/**
|
||||
* Gets the token which occurs after `#embed`, for example `"filename"`
|
||||
* or `<filename>`.
|
||||
*/
|
||||
string getIncludeText() { result = this.getHead() }
|
||||
|
||||
/**
|
||||
* Gets the file directly embedded by this `#embed`.
|
||||
*/
|
||||
File getEmbeddedFile() { embeds(underlyingElement(this), unresolveElement(result)) }
|
||||
}
|
||||
|
||||
@@ -62,11 +62,13 @@ private Class getRootType(FieldAccess fa) {
|
||||
* unspecified type of `v` is a `ReferenceType`.
|
||||
*/
|
||||
private int getVariableSize(Variable v) {
|
||||
exists(Type t |
|
||||
t = v.getUnspecifiedType() and
|
||||
not t instanceof ReferenceType and
|
||||
result = t.getSize()
|
||||
)
|
||||
result =
|
||||
unique(Type t |
|
||||
t = v.getUnspecifiedType() and
|
||||
not t instanceof ReferenceType
|
||||
|
|
||||
t.getSize()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,30 +81,32 @@ private int getSize(VariableAccess va) {
|
||||
not v instanceof Field and
|
||||
result = getVariableSize(v)
|
||||
or
|
||||
exists(Class c, int trueSize |
|
||||
// Otherwise, we find the "outermost" object and compute the size
|
||||
// as the difference between the size of the type of the "outermost
|
||||
// object" and the offset of the field relative to that type.
|
||||
// For example, consider the following structs:
|
||||
// ```
|
||||
// struct S {
|
||||
// uint32_t x;
|
||||
// uint32_t y;
|
||||
// };
|
||||
// struct S2 {
|
||||
// S s;
|
||||
// uint32_t z;
|
||||
// };
|
||||
// ```
|
||||
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
|
||||
// is the size of the base object type (i.e., `S2`) minutes the offset
|
||||
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
|
||||
// buffer is `12 - 4 = 8`.
|
||||
c = getRootType(va) and
|
||||
// we calculate the size based on the last field, to avoid including any padding after it
|
||||
trueSize = max(Field f | | f.getOffsetInClass(c) + getVariableSize(f)) and
|
||||
result = trueSize - v.(Field).getOffsetInClass(c)
|
||||
)
|
||||
result =
|
||||
unique(Class c, int trueSize |
|
||||
// Otherwise, we find the "outermost" object and compute the size
|
||||
// as the difference between the size of the type of the "outermost
|
||||
// object" and the offset of the field relative to that type.
|
||||
// For example, consider the following structs:
|
||||
// ```
|
||||
// struct S {
|
||||
// uint32_t x;
|
||||
// uint32_t y;
|
||||
// };
|
||||
// struct S2 {
|
||||
// S s;
|
||||
// uint32_t z;
|
||||
// };
|
||||
// ```
|
||||
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
|
||||
// is the size of the base object type (i.e., `S2`) minus the offset
|
||||
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
|
||||
// buffer is `12 - 4 = 8`.
|
||||
c = getRootType(va) and
|
||||
// we calculate the size based on the last field, to avoid including any padding after it
|
||||
trueSize = max(Field f | | f.getOffsetInClass(c) + getVariableSize(f))
|
||||
|
|
||||
trueSize - v.(Field).getOffsetInClass(c)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -116,12 +120,8 @@ private int isSource(Expr bufferExpr, Element why) {
|
||||
exists(Variable bufferVar | bufferVar = bufferExpr.(VariableAccess).getTarget() |
|
||||
// buffer is a fixed size array
|
||||
exists(bufferVar.getUnspecifiedType().(ArrayType).getSize()) and
|
||||
result =
|
||||
unique(int size | // more generous than .getSize() itself, when the array is a class field or similar.
|
||||
size = getSize(bufferExpr)
|
||||
|
|
||||
size
|
||||
) and
|
||||
// more generous than .getSize() itself, when the array is a class field or similar.
|
||||
result = getSize(bufferExpr) and
|
||||
why = bufferVar and
|
||||
not memberMayBeVarSize(_, bufferVar) and
|
||||
not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild*() = bufferExpr) and
|
||||
|
||||
@@ -8,7 +8,8 @@ import semmle.code.cpp.ir.IR
|
||||
private import codeql.util.Void
|
||||
private import codeql.controlflow.Guards as SharedGuards
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr as TE
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedFunction as TF
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
|
||||
|
||||
private class BasicBlock = IRCfg::BasicBlock;
|
||||
@@ -683,24 +684,26 @@ final class GuardCondition = GuardConditionImpl;
|
||||
*/
|
||||
private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl instanceof Cpp::BinaryLogicalOperation
|
||||
{
|
||||
GuardConditionImpl l;
|
||||
GuardConditionImpl r;
|
||||
|
||||
GuardConditionFromBinaryLogicalOperator() {
|
||||
super.getLeftOperand() = l and
|
||||
super.getRightOperand() = r
|
||||
}
|
||||
|
||||
override predicate valueControls(Cpp::BasicBlock controlled, GuardValue v) {
|
||||
exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs |
|
||||
this = binop and
|
||||
lhs = binop.getLeftOperand() and
|
||||
rhs = binop.getRightOperand() and
|
||||
lhs.valueControls(controlled, v) and
|
||||
rhs.valueControls(controlled, v)
|
||||
)
|
||||
// `l || r` does not control `r` even though `l` does.
|
||||
not r.(Cpp::Expr).getBasicBlock() = controlled and
|
||||
l.valueControls(controlled, v)
|
||||
or
|
||||
r.valueControls(controlled, v)
|
||||
}
|
||||
|
||||
override predicate valueControlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v) {
|
||||
exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs |
|
||||
this = binop and
|
||||
lhs = binop.getLeftOperand() and
|
||||
rhs = binop.getRightOperand() and
|
||||
lhs.valueControlsEdge(pred, succ, v) and
|
||||
rhs.valueControlsEdge(pred, succ, v)
|
||||
)
|
||||
l.valueControlsEdge(pred, succ, v)
|
||||
or
|
||||
r.valueControlsEdge(pred, succ, v)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -1026,7 +1029,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
|
||||
|
||||
private predicate excludeAsControlledInstruction(Instruction instr) {
|
||||
// Exclude the temporaries generated by a ternary expression.
|
||||
exists(TranslatedConditionalExpr tce |
|
||||
exists(TE::TranslatedConditionalExpr tce |
|
||||
instr = tce.getInstruction(ConditionValueFalseStoreTag())
|
||||
or
|
||||
instr = tce.getInstruction(ConditionValueTrueStoreTag())
|
||||
@@ -1038,6 +1041,14 @@ private predicate excludeAsControlledInstruction(Instruction instr) {
|
||||
or
|
||||
// Exclude unreached instructions, as their AST is the whole function and not a block.
|
||||
instr instanceof UnreachedInstruction
|
||||
or
|
||||
// Exclude instructions generated by a translated function as they map to the function itself
|
||||
// and the function is considered the last basic block of a function body.
|
||||
any(TF::TranslatedFunction tf).getInstruction(_) = instr
|
||||
or
|
||||
// `ChiInstruction`s generated by instructions in the above case don't come from `getInstruction` (since they are generated by AliasedSSA)
|
||||
// so we need to special case them.
|
||||
excludeAsControlledInstruction(instr.(ChiInstruction).getPartial())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
|
||||
import cpp
|
||||
private import new.DataFlow
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as Private
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import internal.FlowSummaryImpl
|
||||
@@ -367,6 +368,8 @@ private predicate elementSpec(
|
||||
) {
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
|
||||
barrierModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
|
||||
barrierGuardModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
|
||||
}
|
||||
|
||||
@@ -1028,6 +1031,84 @@ private module Cached {
|
||||
isSinkNode(n, kind, model) and n.asNode() = node
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TKindModelPair =
|
||||
TMkPair(string kind, string model) { isBarrierGuardNode(_, _, kind, model) }
|
||||
|
||||
private GuardValue convertAcceptingValue(Public::AcceptingValue av) {
|
||||
av.isTrue() and result.asBooleanValue() = true
|
||||
or
|
||||
av.isFalse() and result.asBooleanValue() = false
|
||||
or
|
||||
// NOTE: The below cases don't contribute anything currently since the
|
||||
// callers immediately use `.asBooleanValue()` to convert the `GuardValue`
|
||||
// to a boolean. Once we're willing to accept the breaking change of
|
||||
// converting the barrier guard API to use `GuardValue`s instead `Boolean`s
|
||||
// we can remove this restriction.
|
||||
av.isNoException() and result.getDualValue().isThrowsException()
|
||||
or
|
||||
av.isZero() and result.asIntValue() = 0
|
||||
or
|
||||
av.isNotZero() and result.getDualValue().asIntValue() = 0
|
||||
or
|
||||
av.isNull() and result.isNullValue()
|
||||
or
|
||||
av.isNotNull() and result.isNonNullValue()
|
||||
}
|
||||
|
||||
private predicate barrierGuardChecks(IRGuardCondition g, Expr e, boolean gv, TKindModelPair kmp) {
|
||||
exists(
|
||||
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingvalue,
|
||||
string kind, string model
|
||||
|
|
||||
isBarrierGuardNode(n, acceptingvalue, kind, model) and
|
||||
n.asNode().asExpr() = e and
|
||||
kmp = TMkPair(kind, model) and
|
||||
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
|
||||
n.asNode().(Private::ArgumentNode).getCall().asCallInstruction() = g
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TKindModelPairIntPair =
|
||||
MkKindModelPairIntPair(TKindModelPair pair, int indirectionIndex) {
|
||||
indirectionIndex > 0 and
|
||||
Private::nodeHasInstruction(_, _, indirectionIndex) and
|
||||
exists(pair)
|
||||
}
|
||||
|
||||
private predicate indirectBarrierGuardChecks(
|
||||
IRGuardCondition g, Expr e, boolean gv, TKindModelPairIntPair kmp
|
||||
) {
|
||||
exists(
|
||||
SourceSinkInterpretationInput::InterpretNode interpretNode,
|
||||
Public::AcceptingValue acceptingvalue, string kind, string model, int indirectionIndex,
|
||||
Private::ArgumentNode arg
|
||||
|
|
||||
isBarrierGuardNode(interpretNode, acceptingvalue, kind, model) and
|
||||
arg = interpretNode.asNode() and
|
||||
arg.asIndirectExpr(indirectionIndex) = e and
|
||||
kmp = MkKindModelPairIntPair(TMkPair(kind, model), indirectionIndex) and
|
||||
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
|
||||
arg.getCall().asCallInstruction() = g
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
|
||||
* model.
|
||||
*/
|
||||
cached
|
||||
predicate barrierNode(DataFlow::Node node, string kind, string model) {
|
||||
exists(SourceSinkInterpretationInput::InterpretNode n |
|
||||
isBarrierNode(n, kind, model) and n.asNode() = node
|
||||
)
|
||||
or
|
||||
DataFlow::ParameterizedBarrierGuard<TKindModelPair, barrierGuardChecks/4>::getABarrierNode(TMkPair(kind,
|
||||
model)) = node
|
||||
or
|
||||
DataFlow::ParameterizedBarrierGuard<TKindModelPairIntPair, indirectBarrierGuardChecks/4>::getAnIndirectBarrierNode(MkKindModelPairIntPair(TMkPair(kind,
|
||||
model), _)) = node
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
@@ -1044,6 +1125,12 @@ predicate sourceNode(DataFlow::Node node, string kind) { sourceNode(node, kind,
|
||||
*/
|
||||
predicate sinkNode(DataFlow::Node node, string kind) { sinkNode(node, kind, _) }
|
||||
|
||||
/**
|
||||
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
|
||||
* model.
|
||||
*/
|
||||
predicate barrierNode(DataFlow::Node node, string kind) { barrierNode(node, kind, _) }
|
||||
|
||||
private predicate interpretSummary(
|
||||
Function f, string input, string output, string kind, string provenance, string model
|
||||
) {
|
||||
@@ -1058,40 +1145,22 @@ private predicate interpretSummary(
|
||||
|
||||
// adapter class for converting Mad summaries to `SummarizedCallable`s
|
||||
private class SummarizedCallableAdapter extends SummarizedCallable {
|
||||
SummarizedCallableAdapter() { interpretSummary(this, _, _, _, _, _) }
|
||||
string input_;
|
||||
string output_;
|
||||
string kind;
|
||||
Provenance p_;
|
||||
string model_;
|
||||
|
||||
private predicate relevantSummaryElementManual(
|
||||
string input, string output, string kind, string model
|
||||
) {
|
||||
exists(Provenance provenance |
|
||||
interpretSummary(this, input, output, kind, provenance, model) and
|
||||
provenance.isManual()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
string input, string output, string kind, string model
|
||||
) {
|
||||
exists(Provenance provenance |
|
||||
interpretSummary(this, input, output, kind, provenance, model) and
|
||||
provenance.isGenerated()
|
||||
)
|
||||
}
|
||||
SummarizedCallableAdapter() { interpretSummary(this, input_, output_, kind, p_, model_) }
|
||||
|
||||
override predicate propagatesFlow(
|
||||
string input, string output, boolean preservesValue, string model
|
||||
string input, string output, boolean preservesValue, Provenance p, boolean isExact, string model
|
||||
) {
|
||||
exists(string kind |
|
||||
this.relevantSummaryElementManual(input, output, kind, model)
|
||||
or
|
||||
not this.relevantSummaryElementManual(_, _, _, _) and
|
||||
this.relevantSummaryElementGenerated(input, output, kind, model)
|
||||
|
|
||||
if kind = "value" then preservesValue = true else preservesValue = false
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasProvenance(Provenance provenance) {
|
||||
interpretSummary(this, _, _, _, provenance, _)
|
||||
input = input_ and
|
||||
output = output_ and
|
||||
(if kind = "value" then preservesValue = true else preservesValue = false) and
|
||||
p = p_ and
|
||||
isExact = true and
|
||||
model = model_
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
|
||||
|
||||
class SinkBase = Void;
|
||||
|
||||
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getBlock()) }
|
||||
|
||||
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
|
||||
|
||||
ReturnKind getStandardReturnValueKind() { result = getReturnValueKind("") }
|
||||
@@ -149,16 +151,27 @@ module SourceSinkInterpretationInput implements
|
||||
}
|
||||
|
||||
predicate barrierElement(
|
||||
Element n, string output, string kind, Public::Provenance provenance, string model
|
||||
Element e, string output, string kind, Public::Provenance provenance, string model
|
||||
) {
|
||||
none()
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
barrierModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
predicate barrierGuardElement(
|
||||
Element n, string input, Public::AcceptingValue acceptingvalue, string kind,
|
||||
Element e, string input, Public::AcceptingValue acceptingvalue, string kind,
|
||||
Public::Provenance provenance, string model
|
||||
) {
|
||||
none()
|
||||
exists(
|
||||
string package, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingvalue, kind,
|
||||
provenance, model) and
|
||||
e = interpretElement(package, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TInterpretNode =
|
||||
|
||||
@@ -23,7 +23,7 @@ class Expr extends StmtParent, @expr {
|
||||
predicate hasChild(Expr e, int n) { e = this.getChild(n) }
|
||||
|
||||
/** Gets the enclosing function of this expression, if any. */
|
||||
Function getEnclosingFunction() { result = exprEnclosingElement(this) }
|
||||
override Function getEnclosingFunction() { result = exprEnclosingElement(this) }
|
||||
|
||||
/** Gets the nearest enclosing set of curly braces around this expression in the source, if any. */
|
||||
BlockStmt getEnclosingBlock() { result = this.getEnclosingStmt().getEnclosingBlock() }
|
||||
|
||||
@@ -45,13 +45,13 @@ private string getSingleLocationFilePath(@element e) {
|
||||
overlay[local]
|
||||
private string getMultiLocationFilePath(@element e) {
|
||||
exists(@location_default loc |
|
||||
exists(@var_decl vd | var_decls(vd, e, _, _, loc))
|
||||
var_decls(_, e, _, _, loc)
|
||||
or
|
||||
exists(@fun_decl fd | fun_decls(fd, e, _, _, loc))
|
||||
fun_decls(_, e, _, _, loc)
|
||||
or
|
||||
exists(@type_decl td | type_decls(td, e, loc))
|
||||
type_decls(_, e, loc)
|
||||
or
|
||||
exists(@namespace_decl nd | namespace_decls(nd, e, loc, _))
|
||||
namespace_decls(_, e, loc, _)
|
||||
|
|
||||
result = getLocationFilePath(loc)
|
||||
)
|
||||
@@ -62,19 +62,29 @@ private string getMultiLocationFilePath(@element e) {
|
||||
* overlay variant.
|
||||
*/
|
||||
overlay[local]
|
||||
private predicate holdsInBase() { not isOverlay() }
|
||||
private predicate isBase() { not isOverlay() }
|
||||
|
||||
/**
|
||||
* Holds if `path` was extracted in the overlay database.
|
||||
*/
|
||||
overlay[local]
|
||||
private predicate overlayHasFile(string path) {
|
||||
isOverlay() and
|
||||
files(_, path) and
|
||||
path != ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards an element from the base variant if:
|
||||
* - It has a single location in a changed file, or
|
||||
* - All of its locations are in changed files.
|
||||
* - It has a single location in a file extracted in the overlay, or
|
||||
* - All of its locations are in files extracted in the overlay.
|
||||
*/
|
||||
overlay[discard_entity]
|
||||
private predicate discardElement(@element e) {
|
||||
holdsInBase() and
|
||||
isBase() and
|
||||
(
|
||||
overlayChangedFiles(getSingleLocationFilePath(e))
|
||||
overlayHasFile(getSingleLocationFilePath(e))
|
||||
or
|
||||
forex(string path | path = getMultiLocationFilePath(e) | overlayChangedFiles(path))
|
||||
forex(string path | path = getMultiLocationFilePath(e) | overlayHasFile(path))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1144,7 +1144,7 @@ private newtype TDataFlowCall =
|
||||
}
|
||||
|
||||
private predicate summarizedCallableIsManual(SummarizedCallable sc) {
|
||||
sc.asSummarizedCallable().applyManualModel()
|
||||
sc.asSummarizedCallable().hasManualModel()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -312,6 +312,13 @@ class Node extends TIRDataFlowNode {
|
||||
*/
|
||||
Expr asDefinition() { result = this.asDefinition(_) }
|
||||
|
||||
private predicate isCertainStore() {
|
||||
exists(SsaImpl::Definition def |
|
||||
SsaImpl::defToNode(this, def, _) and
|
||||
def.isCertain()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition associated with this node, if any.
|
||||
*
|
||||
@@ -361,11 +368,10 @@ class Node extends TIRDataFlowNode {
|
||||
* pointed to by `p`.
|
||||
*/
|
||||
Expr asDefinition(boolean uncertain) {
|
||||
exists(StoreInstruction store, SsaImpl::Definition def |
|
||||
exists(StoreInstruction store |
|
||||
store = this.asInstruction() and
|
||||
result = asDefinitionImpl(store) and
|
||||
SsaImpl::defToNode(this, def, _) and
|
||||
if def.isCertain() then uncertain = false else uncertain = true
|
||||
if this.isCertainStore() then uncertain = false else uncertain = true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2417,6 +2423,19 @@ class ContentSet instanceof Content {
|
||||
}
|
||||
}
|
||||
|
||||
private signature class ParamSig;
|
||||
|
||||
private module WithParam<ParamSig P> {
|
||||
/**
|
||||
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||
*
|
||||
* The expression `e` is expected to be a syntactic part of the guard `g`.
|
||||
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
|
||||
* the argument `x`.
|
||||
*/
|
||||
signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch, P param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||
*
|
||||
@@ -2438,7 +2457,7 @@ private predicate controls(IRGuardCondition g, Node n, boolean edge) {
|
||||
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
module ParameterizedBarrierGuard<ParamSig P, WithParam<P>::guardChecksSig/4 guardChecks> {
|
||||
bindingset[value, n]
|
||||
pragma[inline_late]
|
||||
private predicate convertedExprHasValueNumber(ValueNumber value, Node n) {
|
||||
@@ -2448,12 +2467,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch) {
|
||||
guardChecks(g, n.asOperand().getDef().getConvertedResultExpression(), branch)
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch, P p) {
|
||||
guardChecks(g, n.asOperand().getDef().getConvertedResultExpression(), branch, p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression node that is safely guarded by the given guard check.
|
||||
* Gets an expression node that is safely guarded by the given guard check
|
||||
* when the parameter is `p`.
|
||||
*
|
||||
* For example, given the following code:
|
||||
* ```cpp
|
||||
@@ -2484,19 +2504,27 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
*
|
||||
* NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
|
||||
*/
|
||||
Node getABarrierNode() {
|
||||
Node getABarrierNode(P p) {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
convertedExprHasValueNumber(value, result) and
|
||||
guardChecks(g,
|
||||
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and
|
||||
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge, p) and
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
result = SsaImpl::BarrierGuard<P, guardChecksNode/4>::getABarrierNode(p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node that is safely guarded by the given guard check.
|
||||
* Gets an expression node that is safely guarded by the given guard check.
|
||||
*
|
||||
* See `getABarrierNode/1` for examples.
|
||||
*/
|
||||
Node getABarrierNode() { result = getABarrierNode(_) }
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node that is safely guarded by the given
|
||||
* guard check with parameter `p`.
|
||||
*
|
||||
* For example, given the following code:
|
||||
* ```cpp
|
||||
@@ -2528,6 +2556,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
*
|
||||
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(P p) { result = getAnIndirectBarrierNode(_, p) }
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node that is safely guarded by the given guard check.
|
||||
*
|
||||
* See `getAnIndirectBarrierNode/1` for examples.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
|
||||
|
||||
bindingset[value, n]
|
||||
@@ -2542,10 +2577,10 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
}
|
||||
|
||||
private predicate guardChecksIndirectNode(
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex, P p
|
||||
) {
|
||||
guardChecks(g, n.asIndirectOperand(indirectionIndex).getDef().getConvertedResultExpression(),
|
||||
branch)
|
||||
branch, p)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2582,19 +2617,44 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
*
|
||||
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex) {
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex, P p) {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
indirectConvertedExprHasValueNumber(indirectionIndex, value, result) and
|
||||
guardChecks(g,
|
||||
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and
|
||||
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge, p) and
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result =
|
||||
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
SsaImpl::BarrierGuardWithIntParam<P, guardChecksIndirectNode/5>::getABarrierNode(indirectionIndex,
|
||||
p)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a set of barrier nodes for a guard that validates an expression.
|
||||
*
|
||||
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
private predicate guardChecks(IRGuardCondition g, Expr e, boolean branch, Unit unit) {
|
||||
guardChecks(g, e, branch) and
|
||||
exists(unit)
|
||||
}
|
||||
|
||||
import ParameterizedBarrierGuard<Unit, guardChecks/4>
|
||||
}
|
||||
|
||||
private module InstrWithParam<ParamSig P> {
|
||||
/**
|
||||
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
|
||||
*/
|
||||
signature predicate instructionGuardChecksSig(
|
||||
IRGuardCondition g, Instruction instr, boolean branch, P p
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
|
||||
*/
|
||||
@@ -2606,7 +2666,9 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
|
||||
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
|
||||
module ParameterizedInstructionBarrierGuard<
|
||||
ParamSig P, InstrWithParam<P>::instructionGuardChecksSig/4 instructionGuardChecks>
|
||||
{
|
||||
bindingset[value, n]
|
||||
pragma[inline_late]
|
||||
private predicate operandHasValueNumber(ValueNumber value, Node n) {
|
||||
@@ -2616,21 +2678,27 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch) {
|
||||
instructionGuardChecks(g, n.asOperand().getDef(), branch)
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch, P p) {
|
||||
instructionGuardChecks(g, n.asOperand().getDef(), branch, p)
|
||||
}
|
||||
|
||||
/** Gets a node that is safely guarded by the given guard check. */
|
||||
Node getABarrierNode() {
|
||||
/**
|
||||
* Gets a node that is safely guarded by the given guard check with
|
||||
* parameter `p`.
|
||||
*/
|
||||
Node getABarrierNode(P p) {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and
|
||||
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge, p) and
|
||||
operandHasValueNumber(value, result) and
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
result = SsaImpl::BarrierGuard<P, guardChecksNode/4>::getABarrierNode(p)
|
||||
}
|
||||
|
||||
/** Gets a node that is safely guarded by the given guard check. */
|
||||
Node getABarrierNode() { result = getABarrierNode(_) }
|
||||
|
||||
bindingset[value, n]
|
||||
pragma[inline_late]
|
||||
private predicate indirectOperandHasValueNumber(ValueNumber value, int indirectionIndex, Node n) {
|
||||
@@ -2641,25 +2709,52 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
}
|
||||
|
||||
private predicate guardChecksIndirectNode(
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex, P p
|
||||
) {
|
||||
instructionGuardChecks(g, n.asIndirectOperand(indirectionIndex).getDef(), branch)
|
||||
instructionGuardChecks(g, n.asIndirectOperand(indirectionIndex).getDef(), branch, p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect node with indirection index `indirectionIndex` that is
|
||||
* safely guarded by the given guard check.
|
||||
* safely guarded by the given guard check with parameter `p`.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex) {
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex, P p) {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and
|
||||
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge, p) and
|
||||
indirectOperandHasValueNumber(value, indirectionIndex, result) and
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result =
|
||||
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
SsaImpl::BarrierGuardWithIntParam<P, guardChecksIndirectNode/5>::getABarrierNode(indirectionIndex,
|
||||
p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect node that is safely guarded by the given guard check
|
||||
* with parameter `p`.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(P p) { result = getAnIndirectBarrierNode(_, p) }
|
||||
|
||||
/** Gets an indirect node that is safely guarded by the given guard check. */
|
||||
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a set of barrier nodes for a guard that validates an instruction.
|
||||
*
|
||||
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
|
||||
private predicate instructionGuardChecks(
|
||||
IRGuardCondition g, Instruction i, boolean branch, Unit unit
|
||||
) {
|
||||
instructionGuardChecks(g, i, branch) and
|
||||
exists(unit)
|
||||
}
|
||||
|
||||
import ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,17 +15,79 @@ private import DataFlowPrivate
|
||||
import SsaImplCommon
|
||||
|
||||
private module SourceVariables {
|
||||
/**
|
||||
* Holds if `store` is the `StoreInstruction` generated by a postfix
|
||||
* increment or decrement operation `e`, and `postCrement` is the operand
|
||||
* that represents the use of the evaluated value of `e`.
|
||||
*/
|
||||
private predicate isUseAfterPostfixCrement0(StoreInstruction store, Operand postCrement) {
|
||||
exists(
|
||||
BinaryInstruction binary, IRBlock b, int iPre, int iPost, int iStore, Operand preCrement,
|
||||
Instruction left
|
||||
|
|
||||
binary instanceof AddInstruction
|
||||
or
|
||||
binary instanceof PointerAddInstruction
|
||||
or
|
||||
binary instanceof SubInstruction
|
||||
or
|
||||
binary instanceof PointerSubInstruction
|
||||
|
|
||||
store.getSourceValue() = binary and
|
||||
left = binary.getLeft() and
|
||||
strictcount(left.getAUse()) = 2 and
|
||||
left.getAUse() = preCrement and
|
||||
left.getAUse() = postCrement and
|
||||
b.getInstruction(iPre) = preCrement.getUse() and
|
||||
b.getInstruction(iPost) = postCrement.getUse() and
|
||||
b.getInstruction(iStore) = store and
|
||||
iPre < iStore and
|
||||
iStore < iPost
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `store` is the `StoreInstruction` generated by an postfix
|
||||
* increment or decrement operation `e`, and `postCrement` is the fully
|
||||
* converted operand that represents the use of the evaluated value of `e`.
|
||||
*/
|
||||
private predicate isUseAfterPostfixCrement(StoreInstruction store, Operand postCrement) {
|
||||
isUseAfterPostfixCrement0(store, postCrement) and
|
||||
conversionFlow(postCrement, _, false, _)
|
||||
or
|
||||
exists(Instruction instr, Operand postCrement0 |
|
||||
isUseAfterPostfixCrement(store, postCrement0) and
|
||||
conversionFlow(postCrement0, instr, false, _) and
|
||||
instr = postCrement.getDef()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate hasSavedPostfixCrementSourceVariable(
|
||||
BaseSourceVariable base, StoreInstruction store, int ind
|
||||
) {
|
||||
exists(BaseSourceVariableInstruction inst, int ind0 |
|
||||
isUseAfterPostfixCrement(store, _) and
|
||||
inst.getBaseSourceVariable() = base and
|
||||
isDef(_, _, store.getDestinationAddressOperand(), inst, ind0, 0) and
|
||||
ind = [ind0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
private newtype TSourceVariable =
|
||||
TMkSourceVariable(BaseSourceVariable base, int ind) {
|
||||
TNormalSourceVariable(BaseSourceVariable base, int ind) {
|
||||
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||
} or
|
||||
TSavedPostfixCrementSourceVariable(StoreInstruction store, int ind) {
|
||||
hasSavedPostfixCrementSourceVariable(_, store, ind)
|
||||
}
|
||||
|
||||
class SourceVariable extends TSourceVariable {
|
||||
abstract private class AbstractSourceVariable extends TSourceVariable {
|
||||
BaseSourceVariable base;
|
||||
int ind;
|
||||
|
||||
SourceVariable() { this = TMkSourceVariable(base, ind) }
|
||||
bindingset[ind]
|
||||
AbstractSourceVariable() { any() }
|
||||
|
||||
/** Gets the IR variable associated with this `SourceVariable`, if any. */
|
||||
IRVariable getIRVariable() { result = base.(BaseIRVariable).getIRVariable() }
|
||||
@@ -37,7 +99,7 @@ private module SourceVariables {
|
||||
BaseSourceVariable getBaseVariable() { result = base }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = repeatStars(this.getIndirection()) + base.toString() }
|
||||
abstract string toString();
|
||||
|
||||
/**
|
||||
* Gets the number of loads performed on the base source variable
|
||||
@@ -62,6 +124,53 @@ private module SourceVariables {
|
||||
/** Gets the location of this variable. */
|
||||
Location getLocation() { result = this.getBaseVariable().getLocation() }
|
||||
}
|
||||
|
||||
final class SourceVariable = AbstractSourceVariable;
|
||||
|
||||
/**
|
||||
* A regular source variable. Most source variables are instances of this
|
||||
* class.
|
||||
*/
|
||||
class NormalSourceVariable extends AbstractSourceVariable, TNormalSourceVariable {
|
||||
NormalSourceVariable() { this = TNormalSourceVariable(base, ind) }
|
||||
|
||||
final override string toString() {
|
||||
result = repeatStars(this.getIndirection()) + base.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Before a value is postfix incremented (or decremented) we "save" its
|
||||
* current value so that the pre-incremented value can be returned to the
|
||||
* enclosing expression. We use the source variables represented by this
|
||||
* class to represent the "saved value".
|
||||
*/
|
||||
class SavedPostfixCrementSourceVariable extends AbstractSourceVariable,
|
||||
TSavedPostfixCrementSourceVariable
|
||||
{
|
||||
StoreInstruction store;
|
||||
|
||||
SavedPostfixCrementSourceVariable() {
|
||||
this = TSavedPostfixCrementSourceVariable(store, ind) and
|
||||
hasSavedPostfixCrementSourceVariable(base, store, ind)
|
||||
}
|
||||
|
||||
final override string toString() {
|
||||
result = repeatStars(this.getIndirection()) + base.toString() + " [before crement]"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `StoreInstruction` that writes the incremented (or decremented)
|
||||
* value.
|
||||
*/
|
||||
StoreInstruction getStoreInstruction() { result = store }
|
||||
|
||||
/**
|
||||
* Gets the fully converted `Operand` that represents the use of the
|
||||
* value before the increment.
|
||||
*/
|
||||
Operand getOperand() { isUseAfterPostfixCrement(store, result) }
|
||||
}
|
||||
}
|
||||
|
||||
import SourceVariables
|
||||
@@ -109,17 +218,43 @@ private newtype TDefImpl =
|
||||
TDirectDefImpl(Operand address, int indirectionIndex) {
|
||||
isDef(_, _, address, _, _, indirectionIndex)
|
||||
} or
|
||||
TSavedPostfixCrementDefImpl(SavedPostfixCrementSourceVariable sv, int indirectionIndex) {
|
||||
isDef(_, _, sv.getStoreInstruction().getDestinationAddressOperand(), _, sv.getIndirection(),
|
||||
indirectionIndex)
|
||||
} or
|
||||
TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
|
||||
// Represents the initial "definition" of a global variable when entering
|
||||
// a function body.
|
||||
isGlobalDefImpl(v, f, _, indirectionIndex)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasOperandAndIndirection(
|
||||
SavedPostfixCrementSourceVariable sv, Operand operand, int indirection
|
||||
) {
|
||||
sv.getOperand() = operand and
|
||||
sv.getIndirection() = indirection
|
||||
}
|
||||
|
||||
private predicate hasBeforePostCrementUseImpl(
|
||||
SavedPostfixCrementSourceVariable sv, Operand operand, int indirectionIndex
|
||||
) {
|
||||
not isDef(true, _, operand, _, _, _) and
|
||||
exists(int indirection |
|
||||
hasOperandAndIndirection(sv, operand, indirection) and
|
||||
isUse(_, operand, _, indirection, indirectionIndex)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
private newtype TUseImpl =
|
||||
TDirectUseImpl(Operand operand, int indirectionIndex) {
|
||||
isUse(_, operand, _, _, indirectionIndex) and
|
||||
not isDef(true, _, operand, _, _, _)
|
||||
not isDef(true, _, operand, _, _, _) and
|
||||
not hasBeforePostCrementUseImpl(_, operand, indirectionIndex)
|
||||
} or
|
||||
TSavedPostfixCrementUseImpl(SavedPostfixCrementSourceVariable sv, int indirectionIndex) {
|
||||
hasBeforePostCrementUseImpl(sv, _, indirectionIndex)
|
||||
} or
|
||||
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
|
||||
// Represents a final "use" of a global variable to ensure that
|
||||
@@ -223,19 +358,8 @@ abstract class DefImpl extends TDefImpl {
|
||||
*/
|
||||
abstract int getIndirection();
|
||||
|
||||
/**
|
||||
* Gets the base source variable (i.e., the variable without
|
||||
* any indirection) of this definition or use.
|
||||
*/
|
||||
abstract BaseSourceVariable getBaseSourceVariable();
|
||||
|
||||
/** Gets the variable that is defined or used. */
|
||||
SourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
defHasSourceVariable(this, v, indirection)
|
||||
)
|
||||
}
|
||||
abstract SourceVariable getSourceVariable();
|
||||
|
||||
/**
|
||||
* Holds if this definition is guaranteed to totally overwrite the
|
||||
@@ -243,8 +367,8 @@ abstract class DefImpl extends TDefImpl {
|
||||
*/
|
||||
abstract predicate isCertain();
|
||||
|
||||
/** Gets the value written to the destination variable by this definition. */
|
||||
abstract Node0Impl getValue();
|
||||
/** Gets the value written to the destination variable by this definition, if any. */
|
||||
Node0Impl getValue() { none() }
|
||||
|
||||
/** Gets the operand that represents the address of this definition, if any. */
|
||||
Operand getAddressOperand() { none() }
|
||||
@@ -293,19 +417,8 @@ abstract class UseImpl extends TUseImpl {
|
||||
/** Gets the indirection index of this use. */
|
||||
final int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
/**
|
||||
* Gets the base source variable (i.e., the variable without
|
||||
* any indirection) of this definition or use.
|
||||
*/
|
||||
abstract BaseSourceVariable getBaseSourceVariable();
|
||||
|
||||
/** Gets the variable that is defined or used. */
|
||||
SourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
useHasSourceVariable(this, v, indirection)
|
||||
)
|
||||
}
|
||||
abstract SourceVariable getSourceVariable();
|
||||
|
||||
/**
|
||||
* Holds if this use is guaranteed to read the
|
||||
@@ -314,18 +427,6 @@ abstract class UseImpl extends TUseImpl {
|
||||
abstract predicate isCertain();
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate defHasSourceVariable(DefImpl def, BaseSourceVariable bv, int ind) {
|
||||
bv = def.getBaseSourceVariable() and
|
||||
ind = def.getIndirection()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate useHasSourceVariable(UseImpl use, BaseSourceVariable bv, int ind) {
|
||||
bv = use.getBaseSourceVariable() and
|
||||
ind = use.getIndirection()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate sourceVariableHasBaseAndIndex(SourceVariable v, BaseSourceVariable bv, int ind) {
|
||||
v.getBaseVariable() = bv and
|
||||
@@ -358,16 +459,12 @@ abstract private class DefAddressImpl extends DefImpl, TDefAddressImpl {
|
||||
|
||||
final override predicate isCertain() { any() }
|
||||
|
||||
final override Node0Impl getValue() { none() }
|
||||
|
||||
override Cpp::Location getLocation() { result = v.getLocation() }
|
||||
|
||||
final override SourceVariable getSourceVariable() {
|
||||
final override NormalSourceVariable getSourceVariable() {
|
||||
result.getBaseVariable() = v and
|
||||
result.getIndirection() = 0
|
||||
}
|
||||
|
||||
final override BaseSourceVariable getBaseSourceVariable() { result = v }
|
||||
}
|
||||
|
||||
private class DefVariableAddressImpl extends DefAddressImpl {
|
||||
@@ -413,8 +510,17 @@ private class DirectDef extends DefImpl, TDirectDefImpl {
|
||||
isDef(_, _, address, result, _, indirectionIndex)
|
||||
}
|
||||
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
result = this.getBase().getBaseSourceVariable()
|
||||
pragma[nomagic]
|
||||
private predicate hasBaseSourceVariableAndIndirection(BaseSourceVariable v, int indirection) {
|
||||
v = this.getBase().getBaseSourceVariable() and
|
||||
indirection = this.getIndirection()
|
||||
}
|
||||
|
||||
final override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
this.hasBaseSourceVariableAndIndirection(v, indirection)
|
||||
)
|
||||
}
|
||||
|
||||
override int getIndirection() { isDef(_, _, address, _, result, indirectionIndex) }
|
||||
@@ -424,6 +530,32 @@ private class DirectDef extends DefImpl, TDirectDefImpl {
|
||||
override predicate isCertain() { isDef(true, _, address, _, _, indirectionIndex) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A definition that "saves" the value of a variable before it is incremented
|
||||
* or decremented.
|
||||
*/
|
||||
private class SavedPostfixCrementDefImpl extends DefImpl, TSavedPostfixCrementDefImpl {
|
||||
SavedPostfixCrementSourceVariable sv;
|
||||
|
||||
SavedPostfixCrementDefImpl() { this = TSavedPostfixCrementDefImpl(sv, indirectionIndex) }
|
||||
|
||||
override Cpp::Location getLocation() { result = sv.getStoreInstruction().getLocation() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
sv.getStoreInstruction() = block.getInstruction(index)
|
||||
}
|
||||
|
||||
override string toString() { result = "Def of " + this.getSourceVariable() }
|
||||
|
||||
override SourceVariable getSourceVariable() { result = sv }
|
||||
|
||||
override int getIndirection() { result = sv.getIndirection() }
|
||||
|
||||
override predicate isCertain() {
|
||||
isDef(true, _, sv.getStoreInstruction().getDestinationAddressOperand(), _, _, indirectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
private class DirectUseImpl extends UseImpl, TDirectUseImpl {
|
||||
Operand operand;
|
||||
|
||||
@@ -432,29 +564,22 @@ private class DirectUseImpl extends UseImpl, TDirectUseImpl {
|
||||
override string toString() { result = "Use of " + this.getSourceVariable() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
// See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
|
||||
// predicate's implementation.
|
||||
if this.getBase().getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
|
||||
then
|
||||
exists(Operand op, int indirection, Instruction base |
|
||||
indirection = this.getIndirection() and
|
||||
base = this.getBase() and
|
||||
op =
|
||||
min(Operand cand, int i |
|
||||
isUse(_, cand, base, indirection, indirectionIndex) and
|
||||
block.getInstruction(i) = cand.getUse()
|
||||
|
|
||||
cand order by i
|
||||
) and
|
||||
block.getInstruction(index) = op.getUse()
|
||||
)
|
||||
else operand.getUse() = block.getInstruction(index)
|
||||
operand.getUse() = block.getInstruction(index)
|
||||
}
|
||||
|
||||
private BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, indirectionIndex) }
|
||||
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
result = this.getBase().getBaseSourceVariable()
|
||||
pragma[nomagic]
|
||||
private predicate hasBaseSourceVariableAndIndirection(BaseSourceVariable bv, int indirection) {
|
||||
this.getBase().getBaseSourceVariable() = bv and
|
||||
this.getIndirection() = indirection
|
||||
}
|
||||
|
||||
override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
this.hasBaseSourceVariableAndIndirection(v, indirection)
|
||||
)
|
||||
}
|
||||
|
||||
final Operand getOperand() { result = operand }
|
||||
@@ -468,6 +593,34 @@ private class DirectUseImpl extends UseImpl, TDirectUseImpl {
|
||||
override Node getNode() { nodeHasOperand(result, operand, indirectionIndex) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of the original "saved" variable after the variable has been incremented
|
||||
* or decremented.
|
||||
*/
|
||||
private class SavedPostfixCrementUseImpl extends UseImpl, TSavedPostfixCrementUseImpl {
|
||||
SavedPostfixCrementSourceVariable sv;
|
||||
|
||||
SavedPostfixCrementUseImpl() { this = TSavedPostfixCrementUseImpl(sv, indirectionIndex) }
|
||||
|
||||
override string toString() { result = "Use of " + this.getSourceVariable() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
this.getOperand().getUse() = block.getInstruction(index)
|
||||
}
|
||||
|
||||
override SourceVariable getSourceVariable() { result = sv }
|
||||
|
||||
final Operand getOperand() { result = sv.getOperand() }
|
||||
|
||||
final override Cpp::Location getLocation() { result = this.getOperand().getLocation() }
|
||||
|
||||
override int getIndirection() { result = sv.getIndirection() }
|
||||
|
||||
override predicate isCertain() { isUse(true, this.getOperand(), _, _, indirectionIndex) }
|
||||
|
||||
override Node getNode() { nodeHasOperand(result, this.getOperand(), indirectionIndex) }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate finalParameterNodeHasParameterAndIndex(
|
||||
FinalParameterNode n, Parameter p, int indirectionIndex
|
||||
@@ -532,7 +685,18 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
||||
result instanceof UnknownLocation
|
||||
}
|
||||
|
||||
override BaseIRVariable getBaseSourceVariable() { result.getIRVariable().getAst() = p }
|
||||
pragma[nomagic]
|
||||
private predicate hasBaseSourceVariableAndIndirection(BaseIRVariable v, int indirection) {
|
||||
v.getIRVariable().getAst() = p and
|
||||
indirection = this.getIndirection()
|
||||
}
|
||||
|
||||
override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseIRVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
this.hasBaseSourceVariableAndIndirection(v, indirection)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -612,8 +776,17 @@ class GlobalUse extends UseImpl, TGlobalUse {
|
||||
hasReturnPosition(f, block, index)
|
||||
}
|
||||
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
baseSourceVariableIsGlobal(result, global, f)
|
||||
pragma[nomagic]
|
||||
private predicate hasBaseSourceVariableAndIndirection(BaseIRVariable v, int indirection) {
|
||||
baseSourceVariableIsGlobal(v, global, f) and
|
||||
indirection = this.getIndirection()
|
||||
}
|
||||
|
||||
override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseIRVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
this.hasBaseSourceVariableAndIndirection(v, indirection)
|
||||
)
|
||||
}
|
||||
|
||||
final override Cpp::Location getLocation() { result = f.getLocation() }
|
||||
@@ -658,15 +831,15 @@ class GlobalDefImpl extends DefImpl, TGlobalDefImpl {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the global variable associated with this definition. */
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
baseSourceVariableIsGlobal(result, global, f)
|
||||
final override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirectionIndex) and
|
||||
baseSourceVariableIsGlobal(v, global, f)
|
||||
)
|
||||
}
|
||||
|
||||
override int getIndirection() { result = indirectionIndex }
|
||||
|
||||
override Node0Impl getValue() { none() }
|
||||
|
||||
override predicate isCertain() { any() }
|
||||
|
||||
/**
|
||||
@@ -704,9 +877,15 @@ predicate defToNode(Node node, Definition def, SourceVariable sv) {
|
||||
}
|
||||
|
||||
private predicate defToNode(Node node, Definition def) {
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
// Only definitions of `NormalSourceVariable` need to be converted into
|
||||
// dataflow nodes. The other case, `SavedPostfixCrementSourceVariable`,
|
||||
// are internal definitions that don't have a dataflow node representation.
|
||||
def.getSourceVariable() instanceof NormalSourceVariable and
|
||||
(
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
)
|
||||
or
|
||||
node.(InitialGlobalValue).getGlobalDef() = def
|
||||
}
|
||||
@@ -940,6 +1119,16 @@ module SsaCached {
|
||||
SsaImpl::phiHasInputFromBlock(phi, inp, bb)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate uncertainWriteDefinitionInput(Definition uncertain, Definition inp) {
|
||||
SsaImpl::uncertainWriteDefinitionInput(uncertain, inp)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaDefReachesEndOfBlock(IRBlock bb, Definition def) {
|
||||
SsaImpl::ssaDefReachesEndOfBlock(bb, def, _)
|
||||
}
|
||||
|
||||
predicate variableRead = SsaInput::variableRead/4;
|
||||
|
||||
predicate variableWrite = SsaInput::variableWrite/4;
|
||||
@@ -1035,13 +1224,23 @@ class SynthNode extends DataFlowIntegrationImpl::SsaNode {
|
||||
SynthNode() { not this.asDefinition() instanceof SsaImpl::WriteDefinition }
|
||||
}
|
||||
|
||||
signature predicate guardChecksNodeSig(IRGuards::IRGuardCondition g, Node e, boolean branch);
|
||||
private signature class ParamSig;
|
||||
|
||||
signature predicate guardChecksNodeSig(
|
||||
IRGuards::IRGuardCondition g, Node e, boolean branch, int indirectionIndex
|
||||
);
|
||||
private module ParamIntPair<ParamSig P> {
|
||||
newtype TPair = MkPair(P p, int indirectionIndex) { nodeHasInstruction(_, _, indirectionIndex) }
|
||||
}
|
||||
|
||||
module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
private module WithParam<ParamSig P> {
|
||||
signature predicate guardChecksNodeSig(IRGuards::IRGuardCondition g, Node e, boolean gv, P param);
|
||||
}
|
||||
|
||||
private module IntWithParam<ParamSig P> {
|
||||
signature predicate guardChecksNodeSig(
|
||||
IRGuards::IRGuardCondition g, Node e, boolean gv, int indirectionIndex, P param
|
||||
);
|
||||
}
|
||||
|
||||
module BarrierGuardWithIntParam<ParamSig P, IntWithParam<P>::guardChecksNodeSig/5 guardChecksNode> {
|
||||
private predicate ssaDefReachesCertainUse(Definition def, UseImpl use) {
|
||||
exists(SourceVariable v, IRBlock bb, int i |
|
||||
use.hasIndexInBlock(bb, i, v) and
|
||||
@@ -1052,21 +1251,23 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
|
||||
private predicate guardChecksInstr(
|
||||
IRGuards::Guards_v1::Guard g, IRGuards::GuardsInput::Expr instr, IRGuards::GuardValue gv,
|
||||
int indirectionIndex
|
||||
ParamIntPair<P>::TPair pair
|
||||
) {
|
||||
exists(Node node |
|
||||
exists(Node node, int indirectionIndex, P p |
|
||||
pair = ParamIntPair<P>::MkPair(p, indirectionIndex) and
|
||||
nodeHasInstruction(node, instr, indirectionIndex) and
|
||||
guardChecksNode(g, node, gv.asBooleanValue(), indirectionIndex)
|
||||
guardChecksNode(g, node, gv.asBooleanValue(), indirectionIndex, p)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksWithWrappers(
|
||||
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, IRGuards::GuardValue val,
|
||||
int indirectionIndex
|
||||
ParamIntPair<P>::MkPair pair
|
||||
) {
|
||||
exists(Instruction e |
|
||||
IRGuards::Guards_v1::ParameterizedValidationWrapper<int, guardChecksInstr/4>::guardChecks(g,
|
||||
e, val, indirectionIndex)
|
||||
exists(Instruction e, int indirectionIndex |
|
||||
IRGuards::Guards_v1::ParameterizedValidationWrapper<ParamIntPair<P>::TPair, guardChecksInstr/4>::guardChecks(g,
|
||||
e, val, pair) and
|
||||
pair = ParamIntPair<P>::MkPair(_, indirectionIndex)
|
||||
|
|
||||
indirectionIndex = 0 and
|
||||
def.(Definition).getAUse().getDef() = e
|
||||
@@ -1075,18 +1276,19 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
)
|
||||
}
|
||||
|
||||
Node getABarrierNode(int indirectionIndex) {
|
||||
Node getABarrierNode(int indirectionIndex, P p) {
|
||||
// Only get the SynthNodes from the shared implementation, as the ExprNodes cannot
|
||||
// be matched on SourceVariable.
|
||||
result.(SsaSynthNode).getSynthNode() =
|
||||
DataFlowIntegrationImpl::BarrierGuardDefWithState<int, guardChecksWithWrappers/4>::getABarrierNode(indirectionIndex)
|
||||
DataFlowIntegrationImpl::BarrierGuardDefWithState<ParamIntPair<P>::MkPair, guardChecksWithWrappers/4>::getABarrierNode(ParamIntPair<P>::MkPair(p,
|
||||
indirectionIndex))
|
||||
or
|
||||
// Calculate the guarded UseImpls corresponding to ExprNodes directly.
|
||||
exists(
|
||||
DataFlowIntegrationInput::Guard g, IRGuards::GuardValue branch, Definition def, IRBlock bb
|
||||
|
|
||||
guardChecksWithWrappers(g, def, branch, indirectionIndex) and
|
||||
exists(UseImpl use |
|
||||
guardChecksWithWrappers(g, def, branch, ParamIntPair<P>::MkPair(p, indirectionIndex)) and
|
||||
ssaDefReachesCertainUse(def, use) and
|
||||
use.getBlock() = bb and
|
||||
DataFlowIntegrationInput::guardControlsBlock(g, bb, branch) and
|
||||
@@ -1096,15 +1298,16 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
}
|
||||
}
|
||||
|
||||
module BarrierGuard<guardChecksNodeSig/3 guardChecksNode> {
|
||||
module BarrierGuard<ParamSig P, WithParam<P>::guardChecksNodeSig/4 guardChecksNode> {
|
||||
private predicate guardChecksNode(
|
||||
IRGuards::IRGuardCondition g, Node e, boolean branch, int indirectionIndex
|
||||
IRGuards::IRGuardCondition g, Node e, boolean gv, int indirectionIndex, P p
|
||||
) {
|
||||
guardChecksNode(g, e, branch) and indirectionIndex = 0
|
||||
indirectionIndex = 0 and
|
||||
guardChecksNode(g, e, gv, p)
|
||||
}
|
||||
|
||||
Node getABarrierNode() {
|
||||
result = BarrierGuardWithIntParam<guardChecksNode/4>::getABarrierNode(0)
|
||||
Node getABarrierNode(P p) {
|
||||
result = BarrierGuardWithIntParam<P, guardChecksNode/5>::getABarrierNode(0, p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,9 +1362,17 @@ class Definition extends SsaImpl::Definition {
|
||||
private Definition getAPhiInputOrPriorDefinition() {
|
||||
result = this.(PhiNode).getAnInput()
|
||||
or
|
||||
SsaImpl::uncertainWriteDefinitionInput(this, result)
|
||||
uncertainWriteDefinitionInput(this, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this SSA definition is live at the end of basic block `bb`.
|
||||
* That is, this definition reaches the end of basic block `bb`, at which
|
||||
* point it is still live, without crossing another SSA definition of the
|
||||
* same source variable.
|
||||
*/
|
||||
predicate isLiveAtEndOfBlock(IRBlock bb) { ssaDefReachesEndOfBlock(bb, this) }
|
||||
|
||||
/**
|
||||
* Gets a definition that ultimately defines this SSA definition and is
|
||||
* not itself a phi node.
|
||||
|
||||
@@ -104,7 +104,11 @@ newtype TInstructionTag =
|
||||
} or
|
||||
SizeofVlaDimensionTag(int index) {
|
||||
exists(VlaDeclStmt v | exists(v.getTransitiveVlaDimensionStmt(index)))
|
||||
}
|
||||
} or
|
||||
AssertionVarAddressTag() or
|
||||
AssertionVarLoadTag() or
|
||||
AssertionOpTag() or
|
||||
AssertionBranchTag()
|
||||
|
||||
class InstructionTag extends TInstructionTag {
|
||||
final string toString() { result = getInstructionTagId(this) }
|
||||
@@ -296,4 +300,12 @@ string getInstructionTagId(TInstructionTag tag) {
|
||||
tag = CoAwaitBranchTag() and result = "CoAwaitBranch"
|
||||
or
|
||||
tag = BoolToIntConversionTag() and result = "BoolToIntConversion"
|
||||
or
|
||||
tag = AssertionVarAddressTag() and result = "AssertionVarAddress"
|
||||
or
|
||||
tag = AssertionVarLoadTag() and result = "AssertionVarLoad"
|
||||
or
|
||||
tag = AssertionOpTag() and result = "AssertionOp"
|
||||
or
|
||||
tag = AssertionBranchTag() and result = "AssertionBranch"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.internal.IRUtilities
|
||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
private import semmle.code.cpp.ir.internal.CppType
|
||||
private import semmle.code.cpp.ir.internal.TempVariableTag
|
||||
private import InstructionTag
|
||||
private import TranslatedElement
|
||||
private import TranslatedStmt
|
||||
private import TranslatedFunction
|
||||
|
||||
/**
|
||||
* Holds if `s` is a statement that may be an expanded assertion in a
|
||||
* release build.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate stmtCandidate(Stmt s) {
|
||||
not s.isFromUninstantiatedTemplate(_) and
|
||||
(
|
||||
// The expansion of `__analysis_assume(x != 0);` when `__analysis_assume` is
|
||||
// empty is the empty statement.
|
||||
s instanceof EmptyStmt
|
||||
or
|
||||
// The expansion of `assert(x != 0)` when `assert` is `((void)0)` is a zero literal
|
||||
// with a void type.
|
||||
exists(Expr e |
|
||||
e = s.(ExprStmt).getExpr() and
|
||||
e.getValue() = "0" and
|
||||
e.getActualType() instanceof VoidType
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate macroInvocationLocation(int startline, Function f, MacroInvocation mi) {
|
||||
mi.getMacroName() = ["assert", "__analysis_assume"] and
|
||||
mi.getNumberOfArguments() = 1 and
|
||||
mi.getLocation().hasLocationInfo(_, startline, _, _, _) and
|
||||
f.getEntryPoint().isAffectedByMacro(mi)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate stmtParentLocation(int startline, Function f, StmtParent p) {
|
||||
p.getEnclosingFunction() = f and
|
||||
p.getLocation().hasLocationInfo(_, startline, _, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `mi` is a macro invocation with a name that is known
|
||||
* to correspond to an assertion macro, and the macro invocation
|
||||
* is the only thing on the line.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate assertion0(MacroInvocation mi, Stmt s, string arg) {
|
||||
stmtCandidate(s) and
|
||||
s =
|
||||
unique(StmtParent p, int startline, Function f |
|
||||
macroInvocationLocation(startline, f, mi) and
|
||||
stmtParentLocation(startline, f, p) and
|
||||
// Also do not count the elements from the expanded macro, i.e., when checking
|
||||
// if `assert(x)` is the only thing on the line we do not count the
|
||||
// generated `((void)0)` expression.
|
||||
not p = mi.getAnExpandedElement()
|
||||
|
|
||||
p
|
||||
) and
|
||||
arg = mi.getUnexpandedArgument(0)
|
||||
}
|
||||
|
||||
private Function getEnclosingFunctionForMacroInvocation(MacroInvocation mi) {
|
||||
exists(Stmt s |
|
||||
assertion0(mi, s, _) and
|
||||
result = s.getEnclosingFunction()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `arg` has two components and the `i`'th component of the string
|
||||
* `arg` is `s`, and the components are separated by an operation with
|
||||
* opcode `opcode`.
|
||||
*/
|
||||
bindingset[arg]
|
||||
pragma[inline_late]
|
||||
private predicate parseArgument(string arg, string s, int i, Opcode opcode) {
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?<=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareLE
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?>=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareGE
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?<\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareLT
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?>\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareGT
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?!=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareNE
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?==\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareEQ
|
||||
}
|
||||
|
||||
private Element getAChildScope(Element scope) { result.getParentScope() = scope }
|
||||
|
||||
private predicate hasAVariable(MacroInvocation mi, Stmt s, Element scope) {
|
||||
assertion0(mi, s, _) and
|
||||
s.getParent() = scope
|
||||
or
|
||||
hasAVariable(mi, s, getAChildScope(scope))
|
||||
}
|
||||
|
||||
private LocalScopeVariable getVariable(MacroInvocation mi, int i) {
|
||||
exists(string operand, string arg, Stmt s |
|
||||
assertion0(mi, s, arg) and
|
||||
parseArgument(arg, operand, i, _) and
|
||||
result =
|
||||
unique(Variable v |
|
||||
v.getLocation().getStartLine() < s.getLocation().getStartLine() and
|
||||
hasAVariable(mi, s, v.getParentScope()) and
|
||||
v.hasName(operand)
|
||||
|
|
||||
v
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th component of the macro invocation `mi` with opcode
|
||||
* `opcode` is a reference to `var`.
|
||||
*/
|
||||
private predicate hasVarAccessMacroArgument(MacroInvocation mi, Variable var, int i, Opcode opcode) {
|
||||
exists(string arg, string s, Function f |
|
||||
arg = mi.getUnexpandedArgument(0) and
|
||||
f = getEnclosingFunctionForMacroInvocation(mi) and
|
||||
parseArgument(arg, s, i, opcode) and
|
||||
var = getVariable(mi, i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th component of the macro invocation `mi` with opcode
|
||||
* `opcode` is a constant with the value `k`.
|
||||
*/
|
||||
private predicate hasConstMacroArgument(MacroInvocation mi, int k, int i, Opcode opcode) {
|
||||
exists(string arg, string s |
|
||||
assertion0(mi, _, arg) and
|
||||
s.toInt() = k and
|
||||
parseArgument(arg, s, i, opcode)
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasAssertionOperand(MacroInvocation mi, int i) {
|
||||
hasVarAccessMacroArgument(mi, _, i, _)
|
||||
or
|
||||
hasConstMacroArgument(mi, _, i, _)
|
||||
}
|
||||
|
||||
private predicate hasAssertionOpcode(MacroInvocation mi, Opcode opcode) {
|
||||
hasVarAccessMacroArgument(mi, _, _, opcode)
|
||||
or
|
||||
hasConstMacroArgument(mi, _, _, opcode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `mi` is a macro invocation that is an assertion that should be generated
|
||||
* in the control-flow graph at `s`.
|
||||
*/
|
||||
predicate assertion(MacroInvocation mi, Stmt s) {
|
||||
assertion0(mi, s, _) and
|
||||
hasAssertionOperand(mi, 0) and
|
||||
hasAssertionOperand(mi, 1)
|
||||
}
|
||||
|
||||
/** The translation of an operand of an assertion. */
|
||||
abstract private class TranslatedAssertionOperand extends TranslatedElement,
|
||||
TTranslatedAssertionOperand
|
||||
{
|
||||
MacroInvocation mi;
|
||||
int index;
|
||||
|
||||
TranslatedAssertionOperand() { this = TTranslatedAssertionOperand(mi, index) }
|
||||
|
||||
MacroInvocation getMacroInvocation() { result = mi }
|
||||
|
||||
/**
|
||||
* Gets the statement that is being replaced by the assertion that uses this
|
||||
* operand.
|
||||
*/
|
||||
Stmt getStmt() { assertion(mi, result) }
|
||||
|
||||
final override Locatable getAst() { result = this.getStmt() }
|
||||
|
||||
final override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
final override Declaration getFunction() { result = this.getStmt().getEnclosingFunction() }
|
||||
|
||||
/** Gets the instruction which holds the result of this operand. */
|
||||
abstract Instruction getResult();
|
||||
|
||||
final override string toString() { result = "Operand of assertion: " + mi }
|
||||
|
||||
/** Gets the index of this operand (i.e., `0` or `1`). */
|
||||
final int getIndex() { result = index }
|
||||
}
|
||||
|
||||
/** An operand of an assertion that is a variable access. */
|
||||
class TranslatedAssertionVarAccess extends TranslatedAssertionOperand {
|
||||
TranslatedAssertionVarAccess() { hasVarAccessMacroArgument(mi, _, index, _) }
|
||||
|
||||
Variable getVariable() { hasVarAccessMacroArgument(mi, result, index, _) }
|
||||
|
||||
final override IRUserVariable getInstructionVariable(InstructionTag tag) {
|
||||
tag = AssertionVarAddressTag() and
|
||||
result.getVariable() = this.getVariable()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(AssertionVarAddressTag()) and kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = AssertionVarAddressTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(AssertionVarLoadTag())
|
||||
or
|
||||
tag = AssertionVarLoadTag() and
|
||||
result = getTranslatedAssertionMacroInvocation(mi).getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(AssertionVarLoadTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
exists(Variable v | v = this.getVariable() |
|
||||
opcode instanceof Opcode::VariableAddress and
|
||||
tag = AssertionVarAddressTag() and
|
||||
resultType = getTypeForGLValue(v.getType())
|
||||
or
|
||||
opcode instanceof Opcode::Load and
|
||||
tag = AssertionVarLoadTag() and
|
||||
resultType = getTypeForPRValue(v.getType())
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
tag = AssertionVarLoadTag() and
|
||||
operandTag instanceof AddressOperandTag and
|
||||
result = this.getInstruction(AssertionVarAddressTag())
|
||||
}
|
||||
|
||||
final override Instruction getResult() { result = this.getInstruction(AssertionVarLoadTag()) }
|
||||
}
|
||||
|
||||
/** An operand of an assertion that is a constant access. */
|
||||
private class TranslatedAssertionConst extends TranslatedAssertionOperand {
|
||||
TranslatedAssertionConst() { hasConstMacroArgument(mi, _, index, _) }
|
||||
|
||||
int getConst() { hasConstMacroArgument(mi, result, index, _) }
|
||||
|
||||
final override string getInstructionConstantValue(InstructionTag tag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getConst().toString()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = getTranslatedAssertionMacroInvocation(mi).getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
opcode instanceof Opcode::Constant and
|
||||
tag = OnlyInstructionTag() and
|
||||
resultType = getIntType()
|
||||
}
|
||||
|
||||
final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `TranslatedAssertionMacroInvocation` corresponding to the macro
|
||||
* invocation `mi`.
|
||||
*/
|
||||
TranslatedAssertionMacroInvocation getTranslatedAssertionMacroInvocation(MacroInvocation mi) {
|
||||
result.getMacroInvocation() = mi
|
||||
}
|
||||
|
||||
/**
|
||||
* A synthesized assertion which would have otherwise been invisible because the
|
||||
* database represents a release build where assertions are disabled.
|
||||
*/
|
||||
private class TranslatedAssertionMacroInvocation extends TranslatedStmt {
|
||||
MacroInvocation mi;
|
||||
|
||||
TranslatedAssertionMacroInvocation() { assertion(mi, stmt) }
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getLeft().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
TranslatedAssertionOperand getLeft() {
|
||||
result.getMacroInvocation() = mi and
|
||||
result.getIndex() = 0
|
||||
}
|
||||
|
||||
TranslatedAssertionOperand getRight() {
|
||||
result.getMacroInvocation() = mi and
|
||||
result.getIndex() = 1
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = AssertionOpTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(AssertionBranchTag())
|
||||
or
|
||||
tag = AssertionBranchTag() and
|
||||
kind instanceof TrueEdge and
|
||||
result = this.getParent().getChildSuccessor(this, _)
|
||||
}
|
||||
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getLeft()
|
||||
or
|
||||
id = 1 and result = this.getRight()
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(AssertionBranchTag())
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = AssertionOpTag() and
|
||||
resultType = getBoolType() and
|
||||
hasAssertionOpcode(mi, opcode)
|
||||
or
|
||||
tag = AssertionBranchTag() and
|
||||
resultType = getVoidType() and
|
||||
opcode instanceof Opcode::ConditionalBranch
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getLeft() and
|
||||
result = this.getRight().getFirstInstruction(kind)
|
||||
or
|
||||
child = this.getRight() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(AssertionOpTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
tag = AssertionOpTag() and
|
||||
(
|
||||
operandTag instanceof LeftOperandTag and
|
||||
result = this.getLeft().getResult()
|
||||
or
|
||||
operandTag instanceof RightOperandTag and
|
||||
result = this.getRight().getResult()
|
||||
)
|
||||
or
|
||||
tag = AssertionBranchTag() and
|
||||
operandTag instanceof ConditionOperandTag and
|
||||
result = this.getInstruction(AssertionOpTag())
|
||||
}
|
||||
|
||||
MacroInvocation getMacroInvocation() { result = mi }
|
||||
}
|
||||
@@ -12,6 +12,7 @@ private import TranslatedFunction
|
||||
private import TranslatedStmt
|
||||
private import TranslatedExpr
|
||||
private import IRConstruction
|
||||
private import TranslatedAssertion
|
||||
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||
private import SideEffects
|
||||
|
||||
@@ -138,6 +139,14 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
// conditionally constructed (until we have a mechanism for calling these only when the
|
||||
// temporary's constructor was run)
|
||||
isConditionalTemporaryDestructorCall(expr)
|
||||
or
|
||||
// An assertion in a release build is often defined as `#define assert(x) ((void)0)`.
|
||||
// We generate a synthetic assertion in release builds, and when we do that the
|
||||
// expression `((void)0)` should not be translated.
|
||||
exists(MacroInvocation mi |
|
||||
assertion(mi, _) and
|
||||
expr = mi.getExpr().getFullyConverted()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -909,7 +918,8 @@ newtype TTranslatedElement =
|
||||
} or
|
||||
// The side effect that initializes newly-allocated memory.
|
||||
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
|
||||
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) }
|
||||
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) } or
|
||||
TTranslatedAssertionOperand(MacroInvocation mi, int index) { hasAssertionOperand(mi, index) }
|
||||
|
||||
/**
|
||||
* Gets the index of the first explicitly initialized element in `initList`
|
||||
|
||||
@@ -10,6 +10,7 @@ private import TranslatedElement
|
||||
private import TranslatedExpr
|
||||
private import TranslatedFunction
|
||||
private import TranslatedInitialization
|
||||
private import TranslatedAssertion
|
||||
|
||||
TranslatedStmt getTranslatedStmt(Stmt stmt) { result.getAst() = stmt }
|
||||
|
||||
@@ -324,8 +325,16 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
|
||||
|
||||
class TranslatedEmptyStmt extends TranslatedStmt {
|
||||
TranslatedEmptyStmt() {
|
||||
stmt instanceof EmptyStmt or
|
||||
stmt instanceof LabelStmt or
|
||||
// An assertion macro invocation can expand to
|
||||
// an empty statement in release builds. In that case
|
||||
// we synthesize the check that would have occurred.
|
||||
// This is handled by `TranslatedAssertion.qll` and so
|
||||
// we exclude these statements here.
|
||||
not assertion(_, stmt) and
|
||||
stmt instanceof EmptyStmt
|
||||
or
|
||||
stmt instanceof LabelStmt
|
||||
or
|
||||
stmt instanceof SwitchCase
|
||||
}
|
||||
|
||||
@@ -420,6 +429,15 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
class TranslatedExprStmt extends TranslatedStmt {
|
||||
override ExprStmt stmt;
|
||||
|
||||
TranslatedExprStmt() {
|
||||
// An assertion macro invocation typically expand to the
|
||||
// expression `((void)0)` in release builds. In that case
|
||||
// we synthesize the check that would have occurred.
|
||||
// This is handled by `TranslatedAssertion.qll` and so
|
||||
// we exclude these statements here.
|
||||
not assertion(_, stmt)
|
||||
}
|
||||
|
||||
TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr().getFullyConverted()) }
|
||||
|
||||
override TranslatedElement getChildInternal(int id) { id = 0 and result = this.getExpr() }
|
||||
|
||||
@@ -57,3 +57,4 @@ private import implementations.CAtlFile
|
||||
private import implementations.CAtlFileMapping
|
||||
private import implementations.CAtlTemporaryFile
|
||||
private import implementations.CRegKey
|
||||
private import implementations.WinHttp
|
||||
|
||||
@@ -16,17 +16,3 @@ private class MySqlExecutionFunction extends SqlExecutionFunction {
|
||||
|
||||
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mysql_real_escape_string` family of functions from the MySQL C API.
|
||||
*/
|
||||
private class MySqlBarrierFunction extends SqlBarrierFunction {
|
||||
MySqlBarrierFunction() {
|
||||
this.hasName(["mysql_real_escape_string", "mysql_real_escape_string_quote"])
|
||||
}
|
||||
|
||||
override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameterDeref(2) and
|
||||
output.isParameterDeref(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.dataflow.FlowSteps
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
/** The `WINHTTP_HEADER_NAME` class from `winhttp.h`. */
|
||||
class WinHttpHeaderName extends Class {
|
||||
WinHttpHeaderName() { this.hasGlobalName("_WINHTTP_HEADER_NAME") }
|
||||
}
|
||||
|
||||
/** The `WINHTTP_EXTENDED_HEADER` class from `winhttp.h`. */
|
||||
class WinHttpExtendedHeader extends Class {
|
||||
WinHttpExtendedHeader() { this.hasGlobalName("_WINHTTP_EXTENDED_HEADER") }
|
||||
}
|
||||
|
||||
private class WinHttpHeaderNameInheritingContent extends TaintInheritingContent,
|
||||
DataFlow::FieldContent
|
||||
{
|
||||
WinHttpHeaderNameInheritingContent() {
|
||||
this.getIndirectionIndex() = 2 and
|
||||
(
|
||||
this.getAField().getDeclaringType() instanceof WinHttpHeaderName
|
||||
or
|
||||
// The extended header looks like:
|
||||
// struct WINHTTP_EXTENDED_HEADER {
|
||||
// union { [...] };
|
||||
// union { [...] };
|
||||
// };
|
||||
// So the first declaring type is the anonymous unions, and the declaring
|
||||
// type of those anonymous unions is the `WINHTTP_EXTENDED_HEADER` struct.
|
||||
this.getAField().getDeclaringType().getDeclaringType() instanceof WinHttpExtendedHeader
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The `URL_COMPONENTS` class from `winhttp.h`. */
|
||||
class WinHttpUrlComponents extends Class {
|
||||
WinHttpUrlComponents() { this.hasGlobalName("_WINHTTP_URL_COMPONENTS") }
|
||||
}
|
||||
|
||||
private class WinHttpUrlComponentsInheritingContent extends TaintInheritingContent,
|
||||
DataFlow::FieldContent
|
||||
{
|
||||
WinHttpUrlComponentsInheritingContent() {
|
||||
exists(Field f | f = this.getField() and f.getDeclaringType() instanceof WinHttpUrlComponents |
|
||||
if f.getType().getUnspecifiedType() instanceof PointerType
|
||||
then this.getIndirectionIndex() = 2
|
||||
else this.getIndirectionIndex() = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class Stmt extends StmtParent, @stmt {
|
||||
predicate hasChild(Element e, int n) { this.getChild(n) = e }
|
||||
|
||||
/** Gets the enclosing function of this statement, if any. */
|
||||
Function getEnclosingFunction() { result = stmtEnclosingElement(this) }
|
||||
override Function getEnclosingFunction() { result = stmtEnclosingElement(this) }
|
||||
|
||||
/**
|
||||
* Gets the nearest enclosing block of this statement in the source, if any.
|
||||
@@ -159,7 +159,10 @@ private class TStmtParent = @stmt or @expr;
|
||||
*
|
||||
* This is normally a statement, but may be a `StmtExpr`.
|
||||
*/
|
||||
class StmtParent extends ControlFlowNode, TStmtParent { }
|
||||
class StmtParent extends ControlFlowNode, TStmtParent {
|
||||
/** Gets the enclosing function of this element, if any. */
|
||||
Function getEnclosingFunction() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ 'expression' statement.
|
||||
|
||||
@@ -2353,6 +2353,7 @@ case @preprocdirect.kind of
|
||||
| 14 = @ppd_ms_import
|
||||
| 15 = @ppd_elifdef
|
||||
| 16 = @ppd_elifndef
|
||||
| 17 = @ppd_embed
|
||||
| 18 = @ppd_warning
|
||||
;
|
||||
|
||||
@@ -2379,6 +2380,11 @@ includes(
|
||||
int included: @file ref
|
||||
);
|
||||
|
||||
embeds(
|
||||
unique int id: @ppd_embed ref,
|
||||
int included: @file ref
|
||||
);
|
||||
|
||||
link_targets(
|
||||
int id: @link_target,
|
||||
int binary: @file ref
|
||||
@@ -2389,6 +2395,8 @@ link_parent(
|
||||
int link_target : @link_target ref
|
||||
);
|
||||
|
||||
/*- Database metadata -*/
|
||||
|
||||
/**
|
||||
* The CLI will automatically emit applicable tuples for this table,
|
||||
* such as `databaseMetadata("isOverlay", "true")` when building an
|
||||
@@ -2399,6 +2407,8 @@ databaseMetadata(
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
/*- Overlay support -*/
|
||||
|
||||
/**
|
||||
* The CLI will automatically emit tuples for each new/modified/deleted file
|
||||
* when building an overlay database.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Sections for databaseMetadata and overlayChangedFiles
|
||||
compatibility: full
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Support embed preprocessor directive
|
||||
compatibility: partial
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.5.10
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.5.9
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -45,14 +45,15 @@ module SqlTaintedConfig implements DataFlow::ConfigSig {
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) {
|
||||
or
|
||||
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
|
||||
node.asIndirectArgument() = sql.getACallToThisFunction().getArgument(arg) and
|
||||
input.isParameterDeref(arg) and
|
||||
sql.barrierSqlArgument(input, _)
|
||||
)
|
||||
or
|
||||
// barrier defined using models-as-data
|
||||
barrierNode(node, "sql-injection")
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
3
cpp/ql/src/change-notes/released/1.5.10.md
Normal file
3
cpp/ql/src/change-notes/released/1.5.10.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.5.10
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.5.9
|
||||
lastReleaseVersion: 1.5.10
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.5.9
|
||||
version: 1.5.11-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -310,7 +310,7 @@ private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputS
|
||||
}
|
||||
|
||||
private predicate hasManualSummaryModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.hasManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
|
||||
@@ -384,7 +384,9 @@ astGuardsControl
|
||||
| test.c:126:7:126:7 | 1 | true | 131 | 132 |
|
||||
| test.c:126:7:126:7 | 1 | true | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 134 | 123 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | true | 126 | 128 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | true | 131 | 132 |
|
||||
| test.c:131:7:131:7 | b | true | 131 | 132 |
|
||||
@@ -405,9 +407,7 @@ astGuardsControl
|
||||
| test.c:181:9:181:9 | x | true | 181 | 182 |
|
||||
| test.c:181:9:181:9 | x | true | 186 | 180 |
|
||||
| test.cpp:18:8:18:10 | call to get | true | 19 | 19 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | 31 | 32 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | true | 43 | 45 |
|
||||
astGuardsEnsure
|
||||
@@ -589,13 +589,9 @@ astGuardsEnsure
|
||||
| test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | == | test.c:175:32:175:32 | 0 | 0 | 175 | 175 |
|
||||
| test.c:175:13:175:32 | ... == ... | test.c:175:32:175:32 | 0 | != | test.c:175:13:175:15 | call to foo | 0 | 175 | 175 |
|
||||
| test.c:175:13:175:32 | ... == ... | test.c:175:32:175:32 | 0 | == | test.c:175:13:175:15 | call to foo | 0 | 175 | 175 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 31 | 32 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 31 | 32 |
|
||||
astGuardsEnsure_const
|
||||
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | != | 0 | 7 | 9 |
|
||||
@@ -793,13 +789,21 @@ astGuardsEnsure_const
|
||||
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 |
|
||||
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 134 | 123 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 132 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
|
||||
@@ -846,17 +850,11 @@ astGuardsEnsure_const
|
||||
| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | == | 1 | 186 | 180 |
|
||||
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 |
|
||||
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | 19 | 19 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 31 | 32 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | 31 | 32 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 31 | 32 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | 43 | 45 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | 43 | 45 |
|
||||
|
||||
@@ -105,9 +105,13 @@
|
||||
| test.c:126:7:126:7 | 1 | true | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:7 | 1 | true | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | true | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | true | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | true | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | true | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:12:126:26 | call to test3_condition | true | test.c:126:31:128:16 | { ... } |
|
||||
@@ -162,17 +166,11 @@
|
||||
| test.c:219:9:219:22 | call to __builtin_expect | true | test.c:219:25:221:5 | { ... } |
|
||||
| test.cpp:18:8:18:10 | call to get | not null | test.cpp:19:5:19:14 | ExprStmt |
|
||||
| test.cpp:18:8:18:10 | call to get | true | test.cpp:19:5:19:14 | ExprStmt |
|
||||
| test.cpp:30:22:30:22 | x | -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:30:22:30:22 | x | -1 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:30:22:30:22 | x | not -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:30:22:30:22 | x | not -1 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:7 | x | -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:7 | x | -1 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:31:7:31:7 | x | not -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:7 | x | not -1 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:42:13:42:20 | call to getABool | true | test.cpp:43:9:45:23 | { ... } |
|
||||
| test.cpp:60:31:60:31 | i | 0 | test.cpp:62:5:64:12 | case ...: |
|
||||
@@ -408,19 +406,11 @@
|
||||
| test.cpp:400:11:400:25 | call to testEnumWrapper | 2 | test.cpp:404:5:406:12 | case ...: |
|
||||
| test.cpp:400:27:400:27 | b | false | test.cpp:404:5:406:12 | case ...: |
|
||||
| test.cpp:400:27:400:27 | b | true | test.cpp:401:5:403:12 | case ...: |
|
||||
| test.cpp:410:26:410:26 | o | not null | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:410:26:410:26 | o | not null | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:410:26:410:26 | o | null | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:410:26:410:26 | o | null | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | false | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | false | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:7:411:8 | ! ... | true | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | true | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | false | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | false | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | not null | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | not null | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | null | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | null | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | true | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | true | test.cpp:412:1:412:1 | return ... |
|
||||
|
||||
@@ -195,13 +195,9 @@ binary
|
||||
| test.c:215:6:215:18 | call to __builtin_expect | test.c:215:17:215:17 | b | < | test.c:215:13:215:13 | a | 0 | test.c:215:21:217:5 | { ... } |
|
||||
| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:16:219:16 | a | >= | test.c:219:20:219:21 | 42 | 1 | test.c:219:25:221:5 | { ... } |
|
||||
| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:20:219:21 | 42 | < | test.c:219:16:219:16 | a | 0 | test.c:219:25:221:5 | { ... } |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:6 | f | != | test.cpp:105:11:105:14 | 0.0 | 0 | test.cpp:105:17:106:7 | { ... } |
|
||||
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:11:105:14 | 0.0 | != | test.cpp:105:6:105:6 | f | 0 | test.cpp:105:17:106:7 | { ... } |
|
||||
@@ -762,13 +758,21 @@ unary
|
||||
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } |
|
||||
@@ -853,17 +857,11 @@ unary
|
||||
| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:16:219:21 | ... > ... | != | 0 | test.c:219:25:221:5 | { ... } |
|
||||
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | test.cpp:19:5:19:14 | ExprStmt |
|
||||
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | test.cpp:19:5:19:14 | ExprStmt |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | test.cpp:43:9:45:23 | { ... } |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | test.cpp:43:9:45:23 | { ... } |
|
||||
@@ -1401,35 +1399,19 @@ unary
|
||||
| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | == | 0 | test.cpp:394:50:395:7 | { ... } |
|
||||
| test.cpp:400:11:400:25 | call to testEnumWrapper | test.cpp:400:11:400:25 | call to testEnumWrapper | == | 1 | test.cpp:401:5:403:12 | case ...: |
|
||||
| test.cpp:400:11:400:25 | call to testEnumWrapper | test.cpp:400:11:400:25 | call to testEnumWrapper | == | 2 | test.cpp:404:5:406:12 | case ...: |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:412:1:412:1 | return ... |
|
||||
|
||||
18
cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp
Normal file
18
cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
void use(int);
|
||||
|
||||
void test() {
|
||||
int y = 43; // $ asDefinition=43
|
||||
use(y);
|
||||
y = 44; // $ asDefinition="... = ..."
|
||||
use(y);
|
||||
|
||||
int x = 43; // $ asDefinition=43
|
||||
x = 44; // $ asDefinition="... = ..."
|
||||
|
||||
S s;
|
||||
s.x = 42; // $ asDefinition="... = ..."
|
||||
}
|
||||
22
cpp/ql/test/library-tests/dataflow/asDefinition/test.ql
Normal file
22
cpp/ql/test/library-tests/dataflow/asDefinition/test.ql
Normal file
@@ -0,0 +1,22 @@
|
||||
import cpp
|
||||
import utils.test.InlineExpectationsTest
|
||||
import semmle.code.cpp.dataflow.new.DataFlow::DataFlow
|
||||
|
||||
bindingset[s]
|
||||
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }
|
||||
|
||||
module AsDefinitionTest implements TestSig {
|
||||
string getARelevantTag() { result = "asDefinition" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(Node n, Expr e |
|
||||
e = n.asDefinition() and
|
||||
location = e.getLocation() and
|
||||
element = n.toString() and
|
||||
tag = "asDefinition" and
|
||||
value = quote(e.toString())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<AsDefinitionTest>
|
||||
@@ -147,6 +147,29 @@ astFlow
|
||||
| test.cpp:1165:10:1165:15 | call to source | test.cpp:1239:10:1239:26 | * ... |
|
||||
| test.cpp:1195:10:1195:24 | call to indirect_source | test.cpp:1200:19:1200:36 | global_int_ptr_ptr |
|
||||
| test.cpp:1195:10:1195:24 | call to indirect_source | test.cpp:1201:10:1201:27 | global_int_ptr_ptr |
|
||||
| test.cpp:1258:11:1258:16 | call to source | test.cpp:1259:8:1259:10 | ... ++ |
|
||||
| test.cpp:1262:7:1262:12 | call to source | test.cpp:1263:8:1263:10 | ... -- |
|
||||
| test.cpp:1266:7:1266:12 | call to source | test.cpp:1267:8:1267:10 | ++ ... |
|
||||
| test.cpp:1266:7:1266:12 | call to source | test.cpp:1268:8:1268:8 | x |
|
||||
| test.cpp:1270:7:1270:12 | call to source | test.cpp:1271:8:1271:10 | -- ... |
|
||||
| test.cpp:1270:7:1270:12 | call to source | test.cpp:1272:8:1272:8 | x |
|
||||
| test.cpp:1274:7:1274:12 | call to source | test.cpp:1275:8:1275:14 | ... += ... |
|
||||
| test.cpp:1274:7:1274:12 | call to source | test.cpp:1276:8:1276:8 | x |
|
||||
| test.cpp:1278:7:1278:12 | call to source | test.cpp:1279:8:1279:14 | ... -= ... |
|
||||
| test.cpp:1278:7:1278:12 | call to source | test.cpp:1280:8:1280:8 | x |
|
||||
| test.cpp:1284:11:1284:16 | call to source | test.cpp:1285:8:1285:20 | ... ? ... : ... |
|
||||
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1289:8:1289:20 | ... ++ |
|
||||
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1290:8:1290:8 | x |
|
||||
| test.cpp:1292:7:1292:12 | call to source | test.cpp:1294:8:1294:8 | x |
|
||||
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1297:8:1297:18 | ... ? ... : ... |
|
||||
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1298:8:1298:8 | x |
|
||||
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1301:8:1301:18 | ... ? ... : ... |
|
||||
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1302:8:1302:8 | x |
|
||||
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1305:8:1305:18 | ... ? ... : ... |
|
||||
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1306:8:1306:8 | x |
|
||||
| test.cpp:1308:7:1308:12 | call to source | test.cpp:1309:14:1309:16 | ... ++ |
|
||||
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1313:8:1313:24 | ... ? ... : ... |
|
||||
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1314:8:1314:8 | x |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
| true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x |
|
||||
@@ -354,6 +377,19 @@ irFlow
|
||||
| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1218:19:1218:36 | **global_int_ptr_ptr |
|
||||
| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1224:19:1224:37 | ** ... |
|
||||
| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1227:10:1227:29 | * ... |
|
||||
| test.cpp:1258:11:1258:16 | call to source | test.cpp:1259:8:1259:10 | ... ++ |
|
||||
| test.cpp:1262:7:1262:12 | call to source | test.cpp:1263:8:1263:10 | ... -- |
|
||||
| test.cpp:1284:11:1284:16 | call to source | test.cpp:1285:8:1285:20 | ... ? ... : ... |
|
||||
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1290:8:1290:8 | x |
|
||||
| test.cpp:1292:7:1292:12 | call to source | test.cpp:1294:8:1294:8 | x |
|
||||
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1297:8:1297:18 | ... ? ... : ... |
|
||||
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1298:8:1298:8 | x |
|
||||
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1301:8:1301:18 | ... ? ... : ... |
|
||||
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1302:8:1302:8 | x |
|
||||
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1306:8:1306:8 | x |
|
||||
| test.cpp:1308:7:1308:12 | call to source | test.cpp:1309:8:1309:16 | ... ++ |
|
||||
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1313:8:1313:24 | ... ? ... : ... |
|
||||
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1314:8:1314:8 | x |
|
||||
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
|
||||
@@ -1252,4 +1252,64 @@ namespace globals_without_explicit_def {
|
||||
calls_set_array();
|
||||
sink(*global_int_array); // $ ir MISSING: ast
|
||||
}
|
||||
}
|
||||
|
||||
void crement_test1() {
|
||||
int x = source();
|
||||
sink(x++); // $ ir ast
|
||||
sink(x);
|
||||
|
||||
x = source();
|
||||
sink(x--); // $ ir ast
|
||||
sink(x);
|
||||
|
||||
x = source();
|
||||
sink(++x); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
|
||||
x = source();
|
||||
sink(--x); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
|
||||
x = source();
|
||||
sink(x += 10); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
|
||||
x = source();
|
||||
sink(x -= 10); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void crement_test2(bool b, int y) {
|
||||
int x = source();
|
||||
sink(b ? x++ : x--); // $ ir ast
|
||||
sink(x);
|
||||
|
||||
x = source();
|
||||
sink((b ? x : y)++); // $ ast MISSING: ir
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink(++(b ? x : y));
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink(b ? x++ : y); // $ ir ast
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink(b ? x : y++); // $ ir ast
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink(b ? ++x : y); // $ SPURIOUS: ast
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink((long)x++); // $ ir ast
|
||||
sink(x);
|
||||
|
||||
x = source();
|
||||
sink(b ? (long)x++ : 0); // $ ir ast
|
||||
sink(x); // $ ir ast
|
||||
}
|
||||
297
cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
Normal file
297
cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
using uint16_t = unsigned short;
|
||||
using int64_t = long long;
|
||||
using size_t = unsigned long;
|
||||
using uint8_t = unsigned char;
|
||||
using int32_t = int;
|
||||
using uint32_t = unsigned int;
|
||||
|
||||
namespace std
|
||||
{
|
||||
class string
|
||||
{
|
||||
public:
|
||||
string();
|
||||
string(const char *);
|
||||
~string();
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class map
|
||||
{
|
||||
public:
|
||||
map();
|
||||
~map();
|
||||
|
||||
V& operator[](const K& key);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class vector
|
||||
{
|
||||
public:
|
||||
vector();
|
||||
~vector();
|
||||
|
||||
T& operator[](size_t);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unique_ptr {
|
||||
public:
|
||||
unique_ptr();
|
||||
~unique_ptr();
|
||||
|
||||
T* get();
|
||||
};
|
||||
}
|
||||
|
||||
namespace Azure
|
||||
{
|
||||
template <typename T>
|
||||
class Nullable
|
||||
{
|
||||
public:
|
||||
Nullable();
|
||||
Nullable(const T);
|
||||
Nullable(const Nullable &);
|
||||
~Nullable();
|
||||
Nullable (Nullable &&);
|
||||
Nullable & operator= (const Nullable &);
|
||||
bool HasValue() const;
|
||||
const T & Value () const;
|
||||
T& Value ();
|
||||
const T * operator-> () const;
|
||||
T * operator-> ();
|
||||
const T & operator* () const;
|
||||
T & operator* ();
|
||||
};
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Url
|
||||
{
|
||||
public:
|
||||
Url();
|
||||
Url(const std::string &);
|
||||
void AppendPath(const std::string &encodedPath);
|
||||
void AppendQueryParameter(const std::string &encodedKey,
|
||||
const std::string &encodedValue);
|
||||
|
||||
static std::string Url::Decode(const std::string &value);
|
||||
static std::string Url::Encode(const std::string &value,
|
||||
const std::string &doNotEncodeSymbols = "");
|
||||
|
||||
std::string Url::GetAbsoluteUrl() const;
|
||||
const std::string &GetHost() const;
|
||||
const std::string &GetPath() const;
|
||||
uint16_t GetPort() const;
|
||||
std::map<std::string, std::string> GetQueryParameters() const;
|
||||
std::string Url::GetRelativeUrl() const;
|
||||
const std::string &GetScheme() const;
|
||||
void RemoveQueryParameter(const std::string &encodedKey);
|
||||
void SetHost(const std::string &encodedHost);
|
||||
void SetPath(const std::string &encodedPath);
|
||||
void SetPort(uint16_t port);
|
||||
void SetQueryParameters(std::map<std::string, std::string> queryParameters);
|
||||
void SetScheme(const std::string &scheme);
|
||||
};
|
||||
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
Context();
|
||||
};
|
||||
|
||||
namespace IO
|
||||
{
|
||||
class BodyStream
|
||||
{
|
||||
public:
|
||||
virtual ~BodyStream();
|
||||
virtual int64_t Length() const = 0;
|
||||
virtual void Rewind();
|
||||
size_t Read(uint8_t *buffer, size_t count, Azure::Core::Context const &context = Azure::Core::Context());
|
||||
size_t ReadToCount(uint8_t *buffer, size_t count, Azure::Core::Context const &context = Azure::Core::Context());
|
||||
std::vector<uint8_t> ReadToEnd(Azure::Core::Context const &context = Azure::Core::Context());
|
||||
};
|
||||
}
|
||||
|
||||
enum class HttpStatusCode {
|
||||
None = 0,
|
||||
Continue = 100,
|
||||
SwitchingProtocols = 101,
|
||||
Processing = 102,
|
||||
EarlyHints = 103,
|
||||
OK = 200,
|
||||
Created = 201,
|
||||
Accepted = 202,
|
||||
NonAuthoritativeInformation = 203,
|
||||
NoContent = 204,
|
||||
ResetContent = 205,
|
||||
PartialContent = 206,
|
||||
MultiStatus = 207,
|
||||
AlreadyReported = 208,
|
||||
IMUsed = 226,
|
||||
MultipleChoices = 300,
|
||||
MovedPermanently = 301,
|
||||
Found = 302,
|
||||
SeeOther = 303,
|
||||
NotModified = 304,
|
||||
UseProxy = 305,
|
||||
TemporaryRedirect = 307,
|
||||
PermanentRedirect = 308,
|
||||
BadRequest = 400,
|
||||
Unauthorized = 401,
|
||||
PaymentRequired = 402,
|
||||
Forbidden = 403,
|
||||
NotFound = 404,
|
||||
MethodNotAllowed = 405,
|
||||
NotAcceptable = 406,
|
||||
ProxyAuthenticationRequired = 407,
|
||||
RequestTimeout = 408,
|
||||
Conflict = 409,
|
||||
Gone = 410,
|
||||
LengthRequired = 411,
|
||||
PreconditionFailed = 412,
|
||||
PayloadTooLarge = 413,
|
||||
URITooLong = 414,
|
||||
UnsupportedMediaType = 415,
|
||||
RangeNotSatisfiable = 416,
|
||||
ExpectationFailed = 417,
|
||||
MisdirectedRequest = 421,
|
||||
UnprocessableEntity = 422,
|
||||
Locked = 423,
|
||||
FailedDependency = 424,
|
||||
TooEarly = 425,
|
||||
UpgradeRequired = 426,
|
||||
PreconditionRequired = 428,
|
||||
TooManyRequests = 429,
|
||||
RequestHeaderFieldsTooLarge = 431,
|
||||
UnavailableForLegalReasons = 451,
|
||||
InternalServerError = 500,
|
||||
NotImplemented = 501,
|
||||
BadGateway = 502,
|
||||
ServiceUnavailable = 503,
|
||||
GatewayTimeout = 504,
|
||||
HTTPVersionNotSupported = 505,
|
||||
VariantAlsoNegotiates = 506,
|
||||
InsufficientStorage = 507,
|
||||
LoopDetected = 508,
|
||||
NotExtended = 510,
|
||||
NetworkAuthenticationRequired = 511
|
||||
};
|
||||
|
||||
namespace Http
|
||||
{
|
||||
class HttpMethod
|
||||
{
|
||||
public:
|
||||
HttpMethod(std::string value);
|
||||
bool operator==(const HttpMethod &other) const;
|
||||
bool operator!=(const HttpMethod &other) const;
|
||||
const std::string &ToString() const;
|
||||
};
|
||||
|
||||
extern const HttpMethod Get;
|
||||
extern const HttpMethod Head;
|
||||
extern const HttpMethod Post;
|
||||
extern const HttpMethod Put;
|
||||
extern const HttpMethod Delete;
|
||||
extern const HttpMethod Patch;
|
||||
extern const HttpMethod Options;
|
||||
|
||||
class Request
|
||||
{
|
||||
public:
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
bool shouldBufferResponse);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
IO::BodyStream *bodyStream);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
IO::BodyStream *bodyStream,
|
||||
bool shouldBufferResponse);
|
||||
std::map<std::string, std::string> GetHeaders () const;
|
||||
Azure::Nullable<std::string> GetHeader(std::string const &name);
|
||||
IO::BodyStream * GetBodyStream();
|
||||
Azure::Core::IO::BodyStream const* GetBodyStream () const;
|
||||
};
|
||||
|
||||
class RawResponse {
|
||||
public:
|
||||
RawResponse (int32_t majorVersion, int32_t minorVersion, HttpStatusCode statusCode, std::string const &reasonPhrase);
|
||||
RawResponse (RawResponse const &response);
|
||||
RawResponse (RawResponse &&response);
|
||||
~RawResponse ();
|
||||
void SetHeader (std::string const &name, std::string const &value);
|
||||
void SetBodyStream (std::unique_ptr< Azure::Core::IO::BodyStream > stream);
|
||||
void SetBody (std::vector< uint8_t > body);
|
||||
uint32_t GetMajorVersion () const;
|
||||
uint32_t GetMinorVersion () const;
|
||||
HttpStatusCode GetStatusCode () const;
|
||||
std::string const & GetReasonPhrase () const;
|
||||
std::map<std::string, std::string>& GetHeaders () const;
|
||||
std::unique_ptr<Azure::Core::IO::BodyStream> ExtractBodyStream ();
|
||||
std::vector<uint8_t> & GetBody ();
|
||||
std::vector<uint8_t> const& GetBody() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sink(char);
|
||||
void sink(std::string);
|
||||
void sink(std::vector<uint8_t>);
|
||||
void sink(Azure::Nullable<std::string>);
|
||||
|
||||
void test_BodyStream() {
|
||||
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
|
||||
Azure::Core::IO::BodyStream * resp = request.GetBodyStream();
|
||||
|
||||
{
|
||||
unsigned char buffer[1024];
|
||||
resp->Read(buffer, sizeof(buffer));
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
unsigned char buffer[1024];
|
||||
resp->ReadToCount(buffer, sizeof(buffer));
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
std::vector<unsigned char> vec = resp->ReadToEnd();
|
||||
sink(vec); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
void test_RawResponse(Azure::Core::Http::RawResponse& resp) {
|
||||
{
|
||||
std::map<std::string, std::string> body = resp.GetHeaders();
|
||||
sink(body["Content-Type"]); // $ ir
|
||||
}
|
||||
{
|
||||
std::vector<uint8_t> body = resp.GetBody();
|
||||
sink(body); // $ ir
|
||||
}
|
||||
{
|
||||
std::unique_ptr<Azure::Core::IO::BodyStream> bodyStream = resp.ExtractBodyStream();
|
||||
sink(bodyStream.get()->ReadToEnd()); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
void test_GetHeader() {
|
||||
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
|
||||
{
|
||||
auto headerValue = request.GetHeader("Content-Type").Value();
|
||||
sink(headerValue); // $ ir
|
||||
}
|
||||
{
|
||||
std::map<std::string, std::string> headers = request.GetHeaders();
|
||||
std::string contentType = headers["Content-Type"];
|
||||
sink(contentType); // $ ir
|
||||
}
|
||||
}
|
||||
@@ -14,45 +14,111 @@ models
|
||||
| 13 | Source: ; ; false; NtReadFile; ; ; Argument[*5]; local; manual |
|
||||
| 14 | Source: ; ; false; ReadFile; ; ; Argument[*1]; local; manual |
|
||||
| 15 | Source: ; ; false; ReadFileEx; ; ; Argument[*1]; local; manual |
|
||||
| 16 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
|
||||
| 17 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
|
||||
| 18 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
|
||||
| 19 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 20 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 21 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 22 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
|
||||
| 23 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 24 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 25 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 26 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 27 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 28 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 29 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 30 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 31 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
|
||||
| 32 | Summary: ; ; false; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
|
||||
| 33 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 34 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 35 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 36 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 37 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
| 16 | Source: ; ; false; WinHttpQueryHeaders; ; ; Argument[*3]; remote; manual |
|
||||
| 17 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[**8]; remote; manual |
|
||||
| 18 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*5]; remote; manual |
|
||||
| 19 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*6]; remote; manual |
|
||||
| 20 | Source: ; ; false; WinHttpReadData; ; ; Argument[*1]; remote; manual |
|
||||
| 21 | Source: ; ; false; WinHttpReadDataEx; ; ; Argument[*1]; remote; manual |
|
||||
| 22 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
|
||||
| 23 | Source: Azure::Core::Http; RawResponse; true; ExtractBodyStream; ; ; ReturnValue[*]; remote; manual |
|
||||
| 24 | Source: Azure::Core::Http; RawResponse; true; GetBody; ; ; ReturnValue[*]; remote; manual |
|
||||
| 25 | Source: Azure::Core::Http; RawResponse; true; GetHeaders; ; ; ReturnValue[*]; remote; manual |
|
||||
| 26 | Source: Azure::Core::Http; Request; true; GetBodyStream; ; ; ReturnValue[*]; remote; manual |
|
||||
| 27 | Source: Azure::Core::Http; Request; true; GetHeader; ; ; ReturnValue; remote; manual |
|
||||
| 28 | Source: Azure::Core::Http; Request; true; GetHeaders; ; ; ReturnValue; remote; manual |
|
||||
| 29 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
|
||||
| 30 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
|
||||
| 31 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 32 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 33 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 34 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
|
||||
| 35 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 36 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 37 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 38 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 39 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 40 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 41 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 42 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 43 | Summary: ; ; false; WinHttpCrackUrl; ; ; Argument[*0]; Argument[*3]; taint; manual |
|
||||
| 44 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
|
||||
| 45 | Summary: ; ; false; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
|
||||
| 46 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 47 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 48 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 49 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 50 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 51 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 52 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||
| 53 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||
| 54 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
edges
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:37 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:17 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:17 Sink:MaD:2 |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:54 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:29 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:29 Sink:MaD:2 |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:100:64:100:71 | *send_str | provenance | TaintFunction |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:37 |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:35 |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:34 |
|
||||
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:36 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:54 |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:53 |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:50 |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:51 |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:52 |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:26 |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:50 |
|
||||
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:51 |
|
||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:52 |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
||||
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:273:62:273:64 | call to GetHeaders | provenance | Src:MaD:25 |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:10:274:29 | call to operator[] | provenance | |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:14:274:29 | call to operator[] | provenance | |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:277:45:277:47 | call to GetBody | provenance | Src:MaD:24 |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:23 |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:52 |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:53 |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:27 |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:290:10:290:20 | headerValue | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:293:58:293:67 | call to GetHeaders | provenance | Src:MaD:28 |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:294:38:294:53 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| azure.cpp:295:10:295:20 | contentType | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:48 |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:47 |
|
||||
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:49 |
|
||||
| test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | |
|
||||
| test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:1 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:17:24:17:24 | x | provenance | |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:21:27:21:27 | x | provenance | |
|
||||
@@ -61,15 +127,15 @@ edges
|
||||
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | |
|
||||
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:35 |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:48 |
|
||||
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | |
|
||||
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:34 |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:47 |
|
||||
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | |
|
||||
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:36 |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:49 |
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
|
||||
@@ -77,16 +143,16 @@ edges
|
||||
| test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | |
|
||||
| test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | |
|
||||
| test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 |
|
||||
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:33 |
|
||||
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:46 |
|
||||
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | |
|
||||
| test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | |
|
||||
| test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:16 |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:22 |
|
||||
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
|
||||
@@ -95,7 +161,7 @@ edges
|
||||
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:88:22:88:22 | y | test.cpp:89:11:89:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:97:26:97:26 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
|
||||
@@ -104,28 +170,28 @@ edges
|
||||
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:104:62:104:62 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:32 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:45 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:118:44:118:44 | *x | provenance | |
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | |
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:32 |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:18 |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:45 |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:30 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | |
|
||||
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | |
|
||||
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:30:8:30:15 | * ... | provenance | |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | provenance | |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:18 |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:30 |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:4 |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:36:10:36:13 | * ... | provenance | |
|
||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:5 |
|
||||
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:22 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:22 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:34 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:34 |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | |
|
||||
@@ -173,11 +239,11 @@ edges
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:12 |
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | |
|
||||
| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | provenance | |
|
||||
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:21 |
|
||||
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:33 |
|
||||
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:19 |
|
||||
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:31 |
|
||||
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:20 |
|
||||
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:32 |
|
||||
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:403:26:403:36 | *lpParameter [x] | windows.cpp:405:10:405:25 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:405:10:405:25 | *lpParameter [x] | windows.cpp:406:8:406:8 | *s [x] | provenance | |
|
||||
@@ -196,17 +262,17 @@ edges
|
||||
| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | provenance | |
|
||||
| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | provenance | |
|
||||
| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | provenance | |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:27 |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:23 |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:24 |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:25 |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:39 |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:35 |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:36 |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:37 |
|
||||
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | provenance | |
|
||||
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:26 |
|
||||
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:38 |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | provenance | |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:29 |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:30 |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:28 |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:41 |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:42 |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:40 |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | provenance | |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | |
|
||||
@@ -218,37 +284,51 @@ edges
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:573:40:573:41 | *& ... | provenance | |
|
||||
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | windows.cpp:538:10:538:23 | access to array | provenance | |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | provenance | |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:27 |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:39 |
|
||||
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | windows.cpp:543:10:543:23 | access to array | provenance | |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | provenance | |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:23 |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:35 |
|
||||
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | windows.cpp:548:10:548:23 | access to array | provenance | |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | provenance | |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:24 |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:36 |
|
||||
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | windows.cpp:553:10:553:23 | access to array | provenance | |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | provenance | |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:25 |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:37 |
|
||||
| windows.cpp:559:5:559:24 | ... = ... | windows.cpp:561:39:561:44 | *buffer | provenance | |
|
||||
| windows.cpp:559:17:559:24 | call to source | windows.cpp:559:5:559:24 | ... = ... | provenance | |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:562:10:562:19 | *src_string [*Buffer] | provenance | |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:563:40:563:50 | *& ... [*Buffer] | provenance | |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | provenance | |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:28 |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:40 |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:10:562:29 | access to array | provenance | |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:21:562:26 | *Buffer | provenance | |
|
||||
| windows.cpp:562:21:562:26 | *Buffer | windows.cpp:562:10:562:29 | access to array | provenance | |
|
||||
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | windows.cpp:564:10:564:20 | *dest_string [*Buffer] | provenance | |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:26 |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:38 |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:10:564:30 | access to array | provenance | |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:22:564:27 | *Buffer | provenance | |
|
||||
| windows.cpp:564:22:564:27 | *Buffer | windows.cpp:564:10:564:30 | access to array | provenance | |
|
||||
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | windows.cpp:569:10:569:23 | access to array | provenance | |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | provenance | |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:29 |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:41 |
|
||||
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | windows.cpp:574:10:574:23 | access to array | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:30 |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:42 |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:20 |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:21 |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | windows.cpp:661:10:661:16 | * ... | provenance | Src:MaD:16 |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:18 |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:19 |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:17 |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | provenance | MaD:43 |
|
||||
| windows.cpp:728:5:728:28 | ... = ... | windows.cpp:729:35:729:35 | *x | provenance | |
|
||||
| windows.cpp:728:12:728:28 | call to source | windows.cpp:728:5:728:28 | ... = ... | provenance | |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | provenance | |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:43 |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:731:10:731:36 | * ... | provenance | |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:733:10:733:35 | * ... | provenance | |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:735:10:735:37 | * ... | provenance | |
|
||||
nodes
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer |
|
||||
@@ -262,6 +342,59 @@ nodes
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | semmle.label | *send_str |
|
||||
| asio_streams.cpp:101:7:101:17 | send_buffer | semmle.label | send_buffer |
|
||||
| asio_streams.cpp:103:29:103:39 | *send_buffer | semmle.label | *send_buffer |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | semmle.label | [summary param] this in Value |
|
||||
| azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | semmle.label | [summary] to write: ReturnValue[*] in Value |
|
||||
| azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | semmle.label | [summary param] *0 in Read [Return] |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | semmle.label | [summary param] this in Read |
|
||||
| azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | semmle.label | [summary param] *0 in ReadToCount [Return] |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | semmle.label | [summary param] this in ReadToCount |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | semmle.label | [summary param] this in ReadToEnd |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | semmle.label | [summary] to write: ReturnValue in ReadToEnd [element] |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | semmle.label | [summary] to write: ReturnValue.Element in ReadToEnd |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
|
||||
| azure.cpp:257:5:257:8 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:257:16:257:21 | Read output argument | semmle.label | Read output argument |
|
||||
| azure.cpp:258:10:258:16 | * ... | semmle.label | * ... |
|
||||
| azure.cpp:262:5:262:8 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | semmle.label | ReadToCount output argument |
|
||||
| azure.cpp:263:10:263:16 | * ... | semmle.label | * ... |
|
||||
| azure.cpp:266:38:266:41 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:267:10:267:12 | vec | semmle.label | vec |
|
||||
| azure.cpp:267:10:267:12 | vec [element] | semmle.label | vec [element] |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:274:10:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
|
||||
| azure.cpp:282:10:282:38 | call to ReadToEnd | semmle.label | call to ReadToEnd |
|
||||
| azure.cpp:282:21:282:23 | *call to get | semmle.label | *call to get |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
|
||||
| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | semmle.label | [summary param] 0 in ymlStepManual |
|
||||
| test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | semmle.label | [summary] to write: ReturnValue in ymlStepManual |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | semmle.label | [summary param] 0 in ymlStepGenerated |
|
||||
@@ -482,8 +615,34 @@ nodes
|
||||
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | semmle.label | RtlMoveVolatileMemory output argument |
|
||||
| windows.cpp:573:40:573:41 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:574:10:574:23 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | semmle.label | WinHttpReadData output argument |
|
||||
| windows.cpp:647:10:647:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | semmle.label | WinHttpReadDataEx output argument |
|
||||
| windows.cpp:654:10:654:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | semmle.label | WinHttpQueryHeaders output argument |
|
||||
| windows.cpp:661:10:661:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:671:10:671:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:673:10:673:29 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:675:10:675:27 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | semmle.label | [summary param] *0 in WinHttpCrackUrl |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | semmle.label | [summary param] *3 in WinHttpCrackUrl [Return] |
|
||||
| windows.cpp:728:5:728:28 | ... = ... | semmle.label | ... = ... |
|
||||
| windows.cpp:728:12:728:28 | call to source | semmle.label | call to source |
|
||||
| windows.cpp:729:35:729:35 | *x | semmle.label | *x |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | semmle.label | WinHttpCrackUrl output argument |
|
||||
| windows.cpp:731:10:731:36 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:733:10:733:35 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:735:10:735:37 | * ... | semmle.label | * ... |
|
||||
subpaths
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | azure.cpp:257:16:257:21 | Read output argument |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | azure.cpp:262:23:262:28 | ReadToCount output argument |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | azure.cpp:289:63:289:65 | call to Value |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
@@ -498,4 +657,5 @@ subpaths
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | windows.cpp:568:19:568:29 | RtlMoveMemory output argument |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |
|
||||
testFailures
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | remote |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | remote |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | remote |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | remote |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | remote |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | remote |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | remote |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | local |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | local |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | local |
|
||||
@@ -20,3 +26,9 @@
|
||||
| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | local |
|
||||
| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | local |
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | local |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | remote |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | remote |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | remote |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | remote |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | remote |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | remote |
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer |
|
||||
| azure.cpp:252:79:252:98 | call to string | azure.cpp:252:62:252:99 | call to Url |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument |
|
||||
| azure.cpp:287:79:287:98 | call to string | azure.cpp:287:62:287:99 | call to Url |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
| test.cpp:28:35:28:35 | 0 | test.cpp:28:11:28:33 | call to ymlStepManual_with_body |
|
||||
| test.cpp:32:38:32:38 | 0 | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
|
||||
| test.cpp:35:38:35:38 | x | test.cpp:35:11:35:36 | call to ymlStepGenerated_with_body |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |
|
||||
|
||||
@@ -5586,3 +5586,6 @@
|
||||
| Unrecognized output specification "Field[***hEvent]" in summary model. |
|
||||
| Unrecognized output specification "Parameter[***0]" in summary model. |
|
||||
| Unrecognized output specification "Parameter[****0]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[*****]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[****]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[***]" in summary model. |
|
||||
|
||||
@@ -573,4 +573,165 @@ void test_copy_and_move_memory() {
|
||||
RtlMoveVolatileMemory(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
using HINTERNET = void*;
|
||||
using ULONGLONG = unsigned long long;
|
||||
using UINT = unsigned int;
|
||||
using PDWORD = DWORD*;
|
||||
using PCSTR = const char*;
|
||||
typedef union _WINHTTP_HEADER_NAME {
|
||||
PCWSTR pwszName;
|
||||
PCSTR pszName;
|
||||
} WINHTTP_HEADER_NAME, *PWINHTTP_HEADER_NAME;
|
||||
typedef struct _WINHTTP_EXTENDED_HEADER {
|
||||
union {
|
||||
PCWSTR pwszName;
|
||||
PCSTR pszName;
|
||||
};
|
||||
union {
|
||||
PCWSTR pwszValue;
|
||||
PCSTR pszValue;
|
||||
};
|
||||
} WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER;
|
||||
|
||||
BOOL WinHttpReadData(
|
||||
HINTERNET hRequest,
|
||||
LPVOID lpBuffer,
|
||||
DWORD dwNumberOfBytesToRead,
|
||||
LPDWORD lpdwNumberOfBytesRead
|
||||
);
|
||||
|
||||
DWORD WinHttpReadDataEx(
|
||||
HINTERNET hRequest,
|
||||
LPVOID lpBuffer,
|
||||
DWORD dwNumberOfBytesToRead,
|
||||
LPDWORD lpdwNumberOfBytesRead,
|
||||
ULONGLONG ullFlags,
|
||||
DWORD cbProperty,
|
||||
PVOID pvProperty
|
||||
);
|
||||
|
||||
using LPCWSTR = const wchar_t*;
|
||||
|
||||
BOOL WinHttpQueryHeaders(
|
||||
HINTERNET hRequest,
|
||||
DWORD dwInfoLevel,
|
||||
LPCWSTR pwszName,
|
||||
LPVOID lpBuffer,
|
||||
LPDWORD lpdwBufferLength,
|
||||
LPDWORD lpdwIndex
|
||||
);
|
||||
|
||||
DWORD WinHttpQueryHeadersEx(
|
||||
HINTERNET hRequest,
|
||||
DWORD dwInfoLevel,
|
||||
ULONGLONG ullFlags,
|
||||
UINT uiCodePage,
|
||||
PDWORD pdwIndex,
|
||||
PWINHTTP_HEADER_NAME pHeaderName,
|
||||
PVOID pBuffer,
|
||||
PDWORD pdwBufferLength,
|
||||
PWINHTTP_EXTENDED_HEADER *ppHeaders,
|
||||
PDWORD pdwHeadersCount
|
||||
);
|
||||
|
||||
void sink(PCSTR);
|
||||
|
||||
void test_winhttp(HINTERNET hRequest) {
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bytesRead;
|
||||
BOOL result = WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bytesRead;
|
||||
DWORD result = WinHttpReadDataEx(hRequest, buffer, sizeof(buffer), &bytesRead, 0, 0, nullptr);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bufferLength = sizeof(buffer);
|
||||
WinHttpQueryHeaders(hRequest, 0, nullptr, buffer, &bufferLength, nullptr);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bufferLength = sizeof(buffer);
|
||||
PWINHTTP_EXTENDED_HEADER headers;
|
||||
DWORD headersCount;
|
||||
PWINHTTP_HEADER_NAME headerName;
|
||||
DWORD result = WinHttpQueryHeadersEx(hRequest, 0, 0, 0, nullptr, headerName, buffer, &bufferLength, &headers, &headersCount);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
sink(headerName->pszName);
|
||||
sink(*headerName->pszName); // $ ir
|
||||
sink(headers->pszValue);
|
||||
sink(*headers->pszValue); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
using LPWSTR = wchar_t*;
|
||||
using INTERNET_SCHEME = enum {
|
||||
INTERNET_SCHEME_INVALID = -1,
|
||||
INTERNET_SCHEME_UNKNOWN = 0,
|
||||
INTERNET_SCHEME_HTTP = 1,
|
||||
INTERNET_SCHEME_HTTPS = 2,
|
||||
INTERNET_SCHEME_FTP = 3,
|
||||
INTERNET_SCHEME_FILE = 4,
|
||||
INTERNET_SCHEME_NEWS = 5,
|
||||
INTERNET_SCHEME_MAILTO = 6,
|
||||
INTERNET_SCHEME_SNEWS = 7,
|
||||
INTERNET_SCHEME_SOCKS = 8,
|
||||
INTERNET_SCHEME_WAIS = 9,
|
||||
INTERNET_SCHEME_LAST = 10
|
||||
};
|
||||
using INTERNET_PORT = unsigned short;
|
||||
|
||||
typedef struct _WINHTTP_URL_COMPONENTS {
|
||||
DWORD dwStructSize;
|
||||
LPWSTR lpszScheme;
|
||||
DWORD dwSchemeLength;
|
||||
INTERNET_SCHEME nScheme;
|
||||
LPWSTR lpszHostName;
|
||||
DWORD dwHostNameLength;
|
||||
INTERNET_PORT nPort;
|
||||
LPWSTR lpszUserName;
|
||||
DWORD dwUserNameLength;
|
||||
LPWSTR lpszPassword;
|
||||
DWORD dwPasswordLength;
|
||||
LPWSTR lpszUrlPath;
|
||||
DWORD dwUrlPathLength;
|
||||
LPWSTR lpszExtraInfo;
|
||||
DWORD dwExtraInfoLength;
|
||||
} URL_COMPONENTS, *LPURL_COMPONENTS;
|
||||
|
||||
BOOL WinHttpCrackUrl(
|
||||
LPCWSTR pwszUrl,
|
||||
DWORD dwUrlLength,
|
||||
DWORD dwFlags,
|
||||
LPURL_COMPONENTS lpUrlComponents
|
||||
);
|
||||
|
||||
void sink(LPWSTR);
|
||||
|
||||
void test_winhttp_crack_url() {
|
||||
{
|
||||
URL_COMPONENTS urlComponents;
|
||||
urlComponents.dwStructSize = sizeof(URL_COMPONENTS);
|
||||
wchar_t x[256];
|
||||
x[0] = (wchar_t)source();
|
||||
BOOL result = WinHttpCrackUrl(x, 0, 0, &urlComponents);
|
||||
sink(urlComponents.lpszHostName);
|
||||
sink(*urlComponents.lpszHostName); // $ ir
|
||||
sink(urlComponents.lpszUrlPath);
|
||||
sink(*urlComponents.lpszUrlPath); // $ ir
|
||||
sink(urlComponents.lpszExtraInfo);
|
||||
sink(*urlComponents.lpszExtraInfo); // $ ir
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,38 @@ void testCheckArgument(int p) {
|
||||
if (checkArgument(&p)) {
|
||||
sink(p); // $ barrier=glval<int> indirect_barrier=int
|
||||
}
|
||||
}
|
||||
|
||||
int* get_clean_value(int* x) { return x; }
|
||||
bool is_clean_value(int*);
|
||||
|
||||
int* get_clean_pointer(int* x) { return x; }
|
||||
bool is_clean_pointer(int*);
|
||||
|
||||
void sink(int*);
|
||||
|
||||
void test_mad(int x, int* p) {
|
||||
{
|
||||
if(is_clean_value(&x)) {
|
||||
sink(x); // $ external=int
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if(is_clean_value(p)) {
|
||||
sink(*p); // $ external=int
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if(is_clean_pointer(p)) {
|
||||
sink(p); // $ external=int*
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if(is_clean_pointer(&x)) {
|
||||
sink(x); // $ external=glval<int>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: barrierModel
|
||||
data:
|
||||
- ["", "", False, "get_clean_pointer", "", "", "ReturnValue", "test-barrier", "manual"]
|
||||
- ["", "", False, "get_clean_data", "", "", "ReturnValue[*]", "test-barrier", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: barrierGuardModel
|
||||
data:
|
||||
- ["", "", False, "is_clean_value", "", "", "Argument[*0]", "true", "test-barrier", "manual"]
|
||||
- ["", "", False, "is_clean_pointer", "", "", "Argument[0]", "true", "test-barrier", "manual"]
|
||||
@@ -2,6 +2,7 @@ import cpp
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import semmle.code.cpp.controlflow.IRGuards
|
||||
import utils.test.InlineExpectationsTest
|
||||
import semmle.code.cpp.dataflow.ExternalFlow
|
||||
|
||||
predicate instructionGuardChecks(IRGuardCondition gc, Instruction checked, boolean branch) {
|
||||
exists(CallInstruction call |
|
||||
@@ -27,18 +28,26 @@ predicate barrierGuard(DataFlow::Node node, string s) {
|
||||
else s = node.getType().toString().replaceAll(" ", "")
|
||||
}
|
||||
|
||||
predicate externalBarrierGuard(DataFlow::Node node, string s) {
|
||||
barrierNode(node, "test-barrier") and
|
||||
if node.isGLValue()
|
||||
then s = "glval<" + node.getType().toString().replaceAll(" ", "") + ">"
|
||||
else s = node.getType().toString().replaceAll(" ", "")
|
||||
}
|
||||
|
||||
module Test implements TestSig {
|
||||
string getARelevantTag() { result = ["barrier", "indirect_barrier"] }
|
||||
string getARelevantTag() { result = ["barrier", "indirect_barrier", "external"] }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(DataFlow::Node node, string s |
|
||||
indirectBarrierGuard(node, s) and
|
||||
value = s and
|
||||
exists(DataFlow::Node node |
|
||||
indirectBarrierGuard(node, value) and
|
||||
tag = "indirect_barrier"
|
||||
or
|
||||
barrierGuard(node, s) and
|
||||
value = s and
|
||||
barrierGuard(node, value) and
|
||||
tag = "barrier"
|
||||
or
|
||||
externalBarrierGuard(node, value) and
|
||||
tag = "external"
|
||||
|
|
||||
element = node.toString() and
|
||||
location = node.getLocation()
|
||||
|
||||
@@ -25131,6 +25131,517 @@ ir.cpp:
|
||||
# 2823| Type = [ArrayType] int[]
|
||||
# 2823| ValueCategory = lvalue
|
||||
# 2824| getStmt(5): [ReturnStmt] return ...
|
||||
# 2830| [TopLevelFunction] void test_assert_simple(int, int, unsigned int, int)
|
||||
# 2830| <params>:
|
||||
# 2830| getParameter(0): [Parameter] x
|
||||
# 2830| Type = [IntType] int
|
||||
# 2830| getParameter(1): [Parameter] y
|
||||
# 2830| Type = [IntType] int
|
||||
# 2830| getParameter(2): [Parameter] u
|
||||
# 2830| Type = [IntType] unsigned int
|
||||
# 2830| getParameter(3): [Parameter] shadowed
|
||||
# 2830| Type = [IntType] int
|
||||
# 2830| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2831| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2831| getExpr(): [Literal] 0
|
||||
# 2831| Type = [IntType] int
|
||||
# 2831| Value = [Literal] 0
|
||||
# 2831| ValueCategory = prvalue
|
||||
# 2831| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2831| Type = [VoidType] void
|
||||
# 2831| ValueCategory = prvalue
|
||||
# 2831| getExpr(): [CStyleCast] (void)...
|
||||
# 2831| Conversion = [VoidConversion] conversion to void
|
||||
# 2831| Type = [VoidType] void
|
||||
# 2831| ValueCategory = prvalue
|
||||
# 2832| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2832| getExpr(): [Literal] 0
|
||||
# 2832| Type = [IntType] int
|
||||
# 2832| Value = [Literal] 0
|
||||
# 2832| ValueCategory = prvalue
|
||||
# 2832| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2832| Type = [VoidType] void
|
||||
# 2832| ValueCategory = prvalue
|
||||
# 2832| getExpr(): [CStyleCast] (void)...
|
||||
# 2832| Conversion = [VoidConversion] conversion to void
|
||||
# 2832| Type = [VoidType] void
|
||||
# 2832| ValueCategory = prvalue
|
||||
# 2833| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2833| getExpr(): [Literal] 0
|
||||
# 2833| Type = [IntType] int
|
||||
# 2833| Value = [Literal] 0
|
||||
# 2833| ValueCategory = prvalue
|
||||
# 2833| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2833| Type = [VoidType] void
|
||||
# 2833| ValueCategory = prvalue
|
||||
# 2833| getExpr(): [CStyleCast] (void)...
|
||||
# 2833| Conversion = [VoidConversion] conversion to void
|
||||
# 2833| Type = [VoidType] void
|
||||
# 2833| ValueCategory = prvalue
|
||||
# 2835| getStmt(3): [EmptyStmt] ;
|
||||
# 2837| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 2837| getExpr(): [Literal] 0
|
||||
# 2837| Type = [IntType] int
|
||||
# 2837| Value = [Literal] 0
|
||||
# 2837| ValueCategory = prvalue
|
||||
# 2837| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2837| Type = [VoidType] void
|
||||
# 2837| ValueCategory = prvalue
|
||||
# 2837| getExpr(): [CStyleCast] (void)...
|
||||
# 2837| Conversion = [VoidConversion] conversion to void
|
||||
# 2837| Type = [VoidType] void
|
||||
# 2837| ValueCategory = prvalue
|
||||
# 2839| getStmt(5): [BlockStmt] { ... }
|
||||
# 2840| getStmt(0): [DeclStmt] declaration
|
||||
# 2840| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
|
||||
# 2840| Type = [IntType] int
|
||||
# 2840| getVariable().getInitializer(): [Initializer] initializer for shadowed
|
||||
# 2840| getExpr(): [VariableAccess] x
|
||||
# 2840| Type = [IntType] int
|
||||
# 2840| ValueCategory = prvalue(load)
|
||||
# 2841| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2841| getExpr(): [Literal] 0
|
||||
# 2841| Type = [IntType] int
|
||||
# 2841| Value = [Literal] 0
|
||||
# 2841| ValueCategory = prvalue
|
||||
# 2841| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2841| Type = [VoidType] void
|
||||
# 2841| ValueCategory = prvalue
|
||||
# 2841| getExpr(): [CStyleCast] (void)...
|
||||
# 2841| Conversion = [VoidConversion] conversion to void
|
||||
# 2841| Type = [VoidType] void
|
||||
# 2841| ValueCategory = prvalue
|
||||
# 2843| getStmt(6): [ReturnStmt] return ...
|
||||
# 2846| [TemplateFunction,TopLevelFunction] void test_assert_in_template<T>(T, int, unsigned int)
|
||||
# 2846| <params>:
|
||||
# 2846| getParameter(0): [Parameter] x
|
||||
# 2846| Type = [TypeTemplateParameter] T
|
||||
# 2846| getParameter(1): [Parameter] y
|
||||
# 2846| Type = [IntType] int
|
||||
# 2846| getParameter(2): [Parameter] u
|
||||
# 2846| Type = [IntType] unsigned int
|
||||
# 2846| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2847| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2847| getExpr(): [Literal] 0
|
||||
# 2847| Type = [IntType] int
|
||||
# 2847| Value = [Literal] 0
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2847| Type = [VoidType] void
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2847| getExpr(): [CStyleCast] (void)...
|
||||
# 2847| Conversion = [VoidConversion] conversion to void
|
||||
# 2847| Type = [VoidType] void
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2848| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2848| getExpr(): [Literal] 0
|
||||
# 2848| Type = [IntType] int
|
||||
# 2848| Value = [Literal] 0
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2848| Type = [VoidType] void
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2848| getExpr(): [CStyleCast] (void)...
|
||||
# 2848| Conversion = [VoidConversion] conversion to void
|
||||
# 2848| Type = [VoidType] void
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2849| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2849| getExpr(): [Literal] 0
|
||||
# 2849| Type = [IntType] int
|
||||
# 2849| Value = [Literal] 0
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2849| Type = [VoidType] void
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2849| getExpr(): [CStyleCast] (void)...
|
||||
# 2849| Conversion = [VoidConversion] conversion to void
|
||||
# 2849| Type = [VoidType] void
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2851| getStmt(3): [EmptyStmt] ;
|
||||
# 2853| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 2853| getExpr(): [Literal] 0
|
||||
# 2853| Type = [IntType] int
|
||||
# 2853| Value = [Literal] 0
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2853| Type = [VoidType] void
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2853| getExpr(): [CStyleCast] (void)...
|
||||
# 2853| Conversion = [VoidConversion] conversion to void
|
||||
# 2853| Type = [VoidType] void
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2855| getStmt(5): [BlockStmt] { ... }
|
||||
# 2856| getStmt(0): [DeclStmt] declaration
|
||||
# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
|
||||
# 2856| Type = [IntType] int
|
||||
# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed
|
||||
# 2856| getExpr(): [VariableAccess] x
|
||||
# 2856| Type = [TypeTemplateParameter] T
|
||||
# 2856| ValueCategory = lvalue
|
||||
# 2856| getExpr().getFullyConverted(): [CStyleCast] (int)...
|
||||
# 2856| Type = [IntType] int
|
||||
# 2856| ValueCategory = prvalue
|
||||
# 2857| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2857| getExpr(): [Literal] 0
|
||||
# 2857| Type = [IntType] int
|
||||
# 2857| Value = [Literal] 0
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2857| Type = [VoidType] void
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2857| getExpr(): [CStyleCast] (void)...
|
||||
# 2857| Conversion = [VoidConversion] conversion to void
|
||||
# 2857| Type = [VoidType] void
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2859| getStmt(6): [ExprStmt] ExprStmt
|
||||
# 2859| getExpr(): [Literal] 0
|
||||
# 2859| Type = [IntType] int
|
||||
# 2859| Value = [Literal] 0
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2859| Type = [VoidType] void
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2859| getExpr(): [CStyleCast] (void)...
|
||||
# 2859| Conversion = [VoidConversion] conversion to void
|
||||
# 2859| Type = [VoidType] void
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2860| getStmt(7): [ReturnStmt] return ...
|
||||
# 2846| [FunctionTemplateInstantiation,TopLevelFunction] void test_assert_in_template<int>(int, int, unsigned int)
|
||||
# 2846| <params>:
|
||||
# 2846| getParameter(0): [Parameter] x
|
||||
# 2846| Type = [IntType] int
|
||||
# 2846| getParameter(1): [Parameter] y
|
||||
# 2846| Type = [IntType] int
|
||||
# 2846| getParameter(2): [Parameter] u
|
||||
# 2846| Type = [IntType] unsigned int
|
||||
# 2846| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2847| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2847| getExpr(): [Literal] 0
|
||||
# 2847| Type = [IntType] int
|
||||
# 2847| Value = [Literal] 0
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2847| Type = [VoidType] void
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2847| getExpr(): [CStyleCast] (void)...
|
||||
# 2847| Conversion = [VoidConversion] conversion to void
|
||||
# 2847| Type = [VoidType] void
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2848| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2848| getExpr(): [Literal] 0
|
||||
# 2848| Type = [IntType] int
|
||||
# 2848| Value = [Literal] 0
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2848| Type = [VoidType] void
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2848| getExpr(): [CStyleCast] (void)...
|
||||
# 2848| Conversion = [VoidConversion] conversion to void
|
||||
# 2848| Type = [VoidType] void
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2849| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2849| getExpr(): [Literal] 0
|
||||
# 2849| Type = [IntType] int
|
||||
# 2849| Value = [Literal] 0
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2849| Type = [VoidType] void
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2849| getExpr(): [CStyleCast] (void)...
|
||||
# 2849| Conversion = [VoidConversion] conversion to void
|
||||
# 2849| Type = [VoidType] void
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2851| getStmt(3): [EmptyStmt] ;
|
||||
# 2853| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 2853| getExpr(): [Literal] 0
|
||||
# 2853| Type = [IntType] int
|
||||
# 2853| Value = [Literal] 0
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2853| Type = [VoidType] void
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2853| getExpr(): [CStyleCast] (void)...
|
||||
# 2853| Conversion = [VoidConversion] conversion to void
|
||||
# 2853| Type = [VoidType] void
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2855| getStmt(5): [BlockStmt] { ... }
|
||||
# 2856| getStmt(0): [DeclStmt] declaration
|
||||
# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
|
||||
# 2856| Type = [IntType] int
|
||||
# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed
|
||||
# 2856| getExpr(): [VariableAccess] x
|
||||
# 2856| Type = [IntType] int
|
||||
# 2856| ValueCategory = prvalue(load)
|
||||
# 2857| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2857| getExpr(): [Literal] 0
|
||||
# 2857| Type = [IntType] int
|
||||
# 2857| Value = [Literal] 0
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2857| Type = [VoidType] void
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2857| getExpr(): [CStyleCast] (void)...
|
||||
# 2857| Conversion = [VoidConversion] conversion to void
|
||||
# 2857| Type = [VoidType] void
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2859| getStmt(6): [ExprStmt] ExprStmt
|
||||
# 2859| getExpr(): [Literal] 0
|
||||
# 2859| Type = [IntType] int
|
||||
# 2859| Value = [Literal] 0
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2859| Type = [VoidType] void
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2859| getExpr(): [CStyleCast] (void)...
|
||||
# 2859| Conversion = [VoidConversion] conversion to void
|
||||
# 2859| Type = [VoidType] void
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2860| getStmt(7): [ReturnStmt] return ...
|
||||
# 2846| [FunctionTemplateInstantiation,TopLevelFunction] void test_assert_in_template<short>(short, int, unsigned int)
|
||||
# 2846| <params>:
|
||||
# 2846| getParameter(0): [Parameter] x
|
||||
# 2846| Type = [ShortType] short
|
||||
# 2846| getParameter(1): [Parameter] y
|
||||
# 2846| Type = [IntType] int
|
||||
# 2846| getParameter(2): [Parameter] u
|
||||
# 2846| Type = [IntType] unsigned int
|
||||
# 2846| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2847| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2847| getExpr(): [Literal] 0
|
||||
# 2847| Type = [IntType] int
|
||||
# 2847| Value = [Literal] 0
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2847| Type = [VoidType] void
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2847| getExpr(): [CStyleCast] (void)...
|
||||
# 2847| Conversion = [VoidConversion] conversion to void
|
||||
# 2847| Type = [VoidType] void
|
||||
# 2847| ValueCategory = prvalue
|
||||
# 2848| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2848| getExpr(): [Literal] 0
|
||||
# 2848| Type = [IntType] int
|
||||
# 2848| Value = [Literal] 0
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2848| Type = [VoidType] void
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2848| getExpr(): [CStyleCast] (void)...
|
||||
# 2848| Conversion = [VoidConversion] conversion to void
|
||||
# 2848| Type = [VoidType] void
|
||||
# 2848| ValueCategory = prvalue
|
||||
# 2849| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2849| getExpr(): [Literal] 0
|
||||
# 2849| Type = [IntType] int
|
||||
# 2849| Value = [Literal] 0
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2849| Type = [VoidType] void
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2849| getExpr(): [CStyleCast] (void)...
|
||||
# 2849| Conversion = [VoidConversion] conversion to void
|
||||
# 2849| Type = [VoidType] void
|
||||
# 2849| ValueCategory = prvalue
|
||||
# 2851| getStmt(3): [EmptyStmt] ;
|
||||
# 2853| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 2853| getExpr(): [Literal] 0
|
||||
# 2853| Type = [IntType] int
|
||||
# 2853| Value = [Literal] 0
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2853| Type = [VoidType] void
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2853| getExpr(): [CStyleCast] (void)...
|
||||
# 2853| Conversion = [VoidConversion] conversion to void
|
||||
# 2853| Type = [VoidType] void
|
||||
# 2853| ValueCategory = prvalue
|
||||
# 2855| getStmt(5): [BlockStmt] { ... }
|
||||
# 2856| getStmt(0): [DeclStmt] declaration
|
||||
# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
|
||||
# 2856| Type = [IntType] int
|
||||
# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed
|
||||
# 2856| getExpr(): [VariableAccess] x
|
||||
# 2856| Type = [ShortType] short
|
||||
# 2856| ValueCategory = prvalue(load)
|
||||
# 2856| getExpr().getFullyConverted(): [CStyleCast] (int)...
|
||||
# 2856| Conversion = [IntegralConversion] integral conversion
|
||||
# 2856| Type = [IntType] int
|
||||
# 2856| ValueCategory = prvalue
|
||||
# 2857| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2857| getExpr(): [Literal] 0
|
||||
# 2857| Type = [IntType] int
|
||||
# 2857| Value = [Literal] 0
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2857| Type = [VoidType] void
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2857| getExpr(): [CStyleCast] (void)...
|
||||
# 2857| Conversion = [VoidConversion] conversion to void
|
||||
# 2857| Type = [VoidType] void
|
||||
# 2857| ValueCategory = prvalue
|
||||
# 2859| getStmt(6): [ExprStmt] ExprStmt
|
||||
# 2859| getExpr(): [Literal] 0
|
||||
# 2859| Type = [IntType] int
|
||||
# 2859| Value = [Literal] 0
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2859| Type = [VoidType] void
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2859| getExpr(): [CStyleCast] (void)...
|
||||
# 2859| Conversion = [VoidConversion] conversion to void
|
||||
# 2859| Type = [VoidType] void
|
||||
# 2859| ValueCategory = prvalue
|
||||
# 2860| getStmt(7): [ReturnStmt] return ...
|
||||
# 2867| [TopLevelFunction] void (unnamed namespace)::complex_assertions(int, bool, int)
|
||||
# 2867| <params>:
|
||||
# 2867| getParameter(0): [Parameter] x
|
||||
# 2867| Type = [IntType] int
|
||||
# 2867| getParameter(1): [Parameter] b
|
||||
# 2867| Type = [BoolType] bool
|
||||
# 2867| getParameter(2): [Parameter] max
|
||||
# 2867| Type = [IntType] int
|
||||
# 2867| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2868| getStmt(0): [DeclStmt] declaration
|
||||
# 2868| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
|
||||
# 2868| Type = [IntType] int
|
||||
# 2868| getVariable().getInitializer(): [Initializer] initializer for y
|
||||
# 2868| getExpr(): [CommaExpr] ... , ...
|
||||
# 2868| Type = [IntType] int
|
||||
# 2868| ValueCategory = prvalue(load)
|
||||
# 2868| getLeftOperand(): [Literal] 0
|
||||
# 2868| Type = [IntType] int
|
||||
# 2868| Value = [Literal] 0
|
||||
# 2868| ValueCategory = prvalue
|
||||
# 2868| getRightOperand(): [VariableAccess] x
|
||||
# 2868| Type = [IntType] int
|
||||
# 2868| ValueCategory = prvalue(load)
|
||||
# 2868| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2868| Type = [VoidType] void
|
||||
# 2868| ValueCategory = prvalue
|
||||
# 2868| getExpr(): [CStyleCast] (void)...
|
||||
# 2868| Conversion = [VoidConversion] conversion to void
|
||||
# 2868| Type = [VoidType] void
|
||||
# 2868| ValueCategory = prvalue
|
||||
# 2868| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2868| Type = [IntType] int
|
||||
# 2868| ValueCategory = prvalue(load)
|
||||
# 2869| getStmt(1): [DeclStmt] declaration
|
||||
# 2869| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z
|
||||
# 2869| Type = [IntType] int
|
||||
# 2869| getVariable().getInitializer(): [Initializer] initializer for z
|
||||
# 2869| getExpr(): [ConditionalExpr] ... ? ... : ...
|
||||
# 2869| Type = [IntType] int
|
||||
# 2869| ValueCategory = prvalue
|
||||
# 2869| getCondition(): [VariableAccess] b
|
||||
# 2869| Type = [BoolType] bool
|
||||
# 2869| ValueCategory = prvalue(load)
|
||||
# 2869| getThen(): [CommaExpr] ... , ...
|
||||
# 2869| Type = [IntType] int
|
||||
# 2869| Value = [CommaExpr] 0
|
||||
# 2869| ValueCategory = prvalue
|
||||
# 2869| getLeftOperand(): [Literal] 0
|
||||
# 2869| Type = [IntType] int
|
||||
# 2869| Value = [Literal] 0
|
||||
# 2869| ValueCategory = prvalue
|
||||
# 2869| getRightOperand(): [Literal] 0
|
||||
# 2869| Type = [IntType] int
|
||||
# 2869| Value = [Literal] 0
|
||||
# 2869| ValueCategory = prvalue
|
||||
# 2869| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2869| Type = [VoidType] void
|
||||
# 2869| ValueCategory = prvalue
|
||||
# 2869| getExpr(): [CStyleCast] (void)...
|
||||
# 2869| Conversion = [VoidConversion] conversion to void
|
||||
# 2869| Type = [VoidType] void
|
||||
# 2869| ValueCategory = prvalue
|
||||
# 2869| getElse(): [Literal] 1
|
||||
# 2869| Type = [IntType] int
|
||||
# 2869| Value = [Literal] 1
|
||||
# 2869| ValueCategory = prvalue
|
||||
# 2869| getThen().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2869| Type = [IntType] int
|
||||
# 2869| Value = [ParenthesisExpr] 0
|
||||
# 2869| ValueCategory = prvalue
|
||||
# 2871| getStmt(2): [TryStmt] try { ... }
|
||||
# 2871| getStmt(): [BlockStmt] { ... }
|
||||
# 2872| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2872| getExpr(): [ThrowExpr] throw ...
|
||||
# 2872| Type = [IntType] int
|
||||
# 2872| ValueCategory = prvalue
|
||||
# 2872| getExpr(): [Literal] 41
|
||||
# 2872| Type = [IntType] int
|
||||
# 2872| Value = [Literal] 41
|
||||
# 2872| ValueCategory = prvalue
|
||||
# 2873| getChild(1): [Handler] <handler>
|
||||
# 2873| getParameter(): [Parameter] c
|
||||
# 2873| Type = [IntType] int
|
||||
# 2873| getBlock(): [CatchBlock] { ... }
|
||||
# 2874| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2874| getExpr(): [Literal] 0
|
||||
# 2874| Type = [IntType] int
|
||||
# 2874| Value = [Literal] 0
|
||||
# 2874| ValueCategory = prvalue
|
||||
# 2874| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2874| Type = [VoidType] void
|
||||
# 2874| ValueCategory = prvalue
|
||||
# 2874| getExpr(): [CStyleCast] (void)...
|
||||
# 2874| Conversion = [VoidConversion] conversion to void
|
||||
# 2874| Type = [VoidType] void
|
||||
# 2874| ValueCategory = prvalue
|
||||
# 2875| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2875| getExpr(): [Literal] 0
|
||||
# 2875| Type = [IntType] int
|
||||
# 2875| Value = [Literal] 0
|
||||
# 2875| ValueCategory = prvalue
|
||||
# 2875| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2875| Type = [VoidType] void
|
||||
# 2875| ValueCategory = prvalue
|
||||
# 2875| getExpr(): [CStyleCast] (void)...
|
||||
# 2875| Conversion = [VoidConversion] conversion to void
|
||||
# 2875| Type = [VoidType] void
|
||||
# 2875| ValueCategory = prvalue
|
||||
# 2878| getStmt(3): [ExprStmt] ExprStmt
|
||||
# 2878| getExpr(): [Literal] 0
|
||||
# 2878| Type = [IntType] int
|
||||
# 2878| Value = [Literal] 0
|
||||
# 2878| ValueCategory = prvalue
|
||||
# 2878| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2878| Type = [VoidType] void
|
||||
# 2878| ValueCategory = prvalue
|
||||
# 2878| getExpr(): [CStyleCast] (void)...
|
||||
# 2878| Conversion = [VoidConversion] conversion to void
|
||||
# 2878| Type = [VoidType] void
|
||||
# 2878| ValueCategory = prvalue
|
||||
# 2879| getStmt(4): [DeclStmt] declaration
|
||||
# 2879| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
|
||||
# 2879| Type = [IntType] int
|
||||
# 2881| getStmt(5): [TryStmt] try { ... }
|
||||
# 2881| getStmt(): [BlockStmt] { ... }
|
||||
# 2882| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2882| getExpr(): [ThrowExpr] throw ...
|
||||
# 2882| Type = [IntType] int
|
||||
# 2882| ValueCategory = prvalue
|
||||
# 2882| getExpr(): [Literal] 41
|
||||
# 2882| Type = [IntType] int
|
||||
# 2882| Value = [Literal] 41
|
||||
# 2882| ValueCategory = prvalue
|
||||
# 2883| getChild(1): [Handler] <handler>
|
||||
# 2883| getParameter(): [Parameter] shadowed
|
||||
# 2883| Type = [IntType] int
|
||||
# 2883| getBlock(): [CatchBlock] { ... }
|
||||
# 2884| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2884| getExpr(): [Literal] 0
|
||||
# 2884| Type = [IntType] int
|
||||
# 2884| Value = [Literal] 0
|
||||
# 2884| ValueCategory = prvalue
|
||||
# 2884| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2884| Type = [VoidType] void
|
||||
# 2884| ValueCategory = prvalue
|
||||
# 2884| getExpr(): [CStyleCast] (void)...
|
||||
# 2884| Conversion = [VoidConversion] conversion to void
|
||||
# 2884| Type = [VoidType] void
|
||||
# 2884| ValueCategory = prvalue
|
||||
# 2886| getStmt(6): [ReturnStmt] return ...
|
||||
ir23.cpp:
|
||||
# 1| [TopLevelFunction] bool consteval_1()
|
||||
# 1| <params>:
|
||||
|
||||
@@ -20741,6 +20741,331 @@ ir.cpp:
|
||||
# 2821| v2821_10(void) = AliasedUse : m2821_3
|
||||
# 2821| v2821_11(void) = ExitFunction :
|
||||
|
||||
# 2830| void test_assert_simple(int, int, unsigned int, int)
|
||||
# 2830| Block 0
|
||||
# 2830| v2830_1(void) = EnterFunction :
|
||||
# 2830| m2830_2(unknown) = AliasedDefinition :
|
||||
# 2830| m2830_3(unknown) = InitializeNonLocal :
|
||||
# 2830| m2830_4(unknown) = Chi : total:m2830_2, partial:m2830_3
|
||||
# 2830| r2830_5(glval<int>) = VariableAddress[x] :
|
||||
# 2830| m2830_6(int) = InitializeParameter[x] : &:r2830_5
|
||||
# 2830| r2830_7(glval<int>) = VariableAddress[y] :
|
||||
# 2830| m2830_8(int) = InitializeParameter[y] : &:r2830_7
|
||||
# 2830| r2830_9(glval<unsigned int>) = VariableAddress[u] :
|
||||
# 2830| m2830_10(unsigned int) = InitializeParameter[u] : &:r2830_9
|
||||
# 2830| r2830_11(glval<int>) = VariableAddress[shadowed] :
|
||||
# 2830| m2830_12(int) = InitializeParameter[shadowed] : &:r2830_11
|
||||
# 2831| r2831_1(glval<int>) = VariableAddress[x] :
|
||||
# 2831| r2831_2(int) = Load[x] : &:r2831_1, m2830_6
|
||||
# 2831| r2831_3(int) = Constant[0] :
|
||||
# 2831| r2831_4(bool) = CompareGT : r2831_2, r2831_3
|
||||
# 2831| v2831_5(void) = ConditionalBranch : r2831_4
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2832| Block 1
|
||||
# 2832| r2832_1(int) = Constant[0] :
|
||||
# 2832| r2832_2(glval<int>) = VariableAddress[x] :
|
||||
# 2832| r2832_3(int) = Load[x] : &:r2832_2, m2830_6
|
||||
# 2832| r2832_4(bool) = CompareLT : r2832_1, r2832_3
|
||||
# 2832| v2832_5(void) = ConditionalBranch : r2832_4
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2833| Block 2
|
||||
# 2833| r2833_1(glval<int>) = VariableAddress[x] :
|
||||
# 2833| r2833_2(int) = Load[x] : &:r2833_1, m2830_6
|
||||
# 2833| r2833_3(glval<int>) = VariableAddress[y] :
|
||||
# 2833| r2833_4(int) = Load[y] : &:r2833_3, m2830_8
|
||||
# 2833| r2833_5(bool) = CompareLT : r2833_2, r2833_4
|
||||
# 2833| v2833_6(void) = ConditionalBranch : r2833_5
|
||||
#-----| True -> Block 3
|
||||
|
||||
# 2835| Block 3
|
||||
# 2835| r2835_1(glval<int>) = VariableAddress[x] :
|
||||
# 2835| r2835_2(int) = Load[x] : &:r2835_1, m2830_6
|
||||
# 2835| r2835_3(int) = Constant[2] :
|
||||
# 2835| r2835_4(bool) = CompareNE : r2835_2, r2835_3
|
||||
# 2835| v2835_5(void) = ConditionalBranch : r2835_4
|
||||
#-----| True -> Block 4
|
||||
|
||||
# 2837| Block 4
|
||||
# 2837| r2837_1(glval<unsigned int>) = VariableAddress[u] :
|
||||
# 2837| r2837_2(unsigned int) = Load[u] : &:r2837_1, m2830_10
|
||||
# 2837| r2837_3(glval<int>) = VariableAddress[x] :
|
||||
# 2837| r2837_4(int) = Load[x] : &:r2837_3, m2830_6
|
||||
# 2837| r2837_5(bool) = CompareLT : r2837_2, r2837_4
|
||||
# 2837| v2837_6(void) = ConditionalBranch : r2837_5
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 2840| Block 5
|
||||
# 2840| r2840_1(glval<int>) = VariableAddress[shadowed] :
|
||||
# 2840| r2840_2(glval<int>) = VariableAddress[x] :
|
||||
# 2840| r2840_3(int) = Load[x] : &:r2840_2, m2830_6
|
||||
# 2840| m2840_4(int) = Store[shadowed] : &:r2840_1, r2840_3
|
||||
# 2841| r2841_1(int) = Constant[0] :
|
||||
# 2841| v2841_2(void) = Convert : r2841_1
|
||||
# 2843| v2843_1(void) = NoOp :
|
||||
# 2830| v2830_13(void) = ReturnVoid :
|
||||
# 2830| v2830_14(void) = AliasedUse : m2830_3
|
||||
# 2830| v2830_15(void) = ExitFunction :
|
||||
|
||||
# 2846| void test_assert_in_template<int>(int, int, unsigned int)
|
||||
# 2846| Block 0
|
||||
# 2846| v2846_1(void) = EnterFunction :
|
||||
# 2846| m2846_2(unknown) = AliasedDefinition :
|
||||
# 2846| m2846_3(unknown) = InitializeNonLocal :
|
||||
# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3
|
||||
# 2846| r2846_5(glval<int>) = VariableAddress[x] :
|
||||
# 2846| m2846_6(int) = InitializeParameter[x] : &:r2846_5
|
||||
# 2846| r2846_7(glval<int>) = VariableAddress[y] :
|
||||
# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7
|
||||
# 2846| r2846_9(glval<unsigned int>) = VariableAddress[u] :
|
||||
# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9
|
||||
# 2847| r2847_1(glval<int>) = VariableAddress[x] :
|
||||
# 2847| r2847_2(int) = Load[x] : &:r2847_1, m2846_6
|
||||
# 2847| r2847_3(int) = Constant[0] :
|
||||
# 2847| r2847_4(bool) = CompareGT : r2847_2, r2847_3
|
||||
# 2847| v2847_5(void) = ConditionalBranch : r2847_4
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2848| Block 1
|
||||
# 2848| r2848_1(int) = Constant[0] :
|
||||
# 2848| r2848_2(glval<int>) = VariableAddress[x] :
|
||||
# 2848| r2848_3(int) = Load[x] : &:r2848_2, m2846_6
|
||||
# 2848| r2848_4(bool) = CompareLT : r2848_1, r2848_3
|
||||
# 2848| v2848_5(void) = ConditionalBranch : r2848_4
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2849| Block 2
|
||||
# 2849| r2849_1(glval<int>) = VariableAddress[x] :
|
||||
# 2849| r2849_2(int) = Load[x] : &:r2849_1, m2846_6
|
||||
# 2849| r2849_3(glval<int>) = VariableAddress[y] :
|
||||
# 2849| r2849_4(int) = Load[y] : &:r2849_3, m2846_8
|
||||
# 2849| r2849_5(bool) = CompareLT : r2849_2, r2849_4
|
||||
# 2849| v2849_6(void) = ConditionalBranch : r2849_5
|
||||
#-----| True -> Block 3
|
||||
|
||||
# 2851| Block 3
|
||||
# 2851| r2851_1(glval<int>) = VariableAddress[x] :
|
||||
# 2851| r2851_2(int) = Load[x] : &:r2851_1, m2846_6
|
||||
# 2851| r2851_3(int) = Constant[2] :
|
||||
# 2851| r2851_4(bool) = CompareNE : r2851_2, r2851_3
|
||||
# 2851| v2851_5(void) = ConditionalBranch : r2851_4
|
||||
#-----| True -> Block 4
|
||||
|
||||
# 2853| Block 4
|
||||
# 2853| r2853_1(glval<unsigned int>) = VariableAddress[u] :
|
||||
# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, m2846_10
|
||||
# 2853| r2853_3(glval<int>) = VariableAddress[x] :
|
||||
# 2853| r2853_4(int) = Load[x] : &:r2853_3, m2846_6
|
||||
# 2853| r2853_5(bool) = CompareLT : r2853_2, r2853_4
|
||||
# 2853| v2853_6(void) = ConditionalBranch : r2853_5
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 2856| Block 5
|
||||
# 2856| r2856_1(glval<int>) = VariableAddress[shadowed] :
|
||||
# 2856| r2856_2(glval<int>) = VariableAddress[x] :
|
||||
# 2856| r2856_3(int) = Load[x] : &:r2856_2, m2846_6
|
||||
# 2856| m2856_4(int) = Store[shadowed] : &:r2856_1, r2856_3
|
||||
# 2857| r2857_1(glval<int>) = VariableAddress[shadowed] :
|
||||
# 2857| r2857_2(int) = Load[shadowed] : &:r2857_1, m2856_4
|
||||
# 2857| r2857_3(int) = Constant[0] :
|
||||
# 2857| r2857_4(bool) = CompareGT : r2857_2, r2857_3
|
||||
# 2857| v2857_5(void) = ConditionalBranch : r2857_4
|
||||
#-----| True -> Block 6
|
||||
|
||||
# 2859| Block 6
|
||||
# 2859| r2859_1(glval<int>) = VariableAddress[x] :
|
||||
# 2859| r2859_2(int) = Load[x] : &:r2859_1, m2846_6
|
||||
# 2859| r2859_3(int) = Constant[0] :
|
||||
# 2859| r2859_4(bool) = CompareGT : r2859_2, r2859_3
|
||||
# 2859| v2859_5(void) = ConditionalBranch : r2859_4
|
||||
#-----| True -> Block 7
|
||||
|
||||
# 2860| Block 7
|
||||
# 2860| v2860_1(void) = NoOp :
|
||||
# 2846| v2846_11(void) = ReturnVoid :
|
||||
# 2846| v2846_12(void) = AliasedUse : m2846_3
|
||||
# 2846| v2846_13(void) = ExitFunction :
|
||||
|
||||
# 2846| void test_assert_in_template<short>(short, int, unsigned int)
|
||||
# 2846| Block 0
|
||||
# 2846| v2846_1(void) = EnterFunction :
|
||||
# 2846| m2846_2(unknown) = AliasedDefinition :
|
||||
# 2846| m2846_3(unknown) = InitializeNonLocal :
|
||||
# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3
|
||||
# 2846| r2846_5(glval<short>) = VariableAddress[x] :
|
||||
# 2846| m2846_6(short) = InitializeParameter[x] : &:r2846_5
|
||||
# 2846| r2846_7(glval<int>) = VariableAddress[y] :
|
||||
# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7
|
||||
# 2846| r2846_9(glval<unsigned int>) = VariableAddress[u] :
|
||||
# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9
|
||||
# 2847| r2847_1(glval<short>) = VariableAddress[x] :
|
||||
# 2847| r2847_2(short) = Load[x] : &:r2847_1, m2846_6
|
||||
# 2847| r2847_3(int) = Constant[0] :
|
||||
# 2847| r2847_4(bool) = CompareGT : r2847_2, r2847_3
|
||||
# 2847| v2847_5(void) = ConditionalBranch : r2847_4
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2848| Block 1
|
||||
# 2848| r2848_1(int) = Constant[0] :
|
||||
# 2848| r2848_2(glval<short>) = VariableAddress[x] :
|
||||
# 2848| r2848_3(short) = Load[x] : &:r2848_2, m2846_6
|
||||
# 2848| r2848_4(bool) = CompareLT : r2848_1, r2848_3
|
||||
# 2848| v2848_5(void) = ConditionalBranch : r2848_4
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2849| Block 2
|
||||
# 2849| r2849_1(glval<short>) = VariableAddress[x] :
|
||||
# 2849| r2849_2(short) = Load[x] : &:r2849_1, m2846_6
|
||||
# 2849| r2849_3(glval<int>) = VariableAddress[y] :
|
||||
# 2849| r2849_4(int) = Load[y] : &:r2849_3, m2846_8
|
||||
# 2849| r2849_5(bool) = CompareLT : r2849_2, r2849_4
|
||||
# 2849| v2849_6(void) = ConditionalBranch : r2849_5
|
||||
#-----| True -> Block 3
|
||||
|
||||
# 2851| Block 3
|
||||
# 2851| r2851_1(glval<short>) = VariableAddress[x] :
|
||||
# 2851| r2851_2(short) = Load[x] : &:r2851_1, m2846_6
|
||||
# 2851| r2851_3(int) = Constant[2] :
|
||||
# 2851| r2851_4(bool) = CompareNE : r2851_2, r2851_3
|
||||
# 2851| v2851_5(void) = ConditionalBranch : r2851_4
|
||||
#-----| True -> Block 4
|
||||
|
||||
# 2853| Block 4
|
||||
# 2853| r2853_1(glval<unsigned int>) = VariableAddress[u] :
|
||||
# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, m2846_10
|
||||
# 2853| r2853_3(glval<short>) = VariableAddress[x] :
|
||||
# 2853| r2853_4(short) = Load[x] : &:r2853_3, m2846_6
|
||||
# 2853| r2853_5(bool) = CompareLT : r2853_2, r2853_4
|
||||
# 2853| v2853_6(void) = ConditionalBranch : r2853_5
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 2856| Block 5
|
||||
# 2856| r2856_1(glval<int>) = VariableAddress[shadowed] :
|
||||
# 2856| r2856_2(glval<short>) = VariableAddress[x] :
|
||||
# 2856| r2856_3(short) = Load[x] : &:r2856_2, m2846_6
|
||||
# 2856| r2856_4(int) = Convert : r2856_3
|
||||
# 2856| m2856_5(int) = Store[shadowed] : &:r2856_1, r2856_4
|
||||
# 2857| r2857_1(glval<int>) = VariableAddress[shadowed] :
|
||||
# 2857| r2857_2(int) = Load[shadowed] : &:r2857_1, m2856_5
|
||||
# 2857| r2857_3(int) = Constant[0] :
|
||||
# 2857| r2857_4(bool) = CompareGT : r2857_2, r2857_3
|
||||
# 2857| v2857_5(void) = ConditionalBranch : r2857_4
|
||||
#-----| True -> Block 6
|
||||
|
||||
# 2859| Block 6
|
||||
# 2859| r2859_1(glval<short>) = VariableAddress[x] :
|
||||
# 2859| r2859_2(short) = Load[x] : &:r2859_1, m2846_6
|
||||
# 2859| r2859_3(int) = Constant[0] :
|
||||
# 2859| r2859_4(bool) = CompareGT : r2859_2, r2859_3
|
||||
# 2859| v2859_5(void) = ConditionalBranch : r2859_4
|
||||
#-----| True -> Block 7
|
||||
|
||||
# 2860| Block 7
|
||||
# 2860| v2860_1(void) = NoOp :
|
||||
# 2846| v2846_11(void) = ReturnVoid :
|
||||
# 2846| v2846_12(void) = AliasedUse : m2846_3
|
||||
# 2846| v2846_13(void) = ExitFunction :
|
||||
|
||||
# 2867| void (unnamed namespace)::complex_assertions(int, bool, int)
|
||||
# 2867| Block 0
|
||||
# 2867| v2867_1(void) = EnterFunction :
|
||||
# 2867| m2867_2(unknown) = AliasedDefinition :
|
||||
# 2867| m2867_3(unknown) = InitializeNonLocal :
|
||||
# 2867| m2867_4(unknown) = Chi : total:m2867_2, partial:m2867_3
|
||||
# 2867| r2867_5(glval<int>) = VariableAddress[x] :
|
||||
# 2867| m2867_6(int) = InitializeParameter[x] : &:r2867_5
|
||||
# 2867| r2867_7(glval<bool>) = VariableAddress[b] :
|
||||
# 2867| m2867_8(bool) = InitializeParameter[b] : &:r2867_7
|
||||
# 2867| r2867_9(glval<int>) = VariableAddress[max] :
|
||||
# 2867| m2867_10(int) = InitializeParameter[max] : &:r2867_9
|
||||
# 2868| r2868_1(glval<int>) = VariableAddress[y] :
|
||||
# 2868| r2868_2(int) = Constant[0] :
|
||||
# 2868| v2868_3(void) = Convert : r2868_2
|
||||
# 2868| r2868_4(glval<int>) = VariableAddress[x] :
|
||||
# 2868| r2868_5(int) = Load[x] : &:r2868_4, m2867_6
|
||||
# 2868| r2868_6(int) = CopyValue : r2868_5
|
||||
# 2868| m2868_7(int) = Store[y] : &:r2868_1, r2868_6
|
||||
# 2869| r2869_1(glval<int>) = VariableAddress[z] :
|
||||
# 2869| r2869_2(glval<bool>) = VariableAddress[b] :
|
||||
# 2869| r2869_3(bool) = Load[b] : &:r2869_2, m2867_8
|
||||
# 2869| v2869_4(void) = ConditionalBranch : r2869_3
|
||||
#-----| False -> Block 5
|
||||
#-----| True -> Block 4
|
||||
|
||||
# 2867| Block 1
|
||||
# 2867| v2867_11(void) = AliasedUse : m2867_3
|
||||
# 2867| v2867_12(void) = ExitFunction :
|
||||
|
||||
# 2867| Block 2
|
||||
# 2867| v2867_13(void) = Unwind :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2869| Block 3
|
||||
# 2869| m2869_5(int) = Phi : from 4:m2869_11, from 5:m2869_14
|
||||
# 2869| r2869_6(glval<int>) = VariableAddress[#temp2869:17] :
|
||||
# 2869| r2869_7(int) = Load[#temp2869:17] : &:r2869_6, m2869_5
|
||||
# 2869| m2869_8(int) = Store[z] : &:r2869_1, r2869_7
|
||||
# 2872| r2872_1(glval<int>) = VariableAddress[#throw2872:13] :
|
||||
# 2872| r2872_2(int) = Constant[41] :
|
||||
# 2872| m2872_3(int) = Store[#throw2872:13] : &:r2872_1, r2872_2
|
||||
# 2872| v2872_4(void) = ThrowValue : &:r2872_1, m2872_3
|
||||
#-----| C++ Exception -> Block 6
|
||||
|
||||
# 2869| Block 4
|
||||
# 2869| r2869_9(int) = Constant[0] :
|
||||
# 2869| r2869_10(glval<int>) = VariableAddress[#temp2869:17] :
|
||||
# 2869| m2869_11(int) = Store[#temp2869:17] : &:r2869_10, r2869_9
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2869| Block 5
|
||||
# 2869| r2869_12(int) = Constant[1] :
|
||||
# 2869| r2869_13(glval<int>) = VariableAddress[#temp2869:17] :
|
||||
# 2869| m2869_14(int) = Store[#temp2869:17] : &:r2869_13, r2869_12
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2873| Block 6
|
||||
# 2873| v2873_1(void) = CatchByType[int] :
|
||||
#-----| C++ Exception -> Block 2
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 2873| Block 7
|
||||
# 2873| r2873_2(glval<int>) = VariableAddress[c] :
|
||||
# 2873| m2873_3(int) = InitializeParameter[c] : &:r2873_2
|
||||
# 2874| r2874_1(glval<int>) = VariableAddress[c] :
|
||||
# 2874| r2874_2(int) = Load[c] : &:r2874_1, m2873_3
|
||||
# 2874| r2874_3(int) = Constant[42] :
|
||||
# 2874| r2874_4(bool) = CompareLT : r2874_2, r2874_3
|
||||
# 2874| v2874_5(void) = ConditionalBranch : r2874_4
|
||||
#-----| True -> Block 8
|
||||
|
||||
# 2875| Block 8
|
||||
# 2875| r2875_1(int) = Constant[0] :
|
||||
# 2875| v2875_2(void) = Convert : r2875_1
|
||||
# 2878| r2878_1(int) = Constant[0] :
|
||||
# 2878| v2878_2(void) = Convert : r2878_1
|
||||
# 2879| r2879_1(glval<int>) = VariableAddress[shadowed] :
|
||||
# 2879| m2879_2(int) = Uninitialized[shadowed] : &:r2879_1
|
||||
# 2882| r2882_1(glval<int>) = VariableAddress[#throw2882:13] :
|
||||
# 2882| r2882_2(int) = Constant[41] :
|
||||
# 2882| m2882_3(int) = Store[#throw2882:13] : &:r2882_1, r2882_2
|
||||
# 2882| v2882_4(void) = ThrowValue : &:r2882_1, m2882_3
|
||||
#-----| C++ Exception -> Block 9
|
||||
|
||||
# 2883| Block 9
|
||||
# 2883| v2883_1(void) = CatchByType[int] :
|
||||
#-----| C++ Exception -> Block 2
|
||||
#-----| Goto -> Block 10
|
||||
|
||||
# 2883| Block 10
|
||||
# 2883| r2883_2(glval<int>) = VariableAddress[shadowed] :
|
||||
# 2883| m2883_3(int) = InitializeParameter[shadowed] : &:r2883_2
|
||||
# 2884| r2884_1(int) = Constant[0] :
|
||||
# 2884| v2884_2(void) = Convert : r2884_1
|
||||
# 2886| v2886_1(void) = NoOp :
|
||||
# 2867| v2867_14(void) = ReturnVoid :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
ir23.cpp:
|
||||
# 1| bool consteval_1()
|
||||
# 1| Block 0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user