mirror of
https://github.com/github/codeql.git
synced 2026-05-16 04:09:27 +02:00
Compare commits
617 Commits
codeql-cli
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2501a701ad | ||
|
|
0a3670727f | ||
|
|
31b0c423a4 | ||
|
|
7ed4f5b292 | ||
|
|
7372562222 | ||
|
|
1228a83e77 | ||
|
|
c2fa37e285 | ||
|
|
839f2a6be0 | ||
|
|
da29336a8c | ||
|
|
12a86f52c3 | ||
|
|
ac26330476 | ||
|
|
d5c79d4eee | ||
|
|
c91029395d | ||
|
|
d10903a09c | ||
|
|
854c126c37 | ||
|
|
6b90ce0d80 | ||
|
|
a4f3e5e0bb | ||
|
|
93eff2a66a | ||
|
|
488b824ca6 | ||
|
|
b42ab24bc8 | ||
|
|
34e5c5c1f7 | ||
|
|
7be0b2e9eb | ||
|
|
8c8bbde1f7 | ||
|
|
e865574412 | ||
|
|
075cbfd7d2 | ||
|
|
67ff5ae10e | ||
|
|
fde045902a | ||
|
|
73ecb119d6 | ||
|
|
8218397a83 | ||
|
|
4779c23da1 | ||
|
|
75955237a9 | ||
|
|
8dd7602dff | ||
|
|
d7278be064 | ||
|
|
264e57fc59 | ||
|
|
d8fb875bbb | ||
|
|
cc3a76f7f5 | ||
|
|
b019fb3e91 | ||
|
|
c6b8c444d0 | ||
|
|
edf6a80c3b | ||
|
|
d792175907 | ||
|
|
7bcaa49f5a | ||
|
|
6fe9b70c92 | ||
|
|
d699880c86 | ||
|
|
1a575ef297 | ||
|
|
e1ffc8d886 | ||
|
|
9f89c63771 | ||
|
|
0be61be07a | ||
|
|
d5442ec9c5 | ||
|
|
354a55c735 | ||
|
|
e6a6a7931b | ||
|
|
ea384b340a | ||
|
|
e08a873829 | ||
|
|
163252d5f6 | ||
|
|
abf2b12b1c | ||
|
|
a2659eecfb | ||
|
|
77369a09a4 | ||
|
|
03ad04bc8e | ||
|
|
e2602fbbc4 | ||
|
|
7d89028688 | ||
|
|
bbf441f87a | ||
|
|
888dd786b4 | ||
|
|
a58c9e91ea | ||
|
|
301133ad94 | ||
|
|
284ca5e4ee | ||
|
|
4919cc4c4e | ||
|
|
181594badb | ||
|
|
72e08a9277 | ||
|
|
67a0112fcb | ||
|
|
72d9812fea | ||
|
|
dfefd62089 | ||
|
|
aed14f2924 | ||
|
|
b575747357 | ||
|
|
da64ea40b9 | ||
|
|
eb59bc04cd | ||
|
|
3009f40814 | ||
|
|
1ec29bffbb | ||
|
|
d511d46cde | ||
|
|
10548b57d7 | ||
|
|
cd590d356d | ||
|
|
23857267db | ||
|
|
50db6916c8 | ||
|
|
73370e7282 | ||
|
|
756886808d | ||
|
|
f5509da4bb | ||
|
|
2d5c40db31 | ||
|
|
c68d0bc936 | ||
|
|
c1da2dfa73 | ||
|
|
ded49015e0 | ||
|
|
cd289f8207 | ||
|
|
803adae9c6 | ||
|
|
4770eb0328 | ||
|
|
1159508e4f | ||
|
|
59a77666a6 | ||
|
|
3afa4aa91e | ||
|
|
261ba8e02d | ||
|
|
253f932d2a | ||
|
|
9af706c2a5 | ||
|
|
db304d118b | ||
|
|
fefe64bf0c | ||
|
|
5c8367a695 | ||
|
|
c4b626a416 | ||
|
|
de7c9bdd9b | ||
|
|
291d7b3e05 | ||
|
|
a966c0e1eb | ||
|
|
ce229fe21f | ||
|
|
29982fe30e | ||
|
|
66f5e4a05b | ||
|
|
7e77c77d92 | ||
|
|
984795ee46 | ||
|
|
44a83a71a8 | ||
|
|
62c2316124 | ||
|
|
4ca259b200 | ||
|
|
6a21fa04cd | ||
|
|
b092da485d | ||
|
|
c32c4bb6d2 | ||
|
|
39b45fa24f | ||
|
|
f88428f3fd | ||
|
|
361ae1747e | ||
|
|
2643ab3dbf | ||
|
|
a966944fd8 | ||
|
|
5e11fe74f7 | ||
|
|
9bf5999ca0 | ||
|
|
e3ff7644f7 | ||
|
|
125629a7e2 | ||
|
|
210a5bfff2 | ||
|
|
7006cfd8f8 | ||
|
|
84d52b94a3 | ||
|
|
ffa3bdc8bb | ||
|
|
e226c564b6 | ||
|
|
35a1dd8ba9 | ||
|
|
e4a11b86d9 | ||
|
|
e9b3f1282a | ||
|
|
8624ff12be | ||
|
|
fc850b18fe | ||
|
|
7d7a893b55 | ||
|
|
41726f52a2 | ||
|
|
6760dd9121 | ||
|
|
b3be4797e2 | ||
|
|
c906009e5b | ||
|
|
4c16f1be8b | ||
|
|
99cc4171f8 | ||
|
|
ae4c76c788 | ||
|
|
9df5e30034 | ||
|
|
24b679d5a0 | ||
|
|
8b1b1618c4 | ||
|
|
3b344c3578 | ||
|
|
689fda43ed | ||
|
|
08c24930ac | ||
|
|
7611bfb149 | ||
|
|
1da885fae2 | ||
|
|
e219281016 | ||
|
|
946854bd17 | ||
|
|
1ac9d2ee5b | ||
|
|
7068da25f0 | ||
|
|
dd274422d1 | ||
|
|
f2bf540209 | ||
|
|
49d510018d | ||
|
|
0b2458d065 | ||
|
|
26319bfc04 | ||
|
|
de76c0749a | ||
|
|
d14ad92dbd | ||
|
|
b36fd9fdab | ||
|
|
f3a77c6006 | ||
|
|
dbdb433957 | ||
|
|
d3ba7e6b3c | ||
|
|
5f4861f72e | ||
|
|
5de8d9181d | ||
|
|
0d1fd88729 | ||
|
|
bce47fe344 | ||
|
|
29e14f7d8d | ||
|
|
d10597f69d | ||
|
|
3343b78015 | ||
|
|
3eba77421a | ||
|
|
f65fe34513 | ||
|
|
d4cfa8c2b8 | ||
|
|
d2fe4d235a | ||
|
|
e19c7758ed | ||
|
|
6e4865ddd9 | ||
|
|
b6c2ea520b | ||
|
|
2e981e330b | ||
|
|
6e05246daa | ||
|
|
c807ab4216 | ||
|
|
826b8e6aa5 | ||
|
|
78487d437f | ||
|
|
1e3387f2c5 | ||
|
|
e7dbe9f289 | ||
|
|
38b78128c0 | ||
|
|
889cb7a95b | ||
|
|
9c44235782 | ||
|
|
7cba6cd1d8 | ||
|
|
0f242475f2 | ||
|
|
0dca8a5d86 | ||
|
|
39e2b133e9 | ||
|
|
be2712698b | ||
|
|
1cbee6a8a4 | ||
|
|
bb1712b489 | ||
|
|
9957e2683b | ||
|
|
ea2140dc7d | ||
|
|
8badf10a53 | ||
|
|
ae635c609f | ||
|
|
9542646a5d | ||
|
|
104416cc59 | ||
|
|
cb2f7b0f95 | ||
|
|
759f939edd | ||
|
|
bf9a0dab2a | ||
|
|
7852429df2 | ||
|
|
d699201ad0 | ||
|
|
027ed5e909 | ||
|
|
417b9c9a32 | ||
|
|
a3711e1df0 | ||
|
|
c5612ae522 | ||
|
|
68bccfdb93 | ||
|
|
b948ed9045 | ||
|
|
89b91ec5c8 | ||
|
|
c3cf48b38a | ||
|
|
02b8adf717 | ||
|
|
ffd618d6cc | ||
|
|
04f8ed6af0 | ||
|
|
c43ba456e5 | ||
|
|
4ca98bd6fd | ||
|
|
0fe7740dda | ||
|
|
1afcf8c8a8 | ||
|
|
9f8fbf8a1a | ||
|
|
45ddb4832c | ||
|
|
a2f2b6c33f | ||
|
|
61a523510e | ||
|
|
a81d982c90 | ||
|
|
6573b1f772 | ||
|
|
42fd9f0c54 | ||
|
|
a7de0f96e2 | ||
|
|
ad49eada48 | ||
|
|
68cd422788 | ||
|
|
5367fb99d9 | ||
|
|
9c5d7350dc | ||
|
|
ded06a77d0 | ||
|
|
2fd627b460 | ||
|
|
50a9c31b4a | ||
|
|
2ed01d06b4 | ||
|
|
c9d64b6b4f | ||
|
|
b550c067a1 | ||
|
|
9d573e5544 | ||
|
|
137f9e7234 | ||
|
|
d3c24ba110 | ||
|
|
e9e6bce80a | ||
|
|
88fc96e8d7 | ||
|
|
7ad1a21c2d | ||
|
|
a834703195 | ||
|
|
763216b932 | ||
|
|
56f1ff8af1 | ||
|
|
0273b20c75 | ||
|
|
ce97d38a18 | ||
|
|
cb66d62959 | ||
|
|
dc454d3a72 | ||
|
|
a7d92b3473 | ||
|
|
dfc83d844a | ||
|
|
415d9e0674 | ||
|
|
7e05551f16 | ||
|
|
5dff1852e1 | ||
|
|
242a49e6f1 | ||
|
|
c44b8249a5 | ||
|
|
bdad9e197b | ||
|
|
da403c1a79 | ||
|
|
45c56fbce7 | ||
|
|
607f729339 | ||
|
|
6c664e93ef | ||
|
|
e3d6b3e537 | ||
|
|
f17518ace2 | ||
|
|
cd7c851d64 | ||
|
|
1286235773 | ||
|
|
7af1e96943 | ||
|
|
6b58d11eeb | ||
|
|
d42e892097 | ||
|
|
59de92ce64 | ||
|
|
f2eed4d8c4 | ||
|
|
f07f97a94e | ||
|
|
7723dbc6d7 | ||
|
|
8c32919381 | ||
|
|
554a2c26c3 | ||
|
|
3f9701cea7 | ||
|
|
4e6707fee5 | ||
|
|
b424f3fe83 | ||
|
|
9f7413eded | ||
|
|
ebe3f61ef6 | ||
|
|
f996fa2f8b | ||
|
|
d89a86fea4 | ||
|
|
c882945e30 | ||
|
|
db2b8d4bcc | ||
|
|
123e58767b | ||
|
|
96e9dfc7b2 | ||
|
|
b76842ad3d | ||
|
|
3680613f2d | ||
|
|
6cf99688e1 | ||
|
|
89b790d048 | ||
|
|
f33359bd5c | ||
|
|
2b540e251a | ||
|
|
54c2221f35 | ||
|
|
cc7ef5dac1 | ||
|
|
ed40d72e4f | ||
|
|
24ac6c0596 | ||
|
|
7e2abf20c6 | ||
|
|
d146514275 | ||
|
|
d2fca1b804 | ||
|
|
46fc1fdaa1 | ||
|
|
15c49eeee9 | ||
|
|
ee1b3fd7e9 | ||
|
|
8aec87ea57 | ||
|
|
949b0a2613 | ||
|
|
7d99d61662 | ||
|
|
08d44c1bdc | ||
|
|
b8fc84e8e4 | ||
|
|
c6a757e085 | ||
|
|
794a459c1b | ||
|
|
b93e404441 | ||
|
|
02fbb47b64 | ||
|
|
03ca29ab96 | ||
|
|
1805b070dc | ||
|
|
d18ca3f5d7 | ||
|
|
0f3918af16 | ||
|
|
ae2a1c7399 | ||
|
|
736c4beb9e | ||
|
|
6c02e30f56 | ||
|
|
4b0a1cf74b | ||
|
|
410c09270f | ||
|
|
efcadbda69 | ||
|
|
a5c8917ff0 | ||
|
|
842da58269 | ||
|
|
fb4b774c0d | ||
|
|
1f1d48f768 | ||
|
|
95193633fe | ||
|
|
25e4f2c3a2 | ||
|
|
3810b796a0 | ||
|
|
6deaf4e5f8 | ||
|
|
d8462ad1b3 | ||
|
|
bc47646a79 | ||
|
|
dec6039469 | ||
|
|
6fb1058e73 | ||
|
|
672d1637ab | ||
|
|
664c1eba72 | ||
|
|
deaf912cb8 | ||
|
|
cf53956d39 | ||
|
|
6566b91355 | ||
|
|
5734e475d4 | ||
|
|
1e8daff02a | ||
|
|
e94781fa8f | ||
|
|
c1f167ceee | ||
|
|
87d0d723ed | ||
|
|
530c950b41 | ||
|
|
66f11d427b | ||
|
|
bbce7ee96d | ||
|
|
afe1e9c453 | ||
|
|
fe36230061 | ||
|
|
1c3a0d1632 | ||
|
|
e88277bd3b | ||
|
|
abe28cb106 | ||
|
|
c67cc23e07 | ||
|
|
31738a37ae | ||
|
|
f301e46175 | ||
|
|
00c0ebe9e4 | ||
|
|
2b718fbc62 | ||
|
|
6bb37ca465 | ||
|
|
b4c903fd15 | ||
|
|
8441b54bd8 | ||
|
|
e9b1c933ed | ||
|
|
5192d7c137 | ||
|
|
3f54ecbcc2 | ||
|
|
5cce37baa9 | ||
|
|
48607e3ad7 | ||
|
|
b98a966729 | ||
|
|
3b8b33a94d | ||
|
|
3aeacf6df3 | ||
|
|
bdc5f9cdea | ||
|
|
ce6fd8ac5f | ||
|
|
a9ea61f0b2 | ||
|
|
a335ece5e5 | ||
|
|
1634fa2e25 | ||
|
|
81bf415b50 | ||
|
|
246d5c530e | ||
|
|
f7776f812c | ||
|
|
5a76b9f59e | ||
|
|
317757b7ae | ||
|
|
5e01e1d464 | ||
|
|
e1ed49f3ac | ||
|
|
1daedd9fb6 | ||
|
|
cbce0736c2 | ||
|
|
414ae76ae1 | ||
|
|
c615f183c1 | ||
|
|
2575db356d | ||
|
|
6d85d0d0f7 | ||
|
|
ef9d342a99 | ||
|
|
c46f9e4572 | ||
|
|
50190efe1c | ||
|
|
12d1d04592 | ||
|
|
1b4520b058 | ||
|
|
671eb0f82f | ||
|
|
2d0f73d7c2 | ||
|
|
6ef6be7291 | ||
|
|
997984c529 | ||
|
|
a54747f850 | ||
|
|
c8c69aac9b | ||
|
|
e776178be5 | ||
|
|
0a41acc0a6 | ||
|
|
70fdfc2ae3 | ||
|
|
4daabdae2b | ||
|
|
b4db68af80 | ||
|
|
a6f29fa417 | ||
|
|
b5cdaa2f94 | ||
|
|
62666915b4 | ||
|
|
84a78e7a8d | ||
|
|
ba0cc76da1 | ||
|
|
ad3cc8e1c7 | ||
|
|
c2eb2e9c69 | ||
|
|
a644133d8f | ||
|
|
166633dac0 | ||
|
|
d48ab36273 | ||
|
|
d391246f27 | ||
|
|
ba0f07b66c | ||
|
|
af1a0b9a6c | ||
|
|
a2bb7dee18 | ||
|
|
51f166d71e | ||
|
|
bda516e9ea | ||
|
|
106ba11e10 | ||
|
|
d66fe08661 | ||
|
|
a9f7994b7d | ||
|
|
4c06fbdc65 | ||
|
|
42c7006378 | ||
|
|
25cc561e50 | ||
|
|
764581cc3e | ||
|
|
807faf2c70 | ||
|
|
6840a6dafe | ||
|
|
8b5b153a21 | ||
|
|
699ed107f3 | ||
|
|
5623ccf4a0 | ||
|
|
6deeb36a97 | ||
|
|
864f60f90f | ||
|
|
71a36fcf0f | ||
|
|
034db52c5c | ||
|
|
4fb73ea191 | ||
|
|
1de86b4313 | ||
|
|
181b3d0e33 | ||
|
|
79ab27bfed | ||
|
|
d109637e2d | ||
|
|
a1c9deea61 | ||
|
|
b78f12481f | ||
|
|
1643a83678 | ||
|
|
7e36f7dcaf | ||
|
|
386dedb9df | ||
|
|
deaa37d9d3 | ||
|
|
c17a582b34 | ||
|
|
da05e3e0e8 | ||
|
|
6a5e539833 | ||
|
|
202a4cd1a2 | ||
|
|
0bbda992fb | ||
|
|
d968a91799 | ||
|
|
c0d1179c8a | ||
|
|
f47e59dff1 | ||
|
|
b48567f6a5 | ||
|
|
15dd130d31 | ||
|
|
b579ab0694 | ||
|
|
81ed72c96a | ||
|
|
480e3bf506 | ||
|
|
38577e6a5c | ||
|
|
33f8998c2e | ||
|
|
3c4e755233 | ||
|
|
843f2681bb | ||
|
|
8b3e32fa97 | ||
|
|
53ed39065c | ||
|
|
eb8997dc7a | ||
|
|
4d951d8df1 | ||
|
|
86a73fa0e7 | ||
|
|
0fd4f6180f | ||
|
|
1ac9d2c618 | ||
|
|
9082fd218e | ||
|
|
8d88af1af0 | ||
|
|
4eb1035dfe | ||
|
|
655a98452a | ||
|
|
f53496b2a7 | ||
|
|
d468ea9e90 | ||
|
|
b305962c9a | ||
|
|
a36c12ff1f | ||
|
|
60642c52aa | ||
|
|
e22a67e7fe | ||
|
|
a3a4c31911 | ||
|
|
929090a847 | ||
|
|
52ebf9fff6 | ||
|
|
172b8a6967 | ||
|
|
b567ec875a | ||
|
|
55fae2daaa | ||
|
|
97d6e82869 | ||
|
|
f58590c6a9 | ||
|
|
2aba425464 | ||
|
|
ab9f0240d3 | ||
|
|
b9f2da7875 | ||
|
|
3e7444cd66 | ||
|
|
15370506b8 | ||
|
|
a8b7e70d01 | ||
|
|
76438f13b6 | ||
|
|
109b96f038 | ||
|
|
e65269be69 | ||
|
|
59e2b0482c | ||
|
|
3de7b75853 | ||
|
|
970b3d06be | ||
|
|
7c764f3b50 | ||
|
|
cf54d3f4ca | ||
|
|
4c693b4fc3 | ||
|
|
ef139f2ee9 | ||
|
|
779fe6498c | ||
|
|
0336c76871 | ||
|
|
91edde72c4 | ||
|
|
1b31c4dd4c | ||
|
|
4277be5819 | ||
|
|
24f9f13790 | ||
|
|
56871c77f5 | ||
|
|
33e8310625 | ||
|
|
5f502ec6bb | ||
|
|
0443057608 | ||
|
|
570654d1f0 | ||
|
|
1bd536dd9e | ||
|
|
44a9cf93e0 | ||
|
|
808dc3e8d3 | ||
|
|
c981fd714e | ||
|
|
ee58dbc6f7 | ||
|
|
b95effe916 | ||
|
|
eb5529eac5 | ||
|
|
bc55afcee7 | ||
|
|
1c3cc1fa29 | ||
|
|
794d04e4c0 | ||
|
|
551b34e3be | ||
|
|
6e168ff7d8 | ||
|
|
0fba38c6d8 | ||
|
|
eeefdc5dcd | ||
|
|
513da82510 | ||
|
|
d189a15737 | ||
|
|
a623733dfa | ||
|
|
ee0bfff9f4 | ||
|
|
bb56536bfa | ||
|
|
14731e8fa3 | ||
|
|
238049a870 | ||
|
|
4df4a0f51f | ||
|
|
69589766ec | ||
|
|
48c35ce5e9 | ||
|
|
ca93f4d223 | ||
|
|
94a5aa450c | ||
|
|
46af77c1af | ||
|
|
9bd5694c3f | ||
|
|
dbc60140e0 | ||
|
|
97f8d1fca9 | ||
|
|
e60fa6f1a7 | ||
|
|
c5c2df4593 | ||
|
|
168a1e01a4 | ||
|
|
885e25ff2d | ||
|
|
3918e57ffe | ||
|
|
8d34ab6d18 | ||
|
|
c95432457d | ||
|
|
6ccf47ece9 | ||
|
|
063ab1c13f | ||
|
|
8b6a7985db | ||
|
|
5d2984b7a5 | ||
|
|
fb0102b763 | ||
|
|
0d78eeb871 | ||
|
|
43b9199734 | ||
|
|
c4a65e58bb | ||
|
|
747cd1745a | ||
|
|
20b792545d | ||
|
|
7ba2f7a22a | ||
|
|
bdd64ce86d | ||
|
|
af8d4e5ab2 | ||
|
|
3ef82c1091 | ||
|
|
d24db3fcd3 | ||
|
|
b41d47b910 | ||
|
|
c48d47484a | ||
|
|
664dc01c48 | ||
|
|
49d1556c29 | ||
|
|
315cb32f6c | ||
|
|
feadd7127b | ||
|
|
63c71f0b77 | ||
|
|
0cd1c1e2e5 | ||
|
|
0dec4876f1 | ||
|
|
6f1b406b3a | ||
|
|
0237f37842 | ||
|
|
c54561e775 | ||
|
|
fd649c1702 | ||
|
|
f7a662814d | ||
|
|
2d87489dfa | ||
|
|
e7ca2330cb | ||
|
|
e2abd3ff13 | ||
|
|
8960453662 | ||
|
|
2cbb7ed296 | ||
|
|
bee8e6ff0d | ||
|
|
591d81b5f9 | ||
|
|
8f8c064632 | ||
|
|
1e1d42fa35 | ||
|
|
7aff0079f5 | ||
|
|
0e8f83460c | ||
|
|
bbba906ff1 | ||
|
|
6f8ec118df | ||
|
|
c704158150 | ||
|
|
3ac94c33b2 | ||
|
|
55648ac4de | ||
|
|
a0b784e7b1 | ||
|
|
aaf9907a27 | ||
|
|
bb16731b86 | ||
|
|
dbde99df91 | ||
|
|
cb6276e5e2 | ||
|
|
13fa08a90a | ||
|
|
aa8ed91993 | ||
|
|
9e0f985e23 | ||
|
|
8279cf7c9c | ||
|
|
2ba83022c7 | ||
|
|
931f492df2 | ||
|
|
9fc28d5aba | ||
|
|
6f34c3225b | ||
|
|
a988ccb7d5 | ||
|
|
816799c4ba | ||
|
|
7a17b99c17 | ||
|
|
e3e0307db7 | ||
|
|
345f43fbae | ||
|
|
62353122c0 |
10
.github/workflows/go-tests-other-os.yml
vendored
10
.github/workflows/go-tests-other-os.yml
vendored
@@ -7,15 +7,17 @@ on:
|
||||
- .github/workflows/go-tests-other-os.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
env:
|
||||
GO_VERSION: '~1.21.0'
|
||||
jobs:
|
||||
test-mac:
|
||||
name: Test MacOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Set up Go 1.20
|
||||
- name: Set up Go ${{ env.GO_VERSION }}
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
@@ -47,10 +49,10 @@ jobs:
|
||||
name: Test Windows
|
||||
runs-on: windows-latest-xl
|
||||
steps:
|
||||
- name: Set up Go 1.20
|
||||
- name: Set up Go ${{ env.GO_VERSION }}
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
|
||||
6
.github/workflows/go-tests.yml
vendored
6
.github/workflows/go-tests.yml
vendored
@@ -15,15 +15,17 @@ on:
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
env:
|
||||
GO_VERSION: '~1.21.0'
|
||||
jobs:
|
||||
test-linux:
|
||||
name: Test Linux (Ubuntu)
|
||||
runs-on: ubuntu-latest-xl
|
||||
steps:
|
||||
- name: Set up Go 1.20
|
||||
- name: Set up Go ${{ env.GO_VERSION }}
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
|
||||
1
.github/workflows/ruby-qltest.yml
vendored
1
.github/workflows/ruby-qltest.yml
vendored
@@ -14,6 +14,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/ruby-qltest.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
|
||||
@@ -4,6 +4,8 @@ provide:
|
||||
- "*/ql/test/qlpack.yml"
|
||||
- "*/ql/examples/qlpack.yml"
|
||||
- "*/ql/consistency-queries/qlpack.yml"
|
||||
- "*/ql/automodel/src/qlpack.yml"
|
||||
- "*/ql/automodel/test/qlpack.yml"
|
||||
- "shared/*/qlpack.yml"
|
||||
- "cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml"
|
||||
- "go/ql/config/legacy-support/qlpack.yml"
|
||||
|
||||
@@ -32,16 +32,6 @@
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll",
|
||||
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll"
|
||||
],
|
||||
"TaintTracking Java/C++/C#/Go/Python/Ruby/Swift": [
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll",
|
||||
"go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll",
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll",
|
||||
"swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll"
|
||||
],
|
||||
"TaintTracking Legacy Configuration Java/C++/C#/Go/Python/Ruby/Swift": [
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||
@@ -65,15 +55,6 @@
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||
"swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
|
||||
],
|
||||
"DataFlow Java/C++/C#/Python/Ruby/Swift Consistency checks": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll",
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll",
|
||||
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll"
|
||||
],
|
||||
"DataFlow Java/C#/Go/Ruby/Python/Swift Flow Summaries": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll",
|
||||
@@ -566,5 +547,9 @@
|
||||
"EncryptionKeySizes Python/Java": [
|
||||
"python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll",
|
||||
"java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll"
|
||||
],
|
||||
"Python model summaries test extension": [
|
||||
"python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml",
|
||||
"python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,22 @@
|
||||
## 0.9.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.9.2
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* `getAllocatorCall` on `DeleteExpr` and `DeleteArrayExpr` has been deprecated. `getDeallocatorCall` should be used instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added `DeleteOrDeleteArrayExpr` as a super type of `DeleteExpr` and `DeleteArrayExpr`
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* `delete` and `delete[]` are now modeled as calls to the relevant `operator delete` in the IR. In the case of a dynamic delete call a new instruction `VirtualDeleteFunctionAddress` is used to represent a function that dispatches to the correct delete implementation.
|
||||
* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`.
|
||||
|
||||
## 0.9.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
14
cpp/ql/lib/change-notes/released/0.9.2.md
Normal file
14
cpp/ql/lib/change-notes/released/0.9.2.md
Normal file
@@ -0,0 +1,14 @@
|
||||
## 0.9.2
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* `getAllocatorCall` on `DeleteExpr` and `DeleteArrayExpr` has been deprecated. `getDeallocatorCall` should be used instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added `DeleteOrDeleteArrayExpr` as a super type of `DeleteExpr` and `DeleteArrayExpr`
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* `delete` and `delete[]` are now modeled as calls to the relevant `operator delete` in the IR. In the case of a dynamic delete call a new instruction `VirtualDeleteFunctionAddress` is used to represent a function that dispatches to the correct delete implementation.
|
||||
* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`.
|
||||
3
cpp/ql/lib/change-notes/released/0.9.3.md
Normal file
3
cpp/ql/lib/change-notes/released/0.9.3.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.9.3
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.9.1
|
||||
lastReleaseVersion: 0.9.3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.9.1
|
||||
version: 0.9.3
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -826,17 +826,11 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
|
||||
or
|
||||
expr.(Conversion).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(DeleteArrayExpr).getAllocatorCall() = ele and pred = "getAllocatorCall()"
|
||||
expr.(DeleteOrDeleteArrayExpr).getDeallocatorCall() = ele and pred = "getDeallocatorCall()"
|
||||
or
|
||||
expr.(DeleteArrayExpr).getDestructorCall() = ele and pred = "getDestructorCall()"
|
||||
expr.(DeleteOrDeleteArrayExpr).getDestructorCall() = ele and pred = "getDestructorCall()"
|
||||
or
|
||||
expr.(DeleteArrayExpr).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(DeleteExpr).getAllocatorCall() = ele and pred = "getAllocatorCall()"
|
||||
or
|
||||
expr.(DeleteExpr).getDestructorCall() = ele and pred = "getDestructorCall()"
|
||||
or
|
||||
expr.(DeleteExpr).getExpr() = ele and pred = "getExpr()"
|
||||
expr.(DeleteOrDeleteArrayExpr).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(DestructorFieldDestruction).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
|
||||
@@ -332,21 +332,12 @@ private Node getControlOrderChildSparse(Node n, int i) {
|
||||
n = any(ConditionDeclExpr cd | i = 0 and result = cd.getInitializingExpr())
|
||||
or
|
||||
n =
|
||||
any(DeleteExpr del |
|
||||
any(DeleteOrDeleteArrayExpr del |
|
||||
i = 0 and result = del.getExpr()
|
||||
or
|
||||
i = 1 and result = del.getDestructorCall()
|
||||
or
|
||||
i = 2 and result = del.getAllocatorCall()
|
||||
)
|
||||
or
|
||||
n =
|
||||
any(DeleteArrayExpr del |
|
||||
i = 0 and result = del.getExpr()
|
||||
or
|
||||
i = 1 and result = del.getDestructorCall()
|
||||
or
|
||||
i = 2 and result = del.getAllocatorCall()
|
||||
i = 2 and result = del.getDeallocatorCall()
|
||||
)
|
||||
or
|
||||
n =
|
||||
|
||||
@@ -25,6 +25,10 @@ import semmle.code.cpp.dataflow.DataFlow2
|
||||
* global (inter-procedural) taint-tracking analyses.
|
||||
*/
|
||||
deprecated module TaintTracking {
|
||||
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTracking
|
||||
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingParameter::Public
|
||||
private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific
|
||||
private import semmle.code.cpp.dataflow.internal.TaintTrackingImplSpecific
|
||||
private import codeql.dataflow.TaintTracking
|
||||
import TaintFlowMake<CppOldDataFlow, CppOldTaintTracking>
|
||||
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||
}
|
||||
|
||||
@@ -3,297 +3,25 @@
|
||||
* data-flow classes and predicates.
|
||||
*/
|
||||
|
||||
private import DataFlowImplSpecific::Private
|
||||
private import DataFlowImplSpecific::Public
|
||||
private import tainttracking1.TaintTrackingParameter::Private
|
||||
private import tainttracking1.TaintTrackingParameter::Public
|
||||
private import cpp
|
||||
private import DataFlowImplSpecific
|
||||
private import TaintTrackingImplSpecific
|
||||
private import codeql.dataflow.internal.DataFlowImplConsistency
|
||||
|
||||
module Consistency {
|
||||
private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
|
||||
|
||||
/** A class for configuring the consistency queries. */
|
||||
class ConsistencyConfiguration extends TConsistencyConfiguration {
|
||||
string toString() { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
|
||||
predicate uniqueEnclosingCallableExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
|
||||
predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
|
||||
predicate uniqueNodeLocationExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `missingLocation`. */
|
||||
predicate missingLocationExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
|
||||
predicate postWithInFlowExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
|
||||
predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `reverseRead`. */
|
||||
predicate reverseReadExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
|
||||
predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
|
||||
predicate uniquePostUpdateExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
|
||||
predicate viableImplInCallContextTooLargeExclude(
|
||||
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
|
||||
) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
|
||||
predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
|
||||
predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
|
||||
predicate identityLocalStepExclude(Node n) { none() }
|
||||
}
|
||||
|
||||
private class RelevantNode extends Node {
|
||||
RelevantNode() {
|
||||
this instanceof ArgumentNode or
|
||||
this instanceof ParameterNode or
|
||||
this instanceof ReturnNode or
|
||||
this = getAnOutNode(_, _) or
|
||||
simpleLocalFlowStep(this, _) or
|
||||
simpleLocalFlowStep(_, this) or
|
||||
jumpStep(this, _) or
|
||||
jumpStep(_, this) or
|
||||
storeStep(this, _, _) or
|
||||
storeStep(_, _, this) or
|
||||
readStep(this, _, _) or
|
||||
readStep(_, _, this) or
|
||||
defaultAdditionalTaintStep(this, _) or
|
||||
defaultAdditionalTaintStep(_, this)
|
||||
}
|
||||
}
|
||||
|
||||
query predicate uniqueEnclosingCallable(Node n, string msg) {
|
||||
exists(int c |
|
||||
n instanceof RelevantNode and
|
||||
c = count(nodeGetEnclosingCallable(n)) and
|
||||
c != 1 and
|
||||
not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
|
||||
msg = "Node should have one enclosing callable but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) {
|
||||
exists(int c |
|
||||
c = count(call.getEnclosingCallable()) and
|
||||
c != 1 and
|
||||
not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
|
||||
msg = "Call should have one enclosing callable but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueType(Node n, string msg) {
|
||||
exists(int c |
|
||||
n instanceof RelevantNode and
|
||||
c = count(getNodeType(n)) and
|
||||
c != 1 and
|
||||
msg = "Node should have one type but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueNodeLocation(Node n, string msg) {
|
||||
exists(int c |
|
||||
c =
|
||||
count(string filepath, int startline, int startcolumn, int endline, int endcolumn |
|
||||
n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
) and
|
||||
c != 1 and
|
||||
not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
|
||||
msg = "Node should have one location but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate missingLocation(string msg) {
|
||||
exists(int c |
|
||||
c =
|
||||
strictcount(Node n |
|
||||
not n.hasLocationInfo(_, _, _, _, _) and
|
||||
not any(ConsistencyConfiguration conf).missingLocationExclude(n)
|
||||
) and
|
||||
msg = "Nodes without location: " + c
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueNodeToString(Node n, string msg) {
|
||||
exists(int c |
|
||||
c = count(n.toString()) and
|
||||
c != 1 and
|
||||
msg = "Node should have one toString but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate missingToString(string msg) {
|
||||
exists(int c |
|
||||
c = strictcount(Node n | not exists(n.toString())) and
|
||||
msg = "Nodes without toString: " + c
|
||||
)
|
||||
}
|
||||
|
||||
query predicate parameterCallable(ParameterNode p, string msg) {
|
||||
exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
|
||||
msg = "Callable mismatch for parameter."
|
||||
}
|
||||
|
||||
query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
|
||||
simpleLocalFlowStep(n1, n2) and
|
||||
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
|
||||
msg = "Local flow step does not preserve enclosing callable."
|
||||
}
|
||||
|
||||
query predicate readStepIsLocal(Node n1, Node n2, string msg) {
|
||||
readStep(n1, _, n2) and
|
||||
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
|
||||
msg = "Read step does not preserve enclosing callable."
|
||||
}
|
||||
|
||||
query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
|
||||
storeStep(n1, _, n2) and
|
||||
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
|
||||
msg = "Store step does not preserve enclosing callable."
|
||||
}
|
||||
|
||||
private DataFlowType typeRepr() { result = getNodeType(_) }
|
||||
|
||||
query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
|
||||
t = typeRepr() and
|
||||
not compatibleTypes(t, t) and
|
||||
msg = "Type compatibility predicate is not reflexive."
|
||||
}
|
||||
|
||||
query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
|
||||
isUnreachableInCall(n, call) and
|
||||
exists(DataFlowCallable c |
|
||||
c = nodeGetEnclosingCallable(n) and
|
||||
not viableCallable(call) = c
|
||||
) and
|
||||
msg = "Call context for isUnreachableInCall is inconsistent with call graph."
|
||||
}
|
||||
|
||||
query predicate localCallNodes(DataFlowCall call, Node n, string msg) {
|
||||
(
|
||||
n = getAnOutNode(call, _) and
|
||||
msg = "OutNode and call does not share enclosing callable."
|
||||
or
|
||||
n.(ArgumentNode).argumentOf(call, _) and
|
||||
msg = "ArgumentNode and call does not share enclosing callable."
|
||||
) and
|
||||
nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
|
||||
}
|
||||
|
||||
// This predicate helps the compiler forget that in some languages
|
||||
// it is impossible for a result of `getPreUpdateNode` to be an
|
||||
// instance of `PostUpdateNode`.
|
||||
private Node getPre(PostUpdateNode n) {
|
||||
result = n.getPreUpdateNode()
|
||||
private module Input implements InputSig<CppOldDataFlow> {
|
||||
predicate argHasPostUpdateExclude(Private::ArgumentNode n) {
|
||||
// Is the null pointer (or something that's not really a pointer)
|
||||
exists(n.asExpr().getValue())
|
||||
or
|
||||
none()
|
||||
}
|
||||
|
||||
query predicate postIsNotPre(PostUpdateNode n, string msg) {
|
||||
getPre(n) = n and
|
||||
msg = "PostUpdateNode should not equal its pre-update node."
|
||||
}
|
||||
|
||||
query predicate postHasUniquePre(PostUpdateNode n, string msg) {
|
||||
not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
|
||||
exists(int c |
|
||||
c = count(n.getPreUpdateNode()) and
|
||||
c != 1 and
|
||||
msg = "PostUpdateNode should have one pre-update node but has " + c + "."
|
||||
// Isn't a pointer or is a pointer to const
|
||||
forall(DerivedType dt | dt = n.asExpr().getActualType() |
|
||||
dt.getBaseType().isConst()
|
||||
or
|
||||
dt.getBaseType() instanceof RoutineType
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniquePostUpdate(Node n, string msg) {
|
||||
not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
|
||||
1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
|
||||
msg = "Node has multiple PostUpdateNodes."
|
||||
}
|
||||
|
||||
query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
|
||||
nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
|
||||
msg = "PostUpdateNode does not share callable with its pre-update node."
|
||||
}
|
||||
|
||||
private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
|
||||
|
||||
query predicate reverseRead(Node n, string msg) {
|
||||
exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
|
||||
not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
|
||||
msg = "Origin of readStep is missing a PostUpdateNode."
|
||||
}
|
||||
|
||||
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
|
||||
not hasPost(n) and
|
||||
not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
|
||||
msg = "ArgumentNode is missing PostUpdateNode."
|
||||
}
|
||||
|
||||
// This predicate helps the compiler forget that in some languages
|
||||
// it is impossible for a `PostUpdateNode` to be the target of
|
||||
// `simpleLocalFlowStep`.
|
||||
private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
|
||||
|
||||
query predicate postWithInFlow(Node n, string msg) {
|
||||
isPostUpdateNode(n) and
|
||||
not clearsContent(n, _) and
|
||||
simpleLocalFlowStep(_, n) and
|
||||
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
|
||||
msg = "PostUpdateNode should not be the target of local flow."
|
||||
}
|
||||
|
||||
query predicate viableImplInCallContextTooLarge(
|
||||
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
|
||||
) {
|
||||
callable = viableImplInCallContext(call, ctx) and
|
||||
not callable = viableCallable(call) and
|
||||
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
|
||||
}
|
||||
|
||||
query predicate uniqueParameterNodeAtPosition(
|
||||
DataFlowCallable c, ParameterPosition pos, Node p, string msg
|
||||
) {
|
||||
not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
|
||||
isParameterNode(p, c, pos) and
|
||||
not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
|
||||
msg = "Parameters with overlapping positions."
|
||||
}
|
||||
|
||||
query predicate uniqueParameterNodePosition(
|
||||
DataFlowCallable c, ParameterPosition pos, Node p, string msg
|
||||
) {
|
||||
not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
|
||||
isParameterNode(p, c, pos) and
|
||||
not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
|
||||
msg = "Parameter node with multiple positions."
|
||||
}
|
||||
|
||||
query predicate uniqueContentApprox(Content c, string msg) {
|
||||
not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
|
||||
msg = "Non-unique content approximation."
|
||||
}
|
||||
|
||||
query predicate identityLocalStep(Node n, string msg) {
|
||||
simpleLocalFlowStep(n, n) and
|
||||
not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
|
||||
msg = "Node steps to itself"
|
||||
// The above list of cases isn't exhaustive, but it narrows down the
|
||||
// consistency alerts enough that most of them are interesting.
|
||||
}
|
||||
}
|
||||
|
||||
module Consistency = MakeConsistency<CppOldDataFlow, CppOldTaintTracking, Input>;
|
||||
|
||||
@@ -2,7 +2,6 @@ private import cpp
|
||||
private import DataFlowUtil
|
||||
private import DataFlowDispatch
|
||||
private import FlowVar
|
||||
private import DataFlowImplConsistency
|
||||
private import codeql.util.Unit
|
||||
|
||||
/** Gets the callable in which this node occurs. */
|
||||
@@ -297,22 +296,6 @@ class ContentApprox = Unit;
|
||||
pragma[inline]
|
||||
ContentApprox getContentApprox(Content c) { any() }
|
||||
|
||||
private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
|
||||
override predicate argHasPostUpdateExclude(ArgumentNode n) {
|
||||
// Is the null pointer (or something that's not really a pointer)
|
||||
exists(n.asExpr().getValue())
|
||||
or
|
||||
// Isn't a pointer or is a pointer to const
|
||||
forall(DerivedType dt | dt = n.asExpr().getActualType() |
|
||||
dt.getBaseType().isConst()
|
||||
or
|
||||
dt.getBaseType() instanceof RoutineType
|
||||
)
|
||||
// The above list of cases isn't exhaustive, but it narrows down the
|
||||
// consistency alerts enough that most of them are interesting.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an additional term that is added to the `join` and `branch` computations to reflect
|
||||
* an additional forward or backwards branching factor that is not taken into account
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Provides C++-specific definitions for use in the taint tracking library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.TaintTracking
|
||||
private import DataFlowImplSpecific
|
||||
|
||||
module CppOldTaintTracking implements InputSig<CppOldDataFlow> {
|
||||
import TaintTrackingUtil
|
||||
}
|
||||
@@ -39,7 +39,7 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
* of `c` at sinks and inputs to additional taint steps.
|
||||
*/
|
||||
bindingset[node]
|
||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { none() }
|
||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() }
|
||||
|
||||
/**
|
||||
* Holds if `node` should be a sanitizer in all global taint flow configurations
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/**
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) taint-tracking analyses.
|
||||
*/
|
||||
|
||||
import TaintTrackingParameter::Public
|
||||
private import TaintTrackingParameter::Private
|
||||
|
||||
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
|
||||
DataFlowInternal::FullStateConfigSig
|
||||
{
|
||||
import Config
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
Config::isBarrier(node) or defaultTaintSanitizer(node)
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
Config::isAdditionalFlowStep(node1, node2) or
|
||||
defaultAdditionalTaintStep(node1, node2)
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
|
||||
Config::allowImplicitRead(node, c)
|
||||
or
|
||||
(
|
||||
Config::isSink(node) or
|
||||
Config::isSink(node, _) or
|
||||
Config::isAdditionalFlowStep(node, _) or
|
||||
Config::isAdditionalFlowStep(node, _, _, _)
|
||||
) and
|
||||
defaultImplicitTaintRead(node, c)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a global taint tracking computation.
|
||||
*/
|
||||
module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
|
||||
private module Config0 implements DataFlowInternal::FullStateConfigSig {
|
||||
import DataFlowInternal::DefaultState<Config>
|
||||
import Config
|
||||
}
|
||||
|
||||
private module C implements DataFlowInternal::FullStateConfigSig {
|
||||
import AddTaintDefaults<Config0>
|
||||
}
|
||||
|
||||
import DataFlowInternal::Impl<C>
|
||||
}
|
||||
|
||||
/** DEPRECATED: Use `Global` instead. */
|
||||
deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
|
||||
import Global<Config>
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a global taint tracking computation using flow state.
|
||||
*/
|
||||
module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
|
||||
private module Config0 implements DataFlowInternal::FullStateConfigSig {
|
||||
import Config
|
||||
}
|
||||
|
||||
private module C implements DataFlowInternal::FullStateConfigSig {
|
||||
import AddTaintDefaults<Config0>
|
||||
}
|
||||
|
||||
import DataFlowInternal::Impl<C>
|
||||
}
|
||||
|
||||
/** DEPRECATED: Use `GlobalWithState` instead. */
|
||||
deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
|
||||
import GlobalWithState<Config>
|
||||
}
|
||||
@@ -23,6 +23,10 @@ import semmle.code.cpp.dataflow.new.DataFlow2
|
||||
* global (inter-procedural) taint-tracking analyses.
|
||||
*/
|
||||
module TaintTracking {
|
||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTracking
|
||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingParameter::Public
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific
|
||||
private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific
|
||||
private import codeql.dataflow.TaintTracking
|
||||
import TaintFlowMake<CppDataFlow, CppTaintTracking>
|
||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||
}
|
||||
|
||||
@@ -932,19 +932,91 @@ class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
|
||||
Expr getExtent() { result = this.getChild(2) }
|
||||
}
|
||||
|
||||
private class TDeleteOrDeleteArrayExpr = @delete_expr or @delete_array_expr;
|
||||
|
||||
/**
|
||||
* A C++ `delete` or `delete[]` expression.
|
||||
*/
|
||||
class DeleteOrDeleteArrayExpr extends Expr, TDeleteOrDeleteArrayExpr {
|
||||
override int getPrecedence() { result = 16 }
|
||||
|
||||
/**
|
||||
* Gets the call to a destructor that occurs prior to the object's memory being deallocated, if any.
|
||||
*
|
||||
* In the case of `delete[]` at runtime, the destructor will be called once for each element in the array, but the
|
||||
* destructor call only exists once in the AST.
|
||||
*/
|
||||
DestructorCall getDestructorCall() { result = this.getChild(1) }
|
||||
|
||||
/**
|
||||
* Gets the destructor to be called to destroy the object or array, if any.
|
||||
*/
|
||||
Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
|
||||
|
||||
/**
|
||||
* Gets the `operator delete` or `operator delete[]` that deallocates storage.
|
||||
* Does not hold if the type being destroyed has a virtual destructor. In that case, the
|
||||
* `operator delete` that will be called is determined at runtime based on the
|
||||
* dynamic type of the object.
|
||||
*/
|
||||
Function getDeallocator() {
|
||||
expr_deallocator(underlyingElement(this), unresolveElement(result), _)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getDeallocatorCall` instead.
|
||||
*/
|
||||
deprecated FunctionCall getAllocatorCall() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the call to a non-default `operator delete`/`delete[]` that deallocates storage, if any.
|
||||
*
|
||||
* This will only be present when the type being deleted has a custom `operator delete` and
|
||||
* does not have a virtual destructor.
|
||||
*/
|
||||
FunctionCall getDeallocatorCall() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Holds if the deallocation function expects a size argument.
|
||||
*/
|
||||
predicate hasSizedDeallocation() {
|
||||
exists(int form |
|
||||
expr_deallocator(underlyingElement(this), _, form) and
|
||||
form.bitAnd(1) != 0 // Bit zero is the "size" bit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the deallocation function expects an alignment argument.
|
||||
*/
|
||||
predicate hasAlignedDeallocation() {
|
||||
exists(int form |
|
||||
expr_deallocator(underlyingElement(this), _, form) and
|
||||
form.bitAnd(2) != 0 // Bit one is the "alignment" bit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the object or array being deleted.
|
||||
*/
|
||||
Expr getExpr() {
|
||||
// If there is a destructor call, the object being deleted is the qualifier
|
||||
// otherwise it is the third child.
|
||||
result = this.getChild(3) or result = this.getDestructorCall().getQualifier()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `delete` (non-array) expression.
|
||||
* ```
|
||||
* delete ptr;
|
||||
* ```
|
||||
*/
|
||||
class DeleteExpr extends Expr, @delete_expr {
|
||||
class DeleteExpr extends DeleteOrDeleteArrayExpr, @delete_expr {
|
||||
override string toString() { result = "delete" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DeleteExpr" }
|
||||
|
||||
override int getPrecedence() { result = 16 }
|
||||
|
||||
/**
|
||||
* Gets the compile-time type of the object being deleted.
|
||||
*/
|
||||
@@ -957,58 +1029,6 @@ class DeleteExpr extends Expr, @delete_expr {
|
||||
.(PointerType)
|
||||
.getBaseType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the call to a destructor that occurs prior to the object's memory being deallocated, if any.
|
||||
*/
|
||||
DestructorCall getDestructorCall() { result = this.getChild(1) }
|
||||
|
||||
/**
|
||||
* Gets the destructor to be called to destroy the object, if any.
|
||||
*/
|
||||
Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
|
||||
|
||||
/**
|
||||
* Gets the `operator delete` that deallocates storage. Does not hold
|
||||
* if the type being destroyed has a virtual destructor. In that case, the
|
||||
* `operator delete` that will be called is determined at runtime based on the
|
||||
* dynamic type of the object.
|
||||
*/
|
||||
Function getDeallocator() {
|
||||
expr_deallocator(underlyingElement(this), unresolveElement(result), _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the deallocation function expects a size argument.
|
||||
*/
|
||||
predicate hasSizedDeallocation() {
|
||||
exists(int form |
|
||||
expr_deallocator(underlyingElement(this), _, form) and
|
||||
form.bitAnd(1) != 0 // Bit zero is the "size" bit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the deallocation function expects an alignment argument.
|
||||
*/
|
||||
predicate hasAlignedDeallocation() {
|
||||
exists(int form |
|
||||
expr_deallocator(underlyingElement(this), _, form) and
|
||||
form.bitAnd(2) != 0 // Bit one is the "alignment" bit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the call to a non-default `operator delete` that deallocates storage, if any.
|
||||
*
|
||||
* This will only be present when the type being deleted has a custom `operator delete`.
|
||||
*/
|
||||
FunctionCall getAllocatorCall() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the object being deleted.
|
||||
*/
|
||||
Expr getExpr() { result = this.getChild(3) or result = this.getChild(1).getChild(-1) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1017,13 +1037,11 @@ class DeleteExpr extends Expr, @delete_expr {
|
||||
* delete[] arr;
|
||||
* ```
|
||||
*/
|
||||
class DeleteArrayExpr extends Expr, @delete_array_expr {
|
||||
class DeleteArrayExpr extends DeleteOrDeleteArrayExpr, @delete_array_expr {
|
||||
override string toString() { result = "delete[]" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DeleteArrayExpr" }
|
||||
|
||||
override int getPrecedence() { result = 16 }
|
||||
|
||||
/**
|
||||
* Gets the element type of the array being deleted.
|
||||
*/
|
||||
@@ -1036,58 +1054,6 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
|
||||
.(PointerType)
|
||||
.getBaseType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the call to a destructor that occurs prior to the array's memory being deallocated, if any.
|
||||
*
|
||||
* At runtime, the destructor will be called once for each element in the array, but the
|
||||
* destructor call only exists once in the AST.
|
||||
*/
|
||||
DestructorCall getDestructorCall() { result = this.getChild(1) }
|
||||
|
||||
/**
|
||||
* Gets the destructor to be called to destroy each element in the array, if any.
|
||||
*/
|
||||
Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
|
||||
|
||||
/**
|
||||
* Gets the `operator delete[]` that deallocates storage.
|
||||
*/
|
||||
Function getDeallocator() {
|
||||
expr_deallocator(underlyingElement(this), unresolveElement(result), _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the deallocation function expects a size argument.
|
||||
*/
|
||||
predicate hasSizedDeallocation() {
|
||||
exists(int form |
|
||||
expr_deallocator(underlyingElement(this), _, form) and
|
||||
form.bitAnd(1) != 0 // Bit zero is the "size" bit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the deallocation function expects an alignment argument.
|
||||
*/
|
||||
predicate hasAlignedDeallocation() {
|
||||
exists(int form |
|
||||
expr_deallocator(underlyingElement(this), _, form) and
|
||||
form.bitAnd(2) != 0 // Bit one is the "alignment" bit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the call to a non-default `operator delete` that deallocates storage, if any.
|
||||
*
|
||||
* This will only be present when the type being deleted has a custom `operator delete`.
|
||||
*/
|
||||
FunctionCall getAllocatorCall() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the array being deleted.
|
||||
*/
|
||||
Expr getExpr() { result = this.getChild(3) or result = this.getChild(1).getChild(-1) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,10 @@ import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
import semmle.code.cpp.ir.dataflow.DataFlow2
|
||||
|
||||
module TaintTracking {
|
||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTracking
|
||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingParameter::Public
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific
|
||||
private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific
|
||||
private import codeql.dataflow.TaintTracking
|
||||
import TaintFlowMake<CppDataFlow, CppTaintTracking>
|
||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||
}
|
||||
|
||||
@@ -3,297 +3,17 @@
|
||||
* data-flow classes and predicates.
|
||||
*/
|
||||
|
||||
private import DataFlowImplSpecific::Private
|
||||
private import DataFlowImplSpecific::Public
|
||||
private import tainttracking1.TaintTrackingParameter::Private
|
||||
private import tainttracking1.TaintTrackingParameter::Public
|
||||
private import cpp
|
||||
private import DataFlowImplSpecific
|
||||
private import TaintTrackingImplSpecific
|
||||
private import codeql.dataflow.internal.DataFlowImplConsistency
|
||||
|
||||
module Consistency {
|
||||
private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
|
||||
|
||||
/** A class for configuring the consistency queries. */
|
||||
class ConsistencyConfiguration extends TConsistencyConfiguration {
|
||||
string toString() { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */
|
||||
predicate uniqueEnclosingCallableExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */
|
||||
predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */
|
||||
predicate uniqueNodeLocationExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `missingLocation`. */
|
||||
predicate missingLocationExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
|
||||
predicate postWithInFlowExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
|
||||
predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `reverseRead`. */
|
||||
predicate reverseReadExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */
|
||||
predicate postHasUniquePreExclude(PostUpdateNode n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
|
||||
predicate uniquePostUpdateExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
|
||||
predicate viableImplInCallContextTooLargeExclude(
|
||||
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
|
||||
) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */
|
||||
predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */
|
||||
predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
|
||||
predicate identityLocalStepExclude(Node n) { none() }
|
||||
}
|
||||
|
||||
private class RelevantNode extends Node {
|
||||
RelevantNode() {
|
||||
this instanceof ArgumentNode or
|
||||
this instanceof ParameterNode or
|
||||
this instanceof ReturnNode or
|
||||
this = getAnOutNode(_, _) or
|
||||
simpleLocalFlowStep(this, _) or
|
||||
simpleLocalFlowStep(_, this) or
|
||||
jumpStep(this, _) or
|
||||
jumpStep(_, this) or
|
||||
storeStep(this, _, _) or
|
||||
storeStep(_, _, this) or
|
||||
readStep(this, _, _) or
|
||||
readStep(_, _, this) or
|
||||
defaultAdditionalTaintStep(this, _) or
|
||||
defaultAdditionalTaintStep(_, this)
|
||||
}
|
||||
}
|
||||
|
||||
query predicate uniqueEnclosingCallable(Node n, string msg) {
|
||||
exists(int c |
|
||||
n instanceof RelevantNode and
|
||||
c = count(nodeGetEnclosingCallable(n)) and
|
||||
c != 1 and
|
||||
not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and
|
||||
msg = "Node should have one enclosing callable but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) {
|
||||
exists(int c |
|
||||
c = count(call.getEnclosingCallable()) and
|
||||
c != 1 and
|
||||
not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and
|
||||
msg = "Call should have one enclosing callable but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueType(Node n, string msg) {
|
||||
exists(int c |
|
||||
n instanceof RelevantNode and
|
||||
c = count(getNodeType(n)) and
|
||||
c != 1 and
|
||||
msg = "Node should have one type but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueNodeLocation(Node n, string msg) {
|
||||
exists(int c |
|
||||
c =
|
||||
count(string filepath, int startline, int startcolumn, int endline, int endcolumn |
|
||||
n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
) and
|
||||
c != 1 and
|
||||
not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and
|
||||
msg = "Node should have one location but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate missingLocation(string msg) {
|
||||
exists(int c |
|
||||
c =
|
||||
strictcount(Node n |
|
||||
not n.hasLocationInfo(_, _, _, _, _) and
|
||||
not any(ConsistencyConfiguration conf).missingLocationExclude(n)
|
||||
) and
|
||||
msg = "Nodes without location: " + c
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniqueNodeToString(Node n, string msg) {
|
||||
exists(int c |
|
||||
c = count(n.toString()) and
|
||||
c != 1 and
|
||||
msg = "Node should have one toString but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate missingToString(string msg) {
|
||||
exists(int c |
|
||||
c = strictcount(Node n | not exists(n.toString())) and
|
||||
msg = "Nodes without toString: " + c
|
||||
)
|
||||
}
|
||||
|
||||
query predicate parameterCallable(ParameterNode p, string msg) {
|
||||
exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and
|
||||
msg = "Callable mismatch for parameter."
|
||||
}
|
||||
|
||||
query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
|
||||
simpleLocalFlowStep(n1, n2) and
|
||||
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
|
||||
msg = "Local flow step does not preserve enclosing callable."
|
||||
}
|
||||
|
||||
query predicate readStepIsLocal(Node n1, Node n2, string msg) {
|
||||
readStep(n1, _, n2) and
|
||||
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
|
||||
msg = "Read step does not preserve enclosing callable."
|
||||
}
|
||||
|
||||
query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
|
||||
storeStep(n1, _, n2) and
|
||||
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
|
||||
msg = "Store step does not preserve enclosing callable."
|
||||
}
|
||||
|
||||
private DataFlowType typeRepr() { result = getNodeType(_) }
|
||||
|
||||
query predicate compatibleTypesReflexive(DataFlowType t, string msg) {
|
||||
t = typeRepr() and
|
||||
not compatibleTypes(t, t) and
|
||||
msg = "Type compatibility predicate is not reflexive."
|
||||
}
|
||||
|
||||
query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) {
|
||||
isUnreachableInCall(n, call) and
|
||||
exists(DataFlowCallable c |
|
||||
c = nodeGetEnclosingCallable(n) and
|
||||
not viableCallable(call) = c
|
||||
) and
|
||||
msg = "Call context for isUnreachableInCall is inconsistent with call graph."
|
||||
}
|
||||
|
||||
query predicate localCallNodes(DataFlowCall call, Node n, string msg) {
|
||||
(
|
||||
n = getAnOutNode(call, _) and
|
||||
msg = "OutNode and call does not share enclosing callable."
|
||||
or
|
||||
n.(ArgumentNode).argumentOf(call, _) and
|
||||
msg = "ArgumentNode and call does not share enclosing callable."
|
||||
) and
|
||||
nodeGetEnclosingCallable(n) != call.getEnclosingCallable()
|
||||
}
|
||||
|
||||
// This predicate helps the compiler forget that in some languages
|
||||
// it is impossible for a result of `getPreUpdateNode` to be an
|
||||
// instance of `PostUpdateNode`.
|
||||
private Node getPre(PostUpdateNode n) {
|
||||
result = n.getPreUpdateNode()
|
||||
or
|
||||
none()
|
||||
}
|
||||
|
||||
query predicate postIsNotPre(PostUpdateNode n, string msg) {
|
||||
getPre(n) = n and
|
||||
msg = "PostUpdateNode should not equal its pre-update node."
|
||||
}
|
||||
|
||||
query predicate postHasUniquePre(PostUpdateNode n, string msg) {
|
||||
not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and
|
||||
exists(int c |
|
||||
c = count(n.getPreUpdateNode()) and
|
||||
c != 1 and
|
||||
msg = "PostUpdateNode should have one pre-update node but has " + c + "."
|
||||
)
|
||||
}
|
||||
|
||||
query predicate uniquePostUpdate(Node n, string msg) {
|
||||
not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and
|
||||
1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and
|
||||
msg = "Node has multiple PostUpdateNodes."
|
||||
}
|
||||
|
||||
query predicate postIsInSameCallable(PostUpdateNode n, string msg) {
|
||||
nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and
|
||||
msg = "PostUpdateNode does not share callable with its pre-update node."
|
||||
}
|
||||
|
||||
private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
|
||||
|
||||
query predicate reverseRead(Node n, string msg) {
|
||||
exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
|
||||
not any(ConsistencyConfiguration conf).reverseReadExclude(n) and
|
||||
msg = "Origin of readStep is missing a PostUpdateNode."
|
||||
}
|
||||
|
||||
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
|
||||
not hasPost(n) and
|
||||
not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
|
||||
msg = "ArgumentNode is missing PostUpdateNode."
|
||||
}
|
||||
|
||||
// This predicate helps the compiler forget that in some languages
|
||||
// it is impossible for a `PostUpdateNode` to be the target of
|
||||
// `simpleLocalFlowStep`.
|
||||
private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
|
||||
|
||||
query predicate postWithInFlow(Node n, string msg) {
|
||||
isPostUpdateNode(n) and
|
||||
not clearsContent(n, _) and
|
||||
simpleLocalFlowStep(_, n) and
|
||||
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
|
||||
msg = "PostUpdateNode should not be the target of local flow."
|
||||
}
|
||||
|
||||
query predicate viableImplInCallContextTooLarge(
|
||||
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
|
||||
) {
|
||||
callable = viableImplInCallContext(call, ctx) and
|
||||
not callable = viableCallable(call) and
|
||||
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
|
||||
}
|
||||
|
||||
query predicate uniqueParameterNodeAtPosition(
|
||||
DataFlowCallable c, ParameterPosition pos, Node p, string msg
|
||||
) {
|
||||
not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and
|
||||
isParameterNode(p, c, pos) and
|
||||
not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and
|
||||
msg = "Parameters with overlapping positions."
|
||||
}
|
||||
|
||||
query predicate uniqueParameterNodePosition(
|
||||
DataFlowCallable c, ParameterPosition pos, Node p, string msg
|
||||
) {
|
||||
not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and
|
||||
isParameterNode(p, c, pos) and
|
||||
not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and
|
||||
msg = "Parameter node with multiple positions."
|
||||
}
|
||||
|
||||
query predicate uniqueContentApprox(Content c, string msg) {
|
||||
not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
|
||||
msg = "Non-unique content approximation."
|
||||
}
|
||||
|
||||
query predicate identityLocalStep(Node n, string msg) {
|
||||
simpleLocalFlowStep(n, n) and
|
||||
not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
|
||||
msg = "Node steps to itself"
|
||||
private module Input implements InputSig<CppDataFlow> {
|
||||
predicate argHasPostUpdateExclude(Private::ArgumentNode n) {
|
||||
// The rules for whether an IR argument gets a post-update node are too
|
||||
// complex to model here.
|
||||
any()
|
||||
}
|
||||
}
|
||||
|
||||
module Consistency = MakeConsistency<CppDataFlow, CppTaintTracking, Input>;
|
||||
|
||||
@@ -2,7 +2,6 @@ private import cpp as Cpp
|
||||
private import DataFlowUtil
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowDispatch
|
||||
private import DataFlowImplConsistency
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import SsaInternals as Ssa
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
@@ -220,9 +219,10 @@ private module IndirectOperands {
|
||||
int indirectionIndex;
|
||||
|
||||
IndirectOperandFromIRRepr() {
|
||||
exists(Operand repr |
|
||||
repr = Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex) and
|
||||
nodeHasOperand(this, repr, indirectionIndex - 1)
|
||||
exists(Operand repr, int indirectionIndexRepr |
|
||||
Ssa::hasIRRepresentationOfIndirectOperand(operand, indirectionIndex, repr,
|
||||
indirectionIndexRepr) and
|
||||
nodeHasOperand(this, repr, indirectionIndexRepr)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -262,9 +262,10 @@ private module IndirectInstructions {
|
||||
int indirectionIndex;
|
||||
|
||||
IndirectInstructionFromIRRepr() {
|
||||
exists(Instruction repr |
|
||||
repr = Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex) and
|
||||
nodeHasInstruction(this, repr, indirectionIndex - 1)
|
||||
exists(Instruction repr, int indirectionIndexRepr |
|
||||
Ssa::hasIRRepresentationOfIndirectInstruction(instr, indirectionIndex, repr,
|
||||
indirectionIndexRepr) and
|
||||
nodeHasInstruction(this, repr, indirectionIndexRepr)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -690,7 +691,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { storeStepImpl(node1,
|
||||
private predicate numberOfLoadsFromOperandRec(
|
||||
Operand operandFrom, Operand operandTo, int ind, boolean certain
|
||||
) {
|
||||
exists(Instruction load | Ssa::isDereference(load, operandFrom) |
|
||||
exists(Instruction load | Ssa::isDereference(load, operandFrom, _) |
|
||||
operandTo = operandFrom and ind = 0 and certain = true
|
||||
or
|
||||
numberOfLoadsFromOperand(load.getAUse(), operandTo, ind - 1, certain)
|
||||
@@ -714,7 +715,7 @@ private predicate numberOfLoadsFromOperand(
|
||||
) {
|
||||
numberOfLoadsFromOperandRec(operandFrom, operandTo, n, certain)
|
||||
or
|
||||
not Ssa::isDereference(_, operandFrom) and
|
||||
not Ssa::isDereference(_, operandFrom, _) and
|
||||
not conversionFlow(operandFrom, _, _, _) and
|
||||
operandFrom = operandTo and
|
||||
n = 0 and
|
||||
@@ -1011,14 +1012,6 @@ ContentApprox getContentApprox(Content c) {
|
||||
)
|
||||
}
|
||||
|
||||
private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
|
||||
override predicate argHasPostUpdateExclude(ArgumentNode n) {
|
||||
// The rules for whether an IR argument gets a post-update node are too
|
||||
// complex to model here.
|
||||
any()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A local flow relation that includes both local steps, read steps and
|
||||
* argument-to-return flow through summarized functions.
|
||||
|
||||
@@ -550,11 +550,14 @@ class SsaPhiNode extends Node, TSsaPhiNode {
|
||||
* `fromBackEdge` is true if data flows along a back-edge,
|
||||
* and `false` otherwise.
|
||||
*/
|
||||
cached
|
||||
final Node getAnInput(boolean fromBackEdge) {
|
||||
localFlowStep(result, this) and
|
||||
if phi.getBasicBlock().dominates(result.getBasicBlock())
|
||||
then fromBackEdge = true
|
||||
else fromBackEdge = false
|
||||
exists(IRBlock bPhi, IRBlock bResult |
|
||||
bPhi = phi.getBasicBlock() and bResult = result.getBasicBlock()
|
||||
|
|
||||
if bPhi.dominates(bResult) then fromBackEdge = true else fromBackEdge = false
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a node that is used as input to this phi node. */
|
||||
|
||||
@@ -87,6 +87,30 @@ module ProductFlow {
|
||||
* dataflow graph.
|
||||
*/
|
||||
default predicate isBarrierIn2(DataFlow::Node node) { none() }
|
||||
|
||||
/**
|
||||
* Gets the virtual dispatch branching limit when calculating field flow in the first
|
||||
* projection of the product dataflow graph.
|
||||
*
|
||||
* This can be overridden to a smaller value to improve performance (a
|
||||
* value of 0 disables field flow), or a larger value to get more results.
|
||||
*/
|
||||
default int fieldFlowBranchLimit1() {
|
||||
// NOTE: This should be synchronized with the default value in the shared dataflow library
|
||||
result = 2
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual dispatch branching limit when calculating field flow in the second
|
||||
* projection of the product dataflow graph.
|
||||
*
|
||||
* This can be overridden to a smaller value to improve performance (a
|
||||
* value of 0 disables field flow), or a larger value to get more results.
|
||||
*/
|
||||
default int fieldFlowBranchLimit2() {
|
||||
// NOTE: This should be synchronized with the default value in the shared dataflow library
|
||||
result = 2
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,6 +296,30 @@ module ProductFlow {
|
||||
* dataflow graph.
|
||||
*/
|
||||
default predicate isBarrierIn2(DataFlow::Node node) { none() }
|
||||
|
||||
/**
|
||||
* Gets the virtual dispatch branching limit when calculating field flow in the first
|
||||
* projection of the product dataflow graph.
|
||||
*
|
||||
* This can be overridden to a smaller value to improve performance (a
|
||||
* value of 0 disables field flow), or a larger value to get more results.
|
||||
*/
|
||||
default int fieldFlowBranchLimit1() {
|
||||
// NOTE: This should be synchronized with the default value in the shared dataflow library
|
||||
result = 2
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual dispatch branching limit when calculating field flow in the second
|
||||
* projection of the product dataflow graph.
|
||||
*
|
||||
* This can be overridden to a smaller value to improve performance (a
|
||||
* value of 0 disables field flow), or a larger value to get more results.
|
||||
*/
|
||||
default int fieldFlowBranchLimit2() {
|
||||
// NOTE: This should be synchronized with the default value in the shared dataflow library
|
||||
result = 2
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,6 +383,8 @@ module ProductFlow {
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) { Config::isBarrierIn1(node) }
|
||||
|
||||
int fieldFlowBranchLimit() { result = Config::fieldFlowBranchLimit1() }
|
||||
}
|
||||
|
||||
private module Flow1 = DataFlow::GlobalWithState<Config1>;
|
||||
@@ -367,6 +417,8 @@ module ProductFlow {
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) { Config::isBarrierIn2(node) }
|
||||
|
||||
int fieldFlowBranchLimit() { result = Config::fieldFlowBranchLimit2() }
|
||||
}
|
||||
|
||||
private module Flow2 = DataFlow::GlobalWithState<Config2>;
|
||||
|
||||
@@ -74,7 +74,7 @@ predicate hasRawIndirectOperand(Operand op, int indirectionIndex) {
|
||||
type = getLanguageType(op) and
|
||||
m = countIndirectionsForCppType(type) and
|
||||
indirectionIndex = [1 .. m] and
|
||||
not exists(getIRRepresentationOfIndirectOperand(op, indirectionIndex))
|
||||
not hasIRRepresentationOfIndirectOperand(op, indirectionIndex, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
|
||||
type = getResultLanguageType(instr) and
|
||||
m = countIndirectionsForCppType(type) and
|
||||
indirectionIndex = [1 .. m] and
|
||||
not exists(getIRRepresentationOfIndirectInstruction(instr, indirectionIndex))
|
||||
not hasIRRepresentationOfIndirectInstruction(instr, indirectionIndex, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ private newtype TDefOrUseImpl =
|
||||
} or
|
||||
TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) {
|
||||
isUse(_, operand, base, _, indirectionIndex) and
|
||||
not isDef(_, _, operand, _, _, _)
|
||||
not isDef(true, _, operand, _, _, _)
|
||||
} or
|
||||
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
|
||||
// Represents a final "use" of a global variable to ensure that
|
||||
@@ -610,7 +610,7 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
|
||||
hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and
|
||||
hasOperandAndIndex(nTo, op2, indirectionIndex - 1) and
|
||||
instr = op2.getDef() and
|
||||
isDereference(instr, op1)
|
||||
isDereference(instr, op1, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -638,12 +638,24 @@ private predicate adjustForPointerArith(PostUpdateNode pun, UseOrPhi use) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` flows to `nodeTo` because there is `def-use` or
|
||||
* `use-use` flow from `defOrUse` to `use`.
|
||||
*
|
||||
* `uncertain` is `true` if the `defOrUse` is an uncertain definition.
|
||||
*/
|
||||
private predicate localSsaFlow(
|
||||
SsaDefOrUse defOrUse, Node nodeFrom, UseOrPhi use, Node nodeTo, boolean uncertain
|
||||
) {
|
||||
nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and
|
||||
adjacentDefRead(defOrUse, use) and
|
||||
useToNode(use, nodeTo) and
|
||||
nodeFrom != nodeTo
|
||||
}
|
||||
|
||||
private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo, boolean uncertain) {
|
||||
exists(UseOrPhi use |
|
||||
nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and
|
||||
adjacentDefRead(defOrUse, use) and
|
||||
useToNode(use, nodeTo) and
|
||||
nodeFrom != nodeTo
|
||||
localSsaFlow(defOrUse, nodeFrom, use, nodeTo, uncertain)
|
||||
or
|
||||
// Initial global variable value to a first use
|
||||
nodeFrom.(InitialGlobalValue).getGlobalDef() = defOrUse and
|
||||
@@ -684,19 +696,99 @@ predicate ssaFlow(Node nodeFrom, Node nodeTo) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isArgumentOfCallable(DataFlowCall call, ArgumentNode arg) {
|
||||
arg.argumentOf(call, _)
|
||||
private predicate isArgumentOfCallableInstruction(DataFlowCall call, Instruction instr) {
|
||||
isArgumentOfCallableOperand(call, unique( | | getAUse(instr)))
|
||||
}
|
||||
|
||||
/** Holds if there is def-use or use-use flow from `pun` to `nodeTo`. */
|
||||
predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
|
||||
exists(UseOrPhi use, Node preUpdate |
|
||||
private predicate isArgumentOfCallableOperand(DataFlowCall call, Operand operand) {
|
||||
operand.(ArgumentOperand).getCall() = call
|
||||
or
|
||||
exists(FieldAddressInstruction fai |
|
||||
fai.getObjectAddressOperand() = operand and
|
||||
isArgumentOfCallableInstruction(call, fai)
|
||||
)
|
||||
or
|
||||
exists(Instruction deref |
|
||||
isArgumentOfCallableInstruction(call, deref) and
|
||||
isDereference(deref, operand, _)
|
||||
)
|
||||
or
|
||||
exists(Instruction instr |
|
||||
isArgumentOfCallableInstruction(call, instr) and
|
||||
conversionFlow(operand, instr, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isArgumentOfCallable(DataFlowCall call, Node n) {
|
||||
isArgumentOfCallableOperand(call, n.asOperand())
|
||||
or
|
||||
exists(Operand op |
|
||||
n.(IndirectOperand).hasOperandAndIndirectionIndex(op, _) and
|
||||
isArgumentOfCallableOperand(call, op)
|
||||
)
|
||||
or
|
||||
exists(Instruction instr |
|
||||
n.(IndirectInstruction).hasInstructionAndIndirectionIndex(instr, _) and
|
||||
isArgumentOfCallableInstruction(call, instr)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is use-use flow from `pun`'s pre-update node to `n`.
|
||||
*/
|
||||
private predicate postUpdateNodeToFirstUse(PostUpdateNode pun, Node n) {
|
||||
exists(UseOrPhi use |
|
||||
adjustForPointerArith(pun, use) and
|
||||
useToNode(use, nodeTo) and
|
||||
useToNode(use, n)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate stepUntilNotInCall(DataFlowCall call, Node n1, Node n2) {
|
||||
isArgumentOfCallable(call, n1) and
|
||||
exists(Node mid | localSsaFlow(_, n1, _, mid, _) |
|
||||
isArgumentOfCallable(call, mid) and
|
||||
stepUntilNotInCall(call, mid, n2)
|
||||
or
|
||||
not isArgumentOfCallable(call, mid) and
|
||||
mid = n2
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[n1, n2]
|
||||
pragma[inline_late]
|
||||
private predicate isArgumentOfSameCall(DataFlowCall call, Node n1, Node n2) {
|
||||
isArgumentOfCallable(call, n1) and isArgumentOfCallable(call, n2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is def-use or use-use flow from `pun` to `nodeTo`.
|
||||
*
|
||||
* Note: This is more complex than it sounds. Consider a call such as:
|
||||
* ```cpp
|
||||
* write_first_argument(x, x);
|
||||
* sink(x);
|
||||
* ```
|
||||
* Assume flow comes out of the first argument to `write_first_argument`. We
|
||||
* don't want flow to go to the `x` that's also an argument to
|
||||
* `write_first_argument` (because we just flowed out of that function, and we
|
||||
* don't want to flow back into it again).
|
||||
*
|
||||
* We do, however, want flow from the output argument to `x` on the next line, and
|
||||
* similarly we want flow from the second argument of `write_first_argument` to `x`
|
||||
* on the next line.
|
||||
*/
|
||||
predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
|
||||
exists(Node preUpdate, Node mid |
|
||||
preUpdate = pun.getPreUpdateNode() and
|
||||
not exists(DataFlowCall call |
|
||||
isArgumentOfCallable(call, preUpdate) and isArgumentOfCallable(call, nodeTo)
|
||||
postUpdateNodeToFirstUse(pun, mid)
|
||||
|
|
||||
exists(DataFlowCall call |
|
||||
isArgumentOfSameCall(call, preUpdate, mid) and
|
||||
stepUntilNotInCall(call, mid, nodeTo)
|
||||
)
|
||||
or
|
||||
not isArgumentOfSameCall(_, preUpdate, mid) and
|
||||
nodeTo = mid
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -320,10 +320,20 @@ private module IteratorIndirections {
|
||||
}
|
||||
}
|
||||
|
||||
predicate isDereference(Instruction deref, Operand address) {
|
||||
any(Indirection ind).isAdditionalDereference(deref, address)
|
||||
/**
|
||||
* Holds if `deref` is the result of loading the value at the address
|
||||
* represented by `address`.
|
||||
*
|
||||
* If `additional = true` then the dereference comes from an `Indirection`
|
||||
* class (such as a call to an iterator's `operator*`), and if
|
||||
* `additional = false` the dereference is a `LoadInstruction`.
|
||||
*/
|
||||
predicate isDereference(Instruction deref, Operand address, boolean additional) {
|
||||
any(Indirection ind).isAdditionalDereference(deref, address) and
|
||||
additional = true
|
||||
or
|
||||
deref.(LoadInstruction).getSourceAddressOperand() = address
|
||||
deref.(LoadInstruction).getSourceAddressOperand() = address and
|
||||
additional = false
|
||||
}
|
||||
|
||||
predicate isWrite(Node0Impl value, Operand address, boolean certain) {
|
||||
@@ -545,7 +555,7 @@ private module Cached {
|
||||
isDef(_, value, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and
|
||||
isUse(_, iteratorAddress, iteratorBase, numberOfLoads + 1, 0) and
|
||||
iteratorBase.getResultType() instanceof Interfaces::Iterator and
|
||||
isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse()) and
|
||||
isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse(), _) and
|
||||
memory = read.getSideEffectOperand().getAnyDef()
|
||||
)
|
||||
}
|
||||
@@ -781,11 +791,14 @@ private module Cached {
|
||||
* instead associated with the operand returned by this predicate.
|
||||
*/
|
||||
cached
|
||||
Operand getIRRepresentationOfIndirectOperand(Operand operand, int indirectionIndex) {
|
||||
predicate hasIRRepresentationOfIndirectOperand(
|
||||
Operand operand, int indirectionIndex, Operand operandRepr, int indirectionIndexRepr
|
||||
) {
|
||||
indirectionIndex = [1 .. countIndirectionsForCppType(getLanguageType(operand))] and
|
||||
exists(Instruction load |
|
||||
isDereference(load, operand) and
|
||||
result = unique( | | getAUse(load)) and
|
||||
isUseImpl(operand, _, indirectionIndex - 1)
|
||||
isDereference(load, operand, false) and
|
||||
operandRepr = unique( | | getAUse(load)) and
|
||||
indirectionIndexRepr = indirectionIndex - 1
|
||||
)
|
||||
}
|
||||
|
||||
@@ -797,12 +810,15 @@ private module Cached {
|
||||
* instead associated with the instruction returned by this predicate.
|
||||
*/
|
||||
cached
|
||||
Instruction getIRRepresentationOfIndirectInstruction(Instruction instr, int indirectionIndex) {
|
||||
predicate hasIRRepresentationOfIndirectInstruction(
|
||||
Instruction instr, int indirectionIndex, Instruction instrRepr, int indirectionIndexRepr
|
||||
) {
|
||||
indirectionIndex = [1 .. countIndirectionsForCppType(getResultLanguageType(instr))] and
|
||||
exists(Instruction load, Operand address |
|
||||
address.getDef() = instr and
|
||||
isDereference(load, address) and
|
||||
isUseImpl(address, _, indirectionIndex - 1) and
|
||||
result = load
|
||||
isDereference(load, address, false) and
|
||||
instrRepr = load and
|
||||
indirectionIndexRepr = indirectionIndex - 1
|
||||
)
|
||||
}
|
||||
|
||||
@@ -823,7 +839,7 @@ private module Cached {
|
||||
or
|
||||
exists(int ind0 |
|
||||
exists(Operand address |
|
||||
isDereference(operand.getDef(), address) and
|
||||
isDereference(operand.getDef(), address, _) and
|
||||
isUseImpl(address, base, ind0)
|
||||
)
|
||||
or
|
||||
@@ -893,7 +909,7 @@ private module Cached {
|
||||
)
|
||||
or
|
||||
exists(Operand address, boolean certain0 |
|
||||
isDereference(operand.getDef(), address) and
|
||||
isDereference(operand.getDef(), address, _) and
|
||||
isDefImpl(address, base, ind - 1, certain0)
|
||||
|
|
||||
if isCertainAddress(operand) then certain = certain0 else certain = false
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Provides C++-specific definitions for use in the taint tracking library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.TaintTracking
|
||||
private import DataFlowImplSpecific
|
||||
|
||||
module CppTaintTracking implements InputSig<CppDataFlow> {
|
||||
import TaintTrackingUtil
|
||||
}
|
||||
@@ -57,7 +57,7 @@ private predicate operandToInstructionTaintStep(Operand opFrom, Instruction inst
|
||||
)
|
||||
or
|
||||
// Taint flow from an address to its dereference.
|
||||
Ssa::isDereference(instrTo, opFrom)
|
||||
Ssa::isDereference(instrTo, opFrom, _)
|
||||
or
|
||||
// Unary instructions tend to preserve enough information in practice that we
|
||||
// want taint to flow through.
|
||||
@@ -112,7 +112,7 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
* of `c` at sinks and inputs to additional taint steps.
|
||||
*/
|
||||
bindingset[node]
|
||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { none() }
|
||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() }
|
||||
|
||||
/**
|
||||
* Holds if `node` should be a sanitizer in all global taint flow configurations
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/**
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) taint-tracking analyses.
|
||||
*/
|
||||
|
||||
import TaintTrackingParameter::Public
|
||||
private import TaintTrackingParameter::Private
|
||||
|
||||
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
|
||||
DataFlowInternal::FullStateConfigSig
|
||||
{
|
||||
import Config
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
Config::isBarrier(node) or defaultTaintSanitizer(node)
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
Config::isAdditionalFlowStep(node1, node2) or
|
||||
defaultAdditionalTaintStep(node1, node2)
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
|
||||
Config::allowImplicitRead(node, c)
|
||||
or
|
||||
(
|
||||
Config::isSink(node) or
|
||||
Config::isSink(node, _) or
|
||||
Config::isAdditionalFlowStep(node, _) or
|
||||
Config::isAdditionalFlowStep(node, _, _, _)
|
||||
) and
|
||||
defaultImplicitTaintRead(node, c)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a global taint tracking computation.
|
||||
*/
|
||||
module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
|
||||
private module Config0 implements DataFlowInternal::FullStateConfigSig {
|
||||
import DataFlowInternal::DefaultState<Config>
|
||||
import Config
|
||||
}
|
||||
|
||||
private module C implements DataFlowInternal::FullStateConfigSig {
|
||||
import AddTaintDefaults<Config0>
|
||||
}
|
||||
|
||||
import DataFlowInternal::Impl<C>
|
||||
}
|
||||
|
||||
/** DEPRECATED: Use `Global` instead. */
|
||||
deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
|
||||
import Global<Config>
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a global taint tracking computation using flow state.
|
||||
*/
|
||||
module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
|
||||
private module Config0 implements DataFlowInternal::FullStateConfigSig {
|
||||
import Config
|
||||
}
|
||||
|
||||
private module C implements DataFlowInternal::FullStateConfigSig {
|
||||
import AddTaintDefaults<Config0>
|
||||
}
|
||||
|
||||
import DataFlowInternal::Impl<C>
|
||||
}
|
||||
|
||||
/** DEPRECATED: Use `GlobalWithState` instead. */
|
||||
deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
|
||||
import GlobalWithState<Config>
|
||||
}
|
||||
@@ -55,6 +55,7 @@ private newtype TOpcode =
|
||||
TVariableAddress() or
|
||||
TFieldAddress() or
|
||||
TFunctionAddress() or
|
||||
TVirtualDeleteFunctionAddress() or
|
||||
TElementsAddress() or
|
||||
TConstant() or
|
||||
TStringConstant() or
|
||||
@@ -887,6 +888,15 @@ module Opcode {
|
||||
final override string toString() { result = "FunctionAddress" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `VirtualDeleteFunctionAddress`.
|
||||
*
|
||||
* See the `VirtualDeleteFunctionAddressInstruction` documentation for more details.
|
||||
*/
|
||||
class VirtualDeleteFunctionAddress extends Opcode, TVirtualDeleteFunctionAddress {
|
||||
final override string toString() { result = "VirtualDeleteFunctionAddress" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `ConstantInstruction`.
|
||||
*
|
||||
|
||||
@@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction {
|
||||
FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the address of a "virtual" delete function.
|
||||
*
|
||||
* This function, which does not actually exist in the source code, is used to
|
||||
* delete objects of a class with a virtual destructor. In that case the deacllocation
|
||||
* function is selected at runtime based on the dynamic type of the object. So this
|
||||
* function dynamically dispatches to the correct deallocation function.
|
||||
* It also should pass in the required extra arguments to the deallocation function
|
||||
* which may differ dynamically depending on the type of the object.
|
||||
*/
|
||||
class VirtualDeleteFunctionAddressInstruction extends Instruction {
|
||||
VirtualDeleteFunctionAddressInstruction() {
|
||||
this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that initializes a parameter of the enclosing function with the value of the
|
||||
* corresponding argument passed by the caller.
|
||||
|
||||
@@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction {
|
||||
FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the address of a "virtual" delete function.
|
||||
*
|
||||
* This function, which does not actually exist in the source code, is used to
|
||||
* delete objects of a class with a virtual destructor. In that case the deacllocation
|
||||
* function is selected at runtime based on the dynamic type of the object. So this
|
||||
* function dynamically dispatches to the correct deallocation function.
|
||||
* It also should pass in the required extra arguments to the deallocation function
|
||||
* which may differ dynamically depending on the type of the object.
|
||||
*/
|
||||
class VirtualDeleteFunctionAddressInstruction extends Instruction {
|
||||
VirtualDeleteFunctionAddressInstruction() {
|
||||
this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that initializes a parameter of the enclosing function with the value of the
|
||||
* corresponding argument passed by the caller.
|
||||
|
||||
@@ -120,9 +120,9 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Call` or `NewOrNewArrayExpr`.
|
||||
* A `Call` or `NewOrNewArrayExpr` or `DeleteOrDeleteArrayExpr`.
|
||||
*
|
||||
* Both kinds of expression invoke a function as part of their evaluation. This class provides a
|
||||
* All kinds of expression invoke a function as part of their evaluation. This class provides a
|
||||
* way to treat both kinds of function similarly, and to get the invoked `Function`.
|
||||
*/
|
||||
class CallOrAllocationExpr extends Expr {
|
||||
@@ -130,6 +130,8 @@ class CallOrAllocationExpr extends Expr {
|
||||
this instanceof Call
|
||||
or
|
||||
this instanceof NewOrNewArrayExpr
|
||||
or
|
||||
this instanceof DeleteOrDeleteArrayExpr
|
||||
}
|
||||
|
||||
/** Gets the `Function` invoked by this expression, if known. */
|
||||
@@ -137,6 +139,8 @@ class CallOrAllocationExpr extends Expr {
|
||||
result = this.(Call).getTarget()
|
||||
or
|
||||
result = this.(NewOrNewArrayExpr).getAllocator()
|
||||
or
|
||||
result = this.(DeleteOrDeleteArrayExpr).getDeallocator()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -350,6 +350,9 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi
|
||||
or
|
||||
expr instanceof NewOrNewArrayExpr and
|
||||
result = getTranslatedAllocatorCall(expr).getInstruction(CallTag())
|
||||
or
|
||||
expr instanceof DeleteOrDeleteArrayExpr and
|
||||
result = getTranslatedDeleteOrDeleteArray(expr).getInstruction(CallTag())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,17 +77,17 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
newExpr.getInitializer().getFullyConverted() = expr
|
||||
)
|
||||
or
|
||||
exists(DeleteOrDeleteArrayExpr deleteExpr |
|
||||
// Ignore the deallocator call, because we always synthesize it.
|
||||
deleteExpr.getDeallocatorCall() = expr
|
||||
)
|
||||
or
|
||||
// Do not translate input/output variables in GNU asm statements
|
||||
// getRealParent(expr) instanceof AsmStmt
|
||||
// or
|
||||
ignoreExprAndDescendants(getRealParent(expr)) // recursive case
|
||||
or
|
||||
// We do not yet translate destructors properly, so for now we ignore any
|
||||
// custom deallocator call, if present.
|
||||
exists(DeleteExpr deleteExpr | deleteExpr.getAllocatorCall() = expr)
|
||||
or
|
||||
exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getAllocatorCall() = expr)
|
||||
or
|
||||
// va_start doesn't evaluate its argument, so we don't need to translate it.
|
||||
exists(BuiltInVarArgsStart vaStartExpr |
|
||||
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
|
||||
)
|
||||
@@ -104,6 +104,12 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
newExpr.getAllocatorCall() = expr
|
||||
)
|
||||
or
|
||||
exists(DeleteOrDeleteArrayExpr deleteExpr |
|
||||
// Ignore the destructor call as we don't model it yet. Don't ignore
|
||||
// its arguments, though, as they are the arguments to the deallocator.
|
||||
deleteExpr.getDestructorCall() = expr
|
||||
)
|
||||
or
|
||||
// The extractor deliberately emits an `ErrorExpr` as the first argument to
|
||||
// the allocator call, if any, of a `NewOrNewArrayExpr`. That `ErrorExpr`
|
||||
// should not be translated.
|
||||
@@ -111,13 +117,6 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
or
|
||||
not translateFunction(getEnclosingFunction(expr)) and
|
||||
not Raw::varHasIRFunc(getEnclosingVariable(expr))
|
||||
or
|
||||
// We do not yet translate destructors properly, so for now we ignore the
|
||||
// destructor call. We do, however, translate the expression being
|
||||
// destructed, and that expression can be a child of the destructor call.
|
||||
exists(DeleteExpr deleteExpr | deleteExpr.getDestructorCall() = expr)
|
||||
or
|
||||
exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getDestructorCall() = expr)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -416,7 +415,9 @@ predicate hasTranslatedLoad(Expr expr) {
|
||||
not ignoreExpr(expr) and
|
||||
not isNativeCondition(expr) and
|
||||
not isFlexibleCondition(expr) and
|
||||
not ignoreLoad(expr)
|
||||
not ignoreLoad(expr) and
|
||||
// don't insert a load since we'll just substitute the constant value.
|
||||
not isIRConstant(expr)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2017,6 +2017,66 @@ TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) {
|
||||
result.getAst() = newExpr
|
||||
}
|
||||
|
||||
/**
|
||||
* The IR translation of a `delete` or `delete[]`
|
||||
* expression.
|
||||
*/
|
||||
class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, TranslatedCall {
|
||||
override DeleteOrDeleteArrayExpr expr;
|
||||
|
||||
final override Instruction getFirstCallTargetInstruction() {
|
||||
result = this.getInstruction(CallTargetTag())
|
||||
}
|
||||
|
||||
final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
TranslatedCall.super.hasInstruction(opcode, tag, resultType)
|
||||
or
|
||||
tag = CallTargetTag() and
|
||||
resultType = getFunctionGLValueType() and
|
||||
if exists(expr.getDeallocator())
|
||||
then opcode instanceof Opcode::FunctionAddress
|
||||
else opcode instanceof Opcode::VirtualDeleteFunctionAddress
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedCall.super.getInstructionSuccessor(tag, kind)
|
||||
or
|
||||
tag = CallTargetTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getFirstArgumentOrCallInstruction()
|
||||
}
|
||||
|
||||
override Function getInstructionFunction(InstructionTag tag) {
|
||||
tag = CallTargetTag() and result = expr.getDeallocator()
|
||||
}
|
||||
|
||||
final override Type getCallResultType() { result = expr.getType() }
|
||||
|
||||
final override TranslatedExpr getQualifier() { none() }
|
||||
|
||||
final override predicate hasArguments() {
|
||||
// All deallocator calls have at least one argument.
|
||||
any()
|
||||
}
|
||||
|
||||
final override int getNumberOfArguments() {
|
||||
// We ignore the other arguments for now as we would have to synthesize them.
|
||||
result = 1
|
||||
}
|
||||
|
||||
final override TranslatedExpr getArgument(int index) {
|
||||
// The only argument we define is the pointer to be deallocated.
|
||||
index = 0 and
|
||||
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||
}
|
||||
}
|
||||
|
||||
TranslatedDeleteOrDeleteArrayExpr getTranslatedDeleteOrDeleteArray(DeleteOrDeleteArrayExpr newExpr) {
|
||||
result.getAst() = newExpr
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class implemented by any `TranslatedElement` that has a child
|
||||
* expression that is a call to a constructor or destructor, in order to
|
||||
@@ -2954,78 +3014,6 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A placeholder for the translation of a `delete[]` expression.
|
||||
*
|
||||
* Proper translation is not yet implemented, but this stub implementation
|
||||
* ensures that code following a `delete[]` is not unreachable.
|
||||
*/
|
||||
class TranslatedDeleteArrayExprPlaceHolder extends TranslatedSingleInstructionExpr {
|
||||
override DeleteArrayExpr expr;
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getOperand().getFirstInstruction()
|
||||
}
|
||||
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Opcode getOpcode() { result instanceof Opcode::NoOp }
|
||||
|
||||
private TranslatedExpr getOperand() {
|
||||
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A placeholder for the translation of a `delete` expression.
|
||||
*
|
||||
* Proper translation is not yet implemented, but this stub implementation
|
||||
* ensures that code following a `delete` is not unreachable.
|
||||
*/
|
||||
class TranslatedDeleteExprPlaceHolder extends TranslatedSingleInstructionExpr {
|
||||
override DeleteExpr expr;
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getOperand().getFirstInstruction()
|
||||
}
|
||||
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Opcode getOpcode() { result instanceof Opcode::NoOp }
|
||||
|
||||
private TranslatedExpr getOperand() {
|
||||
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The IR translation of a `ConditionDeclExpr`, which represents the value of the declared variable
|
||||
* after conversion to `bool` in code such as:
|
||||
|
||||
@@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction {
|
||||
FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the address of a "virtual" delete function.
|
||||
*
|
||||
* This function, which does not actually exist in the source code, is used to
|
||||
* delete objects of a class with a virtual destructor. In that case the deacllocation
|
||||
* function is selected at runtime based on the dynamic type of the object. So this
|
||||
* function dynamically dispatches to the correct deallocation function.
|
||||
* It also should pass in the required extra arguments to the deallocation function
|
||||
* which may differ dynamically depending on the type of the object.
|
||||
*/
|
||||
class VirtualDeleteFunctionAddressInstruction extends Instruction {
|
||||
VirtualDeleteFunctionAddressInstruction() {
|
||||
this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that initializes a parameter of the enclosing function with the value of the
|
||||
* corresponding argument passed by the caller.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* This file contains the range-analysis specific parts of the `cpp/invalid-pointer-deref` query
|
||||
* that is used by both `AllocationToInvalidPointer.qll` and `InvalidPointerToDereference.qll`.
|
||||
* This file contains the range-analysis specific parts of the `cpp/invalid-pointer-deref`
|
||||
* and `cpp/overrun-write` query.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
@@ -39,6 +39,7 @@ predicate semImplies_v2(SemGuard g1, boolean b1, SemGuard g2, boolean b2) {
|
||||
* Holds if `guard` directly controls the position `controlled` with the
|
||||
* value `testIsTrue`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate semGuardDirectlyControlsSsaRead(
|
||||
SemGuard guard, SemSsaReadPosition controlled, boolean testIsTrue
|
||||
) {
|
||||
|
||||
@@ -17,19 +17,27 @@ private import RangeUtils
|
||||
private import RangeAnalysisStage
|
||||
|
||||
module ModulusAnalysis<DeltaSig D, BoundSig<D> Bounds, UtilSig<D> U> {
|
||||
/**
|
||||
* Holds if `e + delta` equals `v` at `pos`.
|
||||
*/
|
||||
private predicate valueFlowStepSsa(SemSsaVariable v, SemSsaReadPosition pos, SemExpr e, int delta) {
|
||||
U::semSsaUpdateStep(v, e, D::fromInt(delta)) and pos.hasReadOfVar(v)
|
||||
or
|
||||
pragma[nomagic]
|
||||
private predicate valueFlowStepSsaEqFlowCond(
|
||||
SemSsaReadPosition pos, SemSsaVariable v, SemExpr e, int delta
|
||||
) {
|
||||
exists(SemGuard guard, boolean testIsTrue |
|
||||
pos.hasReadOfVar(v) and
|
||||
guard = U::semEqFlowCond(v, e, D::fromInt(delta), true, testIsTrue) and
|
||||
semGuardDirectlyControlsSsaRead(guard, pos, testIsTrue)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e + delta` equals `v` at `pos`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate valueFlowStepSsa(SemSsaVariable v, SemSsaReadPosition pos, SemExpr e, int delta) {
|
||||
U::semSsaUpdateStep(v, e, D::fromInt(delta)) and pos.hasReadOfVar(v)
|
||||
or
|
||||
pos.hasReadOfVar(v) and
|
||||
valueFlowStepSsaEqFlowCond(pos, v, e, delta)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `add` is the addition of `larg` and `rarg`, neither of which are
|
||||
* `ConstantIntegerExpr`s.
|
||||
|
||||
@@ -660,7 +660,7 @@ module RangeStage<
|
||||
* - `upper = false` : `v >= b + delta`
|
||||
*/
|
||||
private predicate boundedSsa(
|
||||
SemSsaVariable v, SemSsaReadPosition pos, SemBound b, D::Delta delta, boolean upper,
|
||||
SemSsaVariable v, SemBound b, D::Delta delta, SemSsaReadPosition pos, boolean upper,
|
||||
boolean fromBackEdge, D::Delta origdelta, SemReason reason
|
||||
) {
|
||||
exists(SemExpr mid, D::Delta d1, D::Delta d2, SemReason r1, SemReason r2 |
|
||||
@@ -673,10 +673,13 @@ module RangeStage<
|
||||
)
|
||||
or
|
||||
exists(D::Delta d, SemReason r1, SemReason r2 |
|
||||
boundedSsa(v, pos, b, d, upper, fromBackEdge, origdelta, r2) or
|
||||
boundedPhi(v, b, d, upper, fromBackEdge, origdelta, r2)
|
||||
boundedSsa(pragma[only_bind_into](v), pragma[only_bind_into](b), pragma[only_bind_into](d),
|
||||
pragma[only_bind_into](pos), upper, fromBackEdge, origdelta, r2)
|
||||
or
|
||||
boundedPhi(pragma[only_bind_into](v), pragma[only_bind_into](b), pragma[only_bind_into](d),
|
||||
upper, fromBackEdge, origdelta, r2)
|
||||
|
|
||||
unequalIntegralSsa(v, pos, b, d, r1) and
|
||||
unequalIntegralSsa(v, b, d, pos, r1) and
|
||||
(
|
||||
upper = true and delta = D::fromFloat(D::toFloat(d) - 1)
|
||||
or
|
||||
@@ -694,7 +697,7 @@ module RangeStage<
|
||||
* Holds if `v != b + delta` at `pos` and `v` is of integral type.
|
||||
*/
|
||||
private predicate unequalIntegralSsa(
|
||||
SemSsaVariable v, SemSsaReadPosition pos, SemBound b, D::Delta delta, SemReason reason
|
||||
SemSsaVariable v, SemBound b, D::Delta delta, SemSsaReadPosition pos, SemReason reason
|
||||
) {
|
||||
exists(SemExpr e, D::Delta d1, D::Delta d2 |
|
||||
unequalFlowStepIntegralSsa(v, pos, e, d1, reason) and
|
||||
@@ -746,7 +749,7 @@ module RangeStage<
|
||||
) {
|
||||
edge.phiInput(phi, inp) and
|
||||
exists(D::Delta d, boolean fromBackEdge0 |
|
||||
boundedSsa(inp, edge, b, d, upper, fromBackEdge0, origdelta, reason)
|
||||
boundedSsa(inp, b, d, edge, upper, fromBackEdge0, origdelta, reason)
|
||||
or
|
||||
boundedPhi(inp, b, d, upper, fromBackEdge0, origdelta, reason)
|
||||
or
|
||||
@@ -1022,7 +1025,7 @@ module RangeStage<
|
||||
reason = TSemNoReason()
|
||||
or
|
||||
exists(SemSsaVariable v, SemSsaReadPositionBlock bb |
|
||||
boundedSsa(v, bb, b, delta, upper, fromBackEdge, origdelta, reason) and
|
||||
boundedSsa(v, b, delta, bb, upper, fromBackEdge, origdelta, reason) and
|
||||
e = v.getAUse() and
|
||||
bb.getBlock() = e.getBasicBlock()
|
||||
)
|
||||
|
||||
@@ -49,6 +49,7 @@ module RangeUtil<Range::DeltaSig D, Range::LangSig<D> Lang> implements Range::Ut
|
||||
* - `isEq = true` : `v == e + delta`
|
||||
* - `isEq = false` : `v != e + delta`
|
||||
*/
|
||||
pragma[nomagic]
|
||||
SemGuard semEqFlowCond(
|
||||
SemSsaVariable v, SemExpr e, D::Delta delta, boolean isEq, boolean testIsTrue
|
||||
) {
|
||||
|
||||
@@ -53,7 +53,7 @@ private class ArgvSource extends LocalFlowSource {
|
||||
exists(Function main, Parameter argv |
|
||||
main.hasGlobalName("main") and
|
||||
main.getParameter(1) = argv and
|
||||
this.asParameter(_) = argv
|
||||
this.asParameter(2) = argv
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ private import semmle.code.cpp.ir.dataflow.internal.ProductFlow
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import codeql.util.Unit
|
||||
private import RangeAnalysisUtil
|
||||
private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
|
||||
private VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
|
||||
|
||||
@@ -77,6 +77,15 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual dispatch branching limit when calculating field flow while searching
|
||||
* for flow from an allocation to the construction of an out-of-bounds pointer.
|
||||
*
|
||||
* This can be overridden to a smaller value to improve performance (a
|
||||
* value of 0 disables field flow), or a larger value to get more results.
|
||||
*/
|
||||
int allocationToInvalidPointerFieldFlowBranchLimit() { result = 0 }
|
||||
|
||||
/**
|
||||
* A module that encapsulates a barrier guard to remove false positives from flow like:
|
||||
* ```cpp
|
||||
@@ -101,9 +110,12 @@ private module SizeBarrier {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
// The sources is the same as in the sources for the second
|
||||
// projection in the `AllocToInvalidPointerConfig` module.
|
||||
hasSize(_, source, _)
|
||||
hasSize(_, source, _) and
|
||||
InterestingPointerAddInstruction::isInterestingSize(source)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`.
|
||||
*/
|
||||
@@ -201,6 +213,8 @@ private module InterestingPointerAddInstruction {
|
||||
hasSize(source.asConvertedExpr(), _, _)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink.asInstruction() = any(PointerAddInstruction pai).getLeft()
|
||||
}
|
||||
@@ -220,6 +234,19 @@ private module InterestingPointerAddInstruction {
|
||||
flowTo(n)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` is a size of an allocation whose result flows to the left operand
|
||||
* of a pointer-arithmetic instruction.
|
||||
*
|
||||
* This predicate is used to reduce the set of tuples in `SizeBarrierConfig::isSource`.
|
||||
*/
|
||||
predicate isInterestingSize(DataFlow::Node n) {
|
||||
exists(DataFlow::Node alloc |
|
||||
hasSize(alloc.asConvertedExpr(), n, _) and
|
||||
flow(alloc, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,6 +271,10 @@ private module Config implements ProductFlow::StateConfigSig {
|
||||
hasSize(allocSource.asConvertedExpr(), sizeSource, sizeAddend)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit1() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
|
||||
|
||||
int fieldFlowBranchLimit2() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
|
||||
|
||||
predicate isSinkPair(
|
||||
DataFlow::Node allocSink, FlowState1 unit, DataFlow::Node sizeSink, FlowState2 sizeAddend
|
||||
) {
|
||||
|
||||
@@ -81,7 +81,17 @@ private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import AllocationToInvalidPointer as AllocToInvalidPointer
|
||||
private import RangeAnalysisUtil
|
||||
private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
|
||||
/**
|
||||
* Gets the virtual dispatch branching limit when calculating field flow while
|
||||
* searching for flow from an out-of-bounds pointer to a dereference of the
|
||||
* pointer.
|
||||
*
|
||||
* This can be overridden to a smaller value to improve performance (a
|
||||
* value of 0 disables field flow), or a larger value to get more results.
|
||||
*/
|
||||
int invalidPointerToDereferenceFieldFlowBranchLimit() { result = 0 }
|
||||
|
||||
private module InvalidPointerToDerefBarrier {
|
||||
private module BarrierConfig implements DataFlow::ConfigSig {
|
||||
@@ -101,6 +111,8 @@ private module InvalidPointerToDerefBarrier {
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
||||
|
||||
int fieldFlowBranchLimit() { result = invalidPointerToDereferenceFieldFlowBranchLimit() }
|
||||
}
|
||||
|
||||
private module BarrierFlow = DataFlow::Global<BarrierConfig>;
|
||||
@@ -178,6 +190,8 @@ private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
|
||||
// Note that this is the only place where the `FlowState` is used in this configuration.
|
||||
node = InvalidPointerToDerefBarrier::getABarrierNode(pai)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = invalidPointerToDereferenceFieldFlowBranchLimit() }
|
||||
}
|
||||
|
||||
private import DataFlow::GlobalWithState<InvalidPointerToDerefConfig>
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
## 0.7.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.7.4
|
||||
|
||||
### New Queries
|
||||
|
||||
* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Comparison where assignment was intended" query (`cpp/compare-where-assign-meant`) no longer reports comparisons that appear in macro expansions.
|
||||
* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result.
|
||||
* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results.
|
||||
|
||||
## 0.7.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -105,8 +105,6 @@ predicate isNonConst(DataFlow::Node node, boolean isIndirect) {
|
||||
or
|
||||
e instanceof NewArrayExpr
|
||||
or
|
||||
e instanceof AssignExpr
|
||||
or
|
||||
exists(Variable v | v = e.(VariableAccess).getTarget() |
|
||||
v.getType().(ArrayType).getBaseType() instanceof CharType and
|
||||
exists(AssignExpr ae |
|
||||
|
||||
@@ -16,6 +16,7 @@ import cpp
|
||||
from ExprInVoidContext op
|
||||
where
|
||||
not op.isUnevaluated() and
|
||||
not inMacroExpansion(op) and
|
||||
(
|
||||
op instanceof EQExpr
|
||||
or
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.security.FunctionWithWrappers
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import SqlTainted::PathGraph
|
||||
|
||||
class SqlLikeFunction extends FunctionWithWrappers {
|
||||
SqlLikeFunction() { sqlArgument(this.getName(), _) }
|
||||
@@ -24,31 +26,43 @@ class SqlLikeFunction extends FunctionWithWrappers {
|
||||
override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) }
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element tainted) {
|
||||
exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _))
|
||||
Expr asSinkExpr(DataFlow::Node node) {
|
||||
result = node.asIndirectArgument()
|
||||
or
|
||||
// We want the conversion so we only get one node for the expression
|
||||
result = node.asConvertedExpr()
|
||||
}
|
||||
|
||||
module SqlTaintedConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node node) {
|
||||
exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(asSinkExpr(node), _))
|
||||
}
|
||||
|
||||
override predicate isBarrier(Expr e) {
|
||||
super.isBarrier(e)
|
||||
or
|
||||
e.getUnspecifiedType() instanceof IntegralType
|
||||
or
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) {
|
||||
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
|
||||
e = sql.getACallToThisFunction().getArgument(arg) and
|
||||
node.asIndirectArgument() = sql.getACallToThisFunction().getArgument(arg) and
|
||||
input.isParameterDeref(arg) and
|
||||
sql.barrierSqlArgument(input, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module SqlTainted = TaintTracking::Global<SqlTaintedConfig>;
|
||||
|
||||
from
|
||||
SqlLikeFunction runSql, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode,
|
||||
string taintCause, string callChain
|
||||
SqlLikeFunction runSql, Expr taintedArg, FlowSource taintSource, SqlTainted::PathNode sourceNode,
|
||||
SqlTainted::PathNode sinkNode, string callChain
|
||||
where
|
||||
runSql.outermostWrapperFunctionCall(taintedArg, callChain) and
|
||||
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
|
||||
isUserInput(taintSource, taintCause)
|
||||
SqlTainted::flowPath(sourceNode, sinkNode) and
|
||||
taintedArg = asSinkExpr(sinkNode.getNode()) and
|
||||
taintSource = sourceNode.getNode()
|
||||
select taintedArg, sourceNode, sinkNode,
|
||||
"This argument to a SQL query function is derived from $@ and then passed to " + callChain + ".",
|
||||
taintSource, "user input (" + taintCause + ")"
|
||||
taintSource, "user input (" + taintSource.getSourceType() + ")"
|
||||
|
||||
@@ -20,28 +20,10 @@ import semmle.code.cpp.models.interfaces.Allocation
|
||||
import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
|
||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
|
||||
import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
import StringSizeFlow::PathGraph1
|
||||
import codeql.util.Unit
|
||||
|
||||
pragma[nomagic]
|
||||
Instruction getABoundIn(SemBound b, IRFunction func) {
|
||||
getSemanticExpr(result) = b.getExpr(0) and
|
||||
result.getEnclosingIRFunction() = func
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `i <= b + delta`.
|
||||
*/
|
||||
bindingset[i]
|
||||
pragma[inline_late]
|
||||
predicate bounded(Instruction i, Instruction b, int delta) {
|
||||
exists(SemBound bound, IRFunction func |
|
||||
semBounded(getSemanticExpr(i), bound, delta, true, _) and
|
||||
b = getABoundIn(bound, func) and
|
||||
i.getEnclosingIRFunction() = func
|
||||
)
|
||||
}
|
||||
|
||||
VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>The program performs an out-of-bounds read or write operation. In addition to causing program instability, techniques exist which may allow an attacker to use this vulnerability to execute arbitrary code.</p>
|
||||
<p>The program performs an out-of-bounds read or write operation, which can cause program instability. In addition, attackers may take advantage of the situation, and implement techniques to use this vulnerability to execute arbitrary code.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
@@ -13,7 +13,7 @@
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The first example allocates a buffer of size <code>size</code> and creates a local variable that stores the location that is one byte past the end of the allocation.
|
||||
This local variable is then dereferenced which results in an out-of-bounds write.
|
||||
This local variable is then dereferenced, which results in an out-of-bounds write.
|
||||
The second example subtracts one from the <code>end</code> variable before dereferencing it. This subtraction ensures that the write correctly updates the final byte of the allocation.</p>
|
||||
<sample src="InvalidPointerDeref.cpp" />
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* @name Invalid pointer dereference
|
||||
* @description Dereferencing a pointer that points past it allocation is undefined behavior
|
||||
* and may lead to security vulnerabilities.
|
||||
* @description Dereferencing an out-of-bounds pointer is undefined behavior and may lead to security vulnerabilities.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @security-severity 9.3
|
||||
* @precision medium
|
||||
* @id cpp/invalid-pointer-deref
|
||||
* @tags reliability
|
||||
* security
|
||||
@@ -94,6 +94,12 @@ module FinalConfig implements DataFlow::StateConfigSig {
|
||||
)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() {
|
||||
result =
|
||||
allocationToInvalidPointerFieldFlowBranchLimit()
|
||||
.maximum(invalidPointerToDereferenceFieldFlowBranchLimit())
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
|
||||
) {
|
||||
@@ -17,21 +17,6 @@ import cpp
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
|
||||
/**
|
||||
* A C++ `delete` or `delete[]` expression.
|
||||
*/
|
||||
class DeleteOrDeleteArrayExpr extends Expr {
|
||||
DeleteOrDeleteArrayExpr() { this instanceof DeleteExpr or this instanceof DeleteArrayExpr }
|
||||
|
||||
DeallocationFunction getDeallocator() {
|
||||
result = [this.(DeleteExpr).getDeallocator(), this.(DeleteArrayExpr).getDeallocator()]
|
||||
}
|
||||
|
||||
Destructor getDestructor() {
|
||||
result = [this.(DeleteExpr).getDestructor(), this.(DeleteArrayExpr).getDestructor()]
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the `Constructor` invoked when `newExpr` allocates memory. */
|
||||
Constructor getConstructorForAllocation(NewOrNewArrayExpr newExpr) {
|
||||
result.getACallToThisFunction() = newExpr.getInitializer()
|
||||
|
||||
11
cpp/ql/src/change-notes/released/0.7.4.md
Normal file
11
cpp/ql/src/change-notes/released/0.7.4.md
Normal file
@@ -0,0 +1,11 @@
|
||||
## 0.7.4
|
||||
|
||||
### New Queries
|
||||
|
||||
* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Comparison where assignment was intended" query (`cpp/compare-where-assign-meant`) no longer reports comparisons that appear in macro expansions.
|
||||
* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result.
|
||||
* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results.
|
||||
3
cpp/ql/src/change-notes/released/0.7.5.md
Normal file
3
cpp/ql/src/change-notes/released/0.7.5.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.7.5
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.7.3
|
||||
lastReleaseVersion: 0.7.5
|
||||
|
||||
@@ -40,7 +40,7 @@ module WordexpTaintConfig implements DataFlow::ConfigSig {
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof WordexpFunction |
|
||||
fc.getArgument(0) = sink.asExpr() and
|
||||
fc.getArgument(0) = sink.asIndirectArgument(1) and
|
||||
not isCommandSubstitutionDisabled(fc)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.7.3
|
||||
version: 0.7.5
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
edges
|
||||
| test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath |
|
||||
| test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath |
|
||||
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath |
|
||||
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath |
|
||||
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath indirection |
|
||||
nodes
|
||||
| test.cpp:22:27:22:30 | argv | semmle.label | argv |
|
||||
| test.cpp:22:27:22:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
|
||||
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
|
||||
| test.cpp:29:13:29:20 | filePath indirection | semmle.label | filePath indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath indirection | test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath indirection | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
|
||||
@@ -9,44 +9,35 @@ edges
|
||||
| test.cpp:22:5:22:7 | arr indirection [p] | test.cpp:19:9:19:16 | mk_array indirection [p] |
|
||||
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | arr indirection [p] |
|
||||
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | arr indirection [p] |
|
||||
| test.cpp:31:9:31:11 | arr indirection [p] | test.cpp:31:13:31:13 | p indirection |
|
||||
| test.cpp:31:13:31:13 | p indirection | test.cpp:31:13:31:13 | p |
|
||||
| test.cpp:35:9:35:11 | arr indirection [p] | test.cpp:35:13:35:13 | p indirection |
|
||||
| test.cpp:35:13:35:13 | p indirection | test.cpp:35:13:35:13 | p |
|
||||
| test.cpp:31:9:31:11 | arr indirection [p] | test.cpp:31:13:31:13 | p |
|
||||
| test.cpp:35:9:35:11 | arr indirection [p] | test.cpp:35:13:35:13 | p |
|
||||
| test.cpp:39:27:39:29 | arr [p] | test.cpp:41:9:41:11 | arr indirection [p] |
|
||||
| test.cpp:39:27:39:29 | arr [p] | test.cpp:45:9:45:11 | arr indirection [p] |
|
||||
| test.cpp:41:9:41:11 | arr indirection [p] | test.cpp:41:13:41:13 | p indirection |
|
||||
| test.cpp:41:13:41:13 | p indirection | test.cpp:41:13:41:13 | p |
|
||||
| test.cpp:45:9:45:11 | arr indirection [p] | test.cpp:45:13:45:13 | p indirection |
|
||||
| test.cpp:45:13:45:13 | p indirection | test.cpp:45:13:45:13 | p |
|
||||
| test.cpp:41:9:41:11 | arr indirection [p] | test.cpp:41:13:41:13 | p |
|
||||
| test.cpp:45:9:45:11 | arr indirection [p] | test.cpp:45:13:45:13 | p |
|
||||
| test.cpp:50:18:50:25 | call to mk_array [p] | test.cpp:39:27:39:29 | arr [p] |
|
||||
| test.cpp:55:5:55:24 | ... = ... | test.cpp:55:9:55:9 | arr indirection [post update] [p] |
|
||||
| test.cpp:55:9:55:9 | arr indirection [post update] [p] | test.cpp:56:5:56:7 | arr indirection [p] |
|
||||
| test.cpp:55:13:55:18 | call to malloc | test.cpp:55:5:55:24 | ... = ... |
|
||||
| test.cpp:56:5:56:7 | arr indirection [p] | test.cpp:59:9:59:11 | arr indirection [p] |
|
||||
| test.cpp:56:5:56:7 | arr indirection [p] | test.cpp:63:9:63:11 | arr indirection [p] |
|
||||
| test.cpp:59:9:59:11 | arr indirection [p] | test.cpp:59:13:59:13 | p indirection |
|
||||
| test.cpp:59:13:59:13 | p indirection | test.cpp:59:13:59:13 | p |
|
||||
| test.cpp:63:9:63:11 | arr indirection [p] | test.cpp:63:13:63:13 | p indirection |
|
||||
| test.cpp:63:13:63:13 | p indirection | test.cpp:63:13:63:13 | p |
|
||||
| test.cpp:59:9:59:11 | arr indirection [p] | test.cpp:59:13:59:13 | p |
|
||||
| test.cpp:63:9:63:11 | arr indirection [p] | test.cpp:63:13:63:13 | p |
|
||||
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | test.cpp:76:20:76:29 | call to mk_array_p indirection [p] |
|
||||
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | test.cpp:98:18:98:27 | call to mk_array_p indirection [p] |
|
||||
| test.cpp:69:5:69:25 | ... = ... | test.cpp:69:10:69:10 | arr indirection [post update] [p] |
|
||||
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | test.cpp:70:5:70:7 | arr indirection [p] |
|
||||
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... |
|
||||
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:67:10:67:19 | mk_array_p indirection [p] |
|
||||
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:70:5:70:7 | arr indirection [p] |
|
||||
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:79:9:79:11 | arr indirection [p] |
|
||||
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:83:9:83:11 | arr indirection [p] |
|
||||
| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p indirection |
|
||||
| test.cpp:79:14:79:14 | p indirection | test.cpp:79:14:79:14 | p |
|
||||
| test.cpp:83:9:83:11 | arr indirection [p] | test.cpp:83:14:83:14 | p indirection |
|
||||
| test.cpp:83:14:83:14 | p indirection | test.cpp:83:14:83:14 | p |
|
||||
| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p |
|
||||
| test.cpp:83:9:83:11 | arr indirection [p] | test.cpp:83:14:83:14 | p |
|
||||
| test.cpp:87:28:87:30 | arr indirection [p] | test.cpp:89:9:89:11 | arr indirection [p] |
|
||||
| test.cpp:87:28:87:30 | arr indirection [p] | test.cpp:93:9:93:11 | arr indirection [p] |
|
||||
| test.cpp:89:9:89:11 | arr indirection [p] | test.cpp:89:14:89:14 | p indirection |
|
||||
| test.cpp:89:14:89:14 | p indirection | test.cpp:89:14:89:14 | p |
|
||||
| test.cpp:93:9:93:11 | arr indirection [p] | test.cpp:93:14:93:14 | p indirection |
|
||||
| test.cpp:93:14:93:14 | p indirection | test.cpp:93:14:93:14 | p |
|
||||
| test.cpp:89:9:89:11 | arr indirection [p] | test.cpp:89:14:89:14 | p |
|
||||
| test.cpp:93:9:93:11 | arr indirection [p] | test.cpp:93:14:93:14 | p |
|
||||
| test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | test.cpp:87:28:87:30 | arr indirection [p] |
|
||||
nodes
|
||||
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
|
||||
@@ -60,17 +51,13 @@ nodes
|
||||
| test.cpp:28:19:28:26 | call to mk_array [p] | semmle.label | call to mk_array [p] |
|
||||
| test.cpp:31:9:31:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:31:13:31:13 | p | semmle.label | p |
|
||||
| test.cpp:31:13:31:13 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:35:9:35:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:35:13:35:13 | p | semmle.label | p |
|
||||
| test.cpp:35:13:35:13 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:39:27:39:29 | arr [p] | semmle.label | arr [p] |
|
||||
| test.cpp:41:9:41:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:41:13:41:13 | p | semmle.label | p |
|
||||
| test.cpp:41:13:41:13 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:45:9:45:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:45:13:45:13 | p | semmle.label | p |
|
||||
| test.cpp:45:13:45:13 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:50:18:50:25 | call to mk_array [p] | semmle.label | call to mk_array [p] |
|
||||
| test.cpp:55:5:55:24 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:55:9:55:9 | arr indirection [post update] [p] | semmle.label | arr indirection [post update] [p] |
|
||||
@@ -78,10 +65,8 @@ nodes
|
||||
| test.cpp:56:5:56:7 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:59:9:59:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:59:13:59:13 | p | semmle.label | p |
|
||||
| test.cpp:59:13:59:13 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:63:9:63:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:63:13:63:13 | p | semmle.label | p |
|
||||
| test.cpp:63:13:63:13 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:67:10:67:19 | mk_array_p indirection [p] | semmle.label | mk_array_p indirection [p] |
|
||||
| test.cpp:69:5:69:25 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | semmle.label | arr indirection [post update] [p] |
|
||||
@@ -90,17 +75,13 @@ nodes
|
||||
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | semmle.label | call to mk_array_p indirection [p] |
|
||||
| test.cpp:79:9:79:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:79:14:79:14 | p | semmle.label | p |
|
||||
| test.cpp:79:14:79:14 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:83:9:83:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:83:14:83:14 | p | semmle.label | p |
|
||||
| test.cpp:83:14:83:14 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:87:28:87:30 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:89:9:89:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:89:14:89:14 | p | semmle.label | p |
|
||||
| test.cpp:89:14:89:14 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:93:9:93:11 | arr indirection [p] | semmle.label | arr indirection [p] |
|
||||
| test.cpp:93:14:93:14 | p | semmle.label | p |
|
||||
| test.cpp:93:14:93:14 | p indirection | semmle.label | p indirection |
|
||||
| test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | semmle.label | call to mk_array_p indirection [p] |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql
|
||||
@@ -34,11 +34,11 @@ newArrayExprDeallocators
|
||||
| allocators.cpp:108:3:108:19 | new[] | FailedInit | void FailedInit::operator delete[](void*, size_t) | 1 | 1 | sized |
|
||||
| allocators.cpp:110:3:110:37 | new[] | FailedInitOveraligned | void FailedInitOveraligned::operator delete[](void*, std::align_val_t, float) | 128 | 128 | aligned |
|
||||
deleteExprs
|
||||
| allocators.cpp:59:3:59:35 | delete | int | void operator delete(void*, unsigned long) | 4 | 4 | sized |
|
||||
| allocators.cpp:60:3:60:38 | delete | String | void operator delete(void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:61:3:61:44 | delete | SizedDealloc | void SizedDealloc::operator delete(void*, size_t) | 32 | 1 | sized |
|
||||
| allocators.cpp:62:3:62:43 | delete | Overaligned | void operator delete(void*, unsigned long, std::align_val_t) | 256 | 128 | sized aligned |
|
||||
| allocators.cpp:64:3:64:44 | delete | const String | void operator delete(void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:59:3:59:35 | delete | int | void operator delete(void*, unsigned long) | 4 | 4 | sized | false |
|
||||
| allocators.cpp:60:3:60:38 | delete | String | void operator delete(void*, unsigned long) | 8 | 8 | sized | false |
|
||||
| allocators.cpp:61:3:61:44 | delete | SizedDealloc | void SizedDealloc::operator delete(void*, size_t) | 32 | 1 | sized | true |
|
||||
| allocators.cpp:62:3:62:43 | delete | Overaligned | void operator delete(void*, unsigned long, std::align_val_t) | 256 | 128 | sized aligned | false |
|
||||
| allocators.cpp:64:3:64:44 | delete | const String | void operator delete(void*, unsigned long) | 8 | 8 | sized | false |
|
||||
deleteArrayExprs
|
||||
| allocators.cpp:78:3:78:37 | delete[] | int | void operator delete[](void*, unsigned long) | 4 | 4 | sized |
|
||||
| allocators.cpp:79:3:79:40 | delete[] | String | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
|
||||
@@ -77,7 +77,8 @@ query predicate newArrayExprDeallocators(
|
||||
}
|
||||
|
||||
query predicate deleteExprs(
|
||||
DeleteExpr expr, string type, string sig, int size, int alignment, string form
|
||||
DeleteExpr expr, string type, string sig, int size, int alignment, string form,
|
||||
boolean hasDeallocatorCall
|
||||
) {
|
||||
exists(Function deallocator, Type deletedType |
|
||||
expr.getDeallocator() = deallocator and
|
||||
@@ -90,7 +91,10 @@ query predicate deleteExprs(
|
||||
(if expr.hasAlignedDeallocation() then aligned = "aligned" else aligned = "") and
|
||||
(if expr.hasSizedDeallocation() then sized = "sized" else sized = "") and
|
||||
form = sized + " " + aligned
|
||||
)
|
||||
) and
|
||||
if exists(expr.getDeallocatorCall())
|
||||
then hasDeallocatorCall = true
|
||||
else hasDeallocatorCall = false
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted.ql:10,8-47)
|
||||
WARNING: Predicate tainted has been deprecated and may be removed in future (tainted.ql:21,3-28)
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace {
|
||||
struct Foo {
|
||||
char string[10];
|
||||
};
|
||||
|
||||
void acquire(char*);
|
||||
|
||||
Foo* test_self_argument_flow() {
|
||||
Foo *info;
|
||||
acquire(info->string); // clean
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
@@ -788,4 +788,12 @@ void test_sometimes_calls_sink_switch() {
|
||||
sometimes_calls_sink_switch(source(), 1);
|
||||
sometimes_calls_sink_switch(0, 0);
|
||||
sometimes_calls_sink_switch(source(), 0);
|
||||
}
|
||||
|
||||
void intPointerSource(int *ref_source, const int* another_arg);
|
||||
|
||||
void test() {
|
||||
MyStruct a;
|
||||
intPointerSource(a.content, a.content);
|
||||
indirect_sink(a.content); // $ ast ir
|
||||
}
|
||||
@@ -5,5 +5,5 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (test.
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:40,25-33)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:42,17-25)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:46,20-28)
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
@@ -0,0 +1,33 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
module TestConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.getLocation().getFile().getBaseName() = "self_argument_flow.cpp" and
|
||||
source.asDefiningArgument() =
|
||||
any(Call call | call.getTarget().hasName("acquire")).getAnArgument()
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink.asIndirectArgument() = any(Call call | call.getTarget().hasName("acquire")).getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
import DataFlow::Global<TestConfig>
|
||||
|
||||
module TestSelfArgumentFlow implements TestSig {
|
||||
string getARelevantTag() { result = "self-arg-flow" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(DataFlow::Node sink |
|
||||
flowTo(sink) and
|
||||
location = sink.getLocation() and
|
||||
element = sink.toString() and
|
||||
tag = "self-arg-flow" and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<TestSelfArgumentFlow>
|
||||
@@ -14,6 +14,8 @@
|
||||
| ref.cpp:120:17:120:18 | x3 | ref.cpp:129:10:129:11 | x3 |
|
||||
| ref.cpp:120:21:120:22 | x4 | ref.cpp:131:15:131:16 | x4 |
|
||||
| ref.cpp:120:21:120:22 | x4 | ref.cpp:132:10:132:11 | x4 |
|
||||
| self_argument_flow.cpp:9:10:9:13 | info | self_argument_flow.cpp:10:13:10:16 | info |
|
||||
| self_argument_flow.cpp:9:10:9:13 | info | self_argument_flow.cpp:12:12:12:15 | info |
|
||||
| test.cpp:75:7:75:8 | u1 | test.cpp:76:8:76:9 | u1 |
|
||||
| test.cpp:83:7:83:8 | u2 | test.cpp:84:13:84:14 | u2 |
|
||||
| test.cpp:83:7:83:8 | u2 | test.cpp:85:8:85:9 | u2 |
|
||||
@@ -44,3 +46,6 @@
|
||||
| test.cpp:595:8:595:9 | xs | test.cpp:597:9:597:10 | xs |
|
||||
| test.cpp:733:7:733:7 | x | test.cpp:734:41:734:41 | x |
|
||||
| test.cpp:733:7:733:7 | x | test.cpp:735:8:735:8 | x |
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:797:20:797:20 | a |
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:797:31:797:31 | a |
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:798:17:798:17 | a |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,5 +3,5 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (taint
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:61,22-30)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:68,25-33)
|
||||
WARNING: Module TaintTracking has been deprecated and may be removed in future (taint.ql:73,20-33)
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -1798,6 +1798,23 @@ ir.c:
|
||||
# 10| Type = [CTypedefType] MyCoords
|
||||
# 10| ValueCategory = lvalue
|
||||
# 11| getStmt(3): [ReturnStmt] return ...
|
||||
# 13| [TopLevelFunction] void CStyleCast(void*)
|
||||
# 13| <params>:
|
||||
# 13| getParameter(0): [Parameter] src
|
||||
# 13| Type = [VoidPointerType] void *
|
||||
# 14| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 15| getStmt(0): [DeclStmt] declaration
|
||||
# 15| getDeclarationEntry(0): [VariableDeclarationEntry] definition of dst
|
||||
# 15| Type = [CharPointerType] char *
|
||||
# 15| getVariable().getInitializer(): [Initializer] initializer for dst
|
||||
# 15| getExpr(): [VariableAccess] src
|
||||
# 15| Type = [VoidPointerType] void *
|
||||
# 15| ValueCategory = prvalue(load)
|
||||
# 15| getExpr().getFullyConverted(): [CStyleCast] (char *)...
|
||||
# 15| Conversion = [PointerConversion] pointer conversion
|
||||
# 15| Type = [CharPointerType] char *
|
||||
# 15| ValueCategory = prvalue
|
||||
# 16| getStmt(1): [ReturnStmt] return ...
|
||||
ir.cpp:
|
||||
# 1| [TopLevelFunction] void Constants()
|
||||
# 1| <params>:
|
||||
@@ -8460,7 +8477,7 @@ ir.cpp:
|
||||
# 1018| getExpr(): [DeleteExpr] delete
|
||||
# 1018| Type = [VoidType] void
|
||||
# 1018| ValueCategory = prvalue
|
||||
# 1018| getAllocatorCall(): [FunctionCall] call to operator delete
|
||||
# 1018| getDeallocatorCall(): [FunctionCall] call to operator delete
|
||||
# 1018| Type = [VoidType] void
|
||||
# 1018| ValueCategory = prvalue
|
||||
# 1018| getExpr(): [Literal] 0
|
||||
@@ -8538,7 +8555,7 @@ ir.cpp:
|
||||
# 1027| getExpr(): [DeleteArrayExpr] delete[]
|
||||
# 1027| Type = [VoidType] void
|
||||
# 1027| ValueCategory = prvalue
|
||||
# 1027| getAllocatorCall(): [FunctionCall] call to operator delete[]
|
||||
# 1027| getDeallocatorCall(): [FunctionCall] call to operator delete[]
|
||||
# 1027| Type = [VoidType] void
|
||||
# 1027| ValueCategory = prvalue
|
||||
# 1027| getExpr(): [Literal] 0
|
||||
@@ -15536,6 +15553,193 @@ ir.cpp:
|
||||
# 2030| Type = [IntType] int
|
||||
# 2030| ValueCategory = prvalue
|
||||
# 2031| getStmt(2): [ReturnStmt] return ...
|
||||
# 2033| [TopLevelFunction] void NewDeleteMem()
|
||||
# 2033| <params>:
|
||||
# 2033| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2034| getStmt(0): [DeclStmt] declaration
|
||||
# 2034| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 2034| Type = [IntPointerType] int *
|
||||
# 2034| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 2034| getExpr(): [NewExpr] new
|
||||
# 2034| Type = [IntPointerType] int *
|
||||
# 2034| ValueCategory = prvalue
|
||||
# 2035| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2035| getExpr(): [AssignExpr] ... = ...
|
||||
# 2035| Type = [IntType] int
|
||||
# 2035| ValueCategory = lvalue
|
||||
# 2035| getLValue(): [PointerDereferenceExpr] * ...
|
||||
# 2035| Type = [IntType] int
|
||||
# 2035| ValueCategory = lvalue
|
||||
# 2035| getOperand(): [VariableAccess] x
|
||||
# 2035| Type = [IntPointerType] int *
|
||||
# 2035| ValueCategory = prvalue(load)
|
||||
# 2035| getRValue(): [Literal] 6
|
||||
# 2035| Type = [IntType] int
|
||||
# 2035| Value = [Literal] 6
|
||||
# 2035| ValueCategory = prvalue
|
||||
# 2036| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2036| getExpr(): [DeleteExpr] delete
|
||||
# 2036| Type = [VoidType] void
|
||||
# 2036| ValueCategory = prvalue
|
||||
# 2036| getExpr(): [VariableAccess] x
|
||||
# 2036| Type = [IntPointerType] int *
|
||||
# 2036| ValueCategory = prvalue(load)
|
||||
# 2037| getStmt(3): [ReturnStmt] return ...
|
||||
# 2039| [CopyAssignmentOperator] Base2& Base2::operator=(Base2 const&)
|
||||
# 2039| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Base2 &
|
||||
# 2039| [Constructor] void Base2::Base2()
|
||||
# 2039| <params>:
|
||||
# 2039| <initializations>:
|
||||
# 2039| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2039| getStmt(0): [ReturnStmt] return ...
|
||||
# 2039| [CopyConstructor] void Base2::Base2(Base2 const&)
|
||||
# 2039| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Base2 &
|
||||
# 2041| [MemberFunction] void Base2::operator delete(void*)
|
||||
# 2041| <params>:
|
||||
# 2041| getParameter(0): [Parameter] p
|
||||
# 2041| Type = [VoidPointerType] void *
|
||||
# 2041| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2042| getStmt(0): [ReturnStmt] return ...
|
||||
# 2043| [Destructor,VirtualFunction] void Base2::~Base2()
|
||||
# 2043| <params>:
|
||||
# 2043| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2043| getStmt(0): [ReturnStmt] return ...
|
||||
# 2043| <destructions>:
|
||||
# 2046| [CopyAssignmentOperator] Derived2& Derived2::operator=(Derived2 const&)
|
||||
# 2046| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Derived2 &
|
||||
# 2046| [Constructor] void Derived2::Derived2()
|
||||
# 2046| <params>:
|
||||
# 2046| <initializations>:
|
||||
# 2046| getInitializer(0): [ConstructorDirectInit] call to Base2
|
||||
# 2046| Type = [VoidType] void
|
||||
# 2046| ValueCategory = prvalue
|
||||
# 2046| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2046| getStmt(0): [ReturnStmt] return ...
|
||||
# 2046| [CopyConstructor] void Derived2::Derived2(Derived2 const&)
|
||||
# 2046| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Derived2 &
|
||||
# 2049| [Destructor,VirtualFunction] void Derived2::~Derived2()
|
||||
# 2049| <params>:
|
||||
# 2049| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2049| getStmt(0): [ReturnStmt] return ...
|
||||
# 2049| <destructions>:
|
||||
# 2049| getDestruction(0): [DestructorDirectDestruction] call to ~Base2
|
||||
# 2049| Type = [VoidType] void
|
||||
# 2049| ValueCategory = prvalue
|
||||
# 2051| [MemberFunction] void Derived2::operator delete(void*)
|
||||
# 2051| <params>:
|
||||
# 2051| getParameter(0): [Parameter] p
|
||||
# 2051| Type = [VoidPointerType] void *
|
||||
# 2051| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2052| getStmt(0): [ReturnStmt] return ...
|
||||
# 2056| [TopLevelFunction] int virtual_delete()
|
||||
# 2056| <params>:
|
||||
# 2057| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2058| getStmt(0): [DeclStmt] declaration
|
||||
# 2058| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b1
|
||||
# 2058| Type = [PointerType] Base2 *
|
||||
# 2058| getVariable().getInitializer(): [Initializer] initializer for b1
|
||||
# 2058| getExpr(): [NewExpr] new
|
||||
# 2058| Type = [PointerType] Base2 *
|
||||
# 2058| ValueCategory = prvalue
|
||||
# 2058| getInitializer(): [ConstructorCall] call to Base2
|
||||
# 2058| Type = [VoidType] void
|
||||
# 2058| ValueCategory = prvalue
|
||||
# 2059| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2059| getExpr(): [DeleteExpr] delete
|
||||
# 2059| Type = [VoidType] void
|
||||
# 2059| ValueCategory = prvalue
|
||||
# 2059| getDeallocatorCall(): [FunctionCall] call to operator delete
|
||||
# 2059| Type = [VoidType] void
|
||||
# 2059| ValueCategory = prvalue
|
||||
# 2059| getDestructorCall(): [DestructorCall] call to ~Base2
|
||||
# 2059| Type = [VoidType] void
|
||||
# 2059| ValueCategory = prvalue
|
||||
# 2059| getQualifier(): [VariableAccess] b1
|
||||
# 2059| Type = [PointerType] Base2 *
|
||||
# 2059| ValueCategory = prvalue(load)
|
||||
# 2061| getStmt(2): [DeclStmt] declaration
|
||||
# 2061| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b2
|
||||
# 2061| Type = [PointerType] Base2 *
|
||||
# 2061| getVariable().getInitializer(): [Initializer] initializer for b2
|
||||
# 2061| getExpr(): [NewExpr] new
|
||||
# 2061| Type = [PointerType] Derived2 *
|
||||
# 2061| ValueCategory = prvalue
|
||||
# 2061| getInitializer(): [ConstructorCall] call to Derived2
|
||||
# 2061| Type = [VoidType] void
|
||||
# 2061| ValueCategory = prvalue
|
||||
# 2061| getExpr().getFullyConverted(): [CStyleCast] (Base2 *)...
|
||||
# 2061| Conversion = [BaseClassConversion] base class conversion
|
||||
# 2061| Type = [PointerType] Base2 *
|
||||
# 2061| ValueCategory = prvalue
|
||||
# 2062| getStmt(3): [ExprStmt] ExprStmt
|
||||
# 2062| getExpr(): [DeleteExpr] delete
|
||||
# 2062| Type = [VoidType] void
|
||||
# 2062| ValueCategory = prvalue
|
||||
# 2062| getDeallocatorCall(): [FunctionCall] call to operator delete
|
||||
# 2062| Type = [VoidType] void
|
||||
# 2062| ValueCategory = prvalue
|
||||
# 2062| getDestructorCall(): [DestructorCall] call to ~Base2
|
||||
# 2062| Type = [VoidType] void
|
||||
# 2062| ValueCategory = prvalue
|
||||
# 2062| getQualifier(): [VariableAccess] b2
|
||||
# 2062| Type = [PointerType] Base2 *
|
||||
# 2062| ValueCategory = prvalue(load)
|
||||
# 2064| getStmt(4): [DeclStmt] declaration
|
||||
# 2064| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d
|
||||
# 2064| Type = [PointerType] Derived2 *
|
||||
# 2064| getVariable().getInitializer(): [Initializer] initializer for d
|
||||
# 2064| getExpr(): [NewExpr] new
|
||||
# 2064| Type = [PointerType] Derived2 *
|
||||
# 2064| ValueCategory = prvalue
|
||||
# 2064| getInitializer(): [ConstructorCall] call to Derived2
|
||||
# 2064| Type = [VoidType] void
|
||||
# 2064| ValueCategory = prvalue
|
||||
# 2065| getStmt(5): [ExprStmt] ExprStmt
|
||||
# 2065| getExpr(): [DeleteExpr] delete
|
||||
# 2065| Type = [VoidType] void
|
||||
# 2065| ValueCategory = prvalue
|
||||
# 2065| getDeallocatorCall(): [FunctionCall] call to operator delete
|
||||
# 2065| Type = [VoidType] void
|
||||
# 2065| ValueCategory = prvalue
|
||||
# 2065| getDestructorCall(): [DestructorCall] call to ~Derived2
|
||||
# 2065| Type = [VoidType] void
|
||||
# 2065| ValueCategory = prvalue
|
||||
# 2065| getQualifier(): [VariableAccess] d
|
||||
# 2065| Type = [PointerType] Derived2 *
|
||||
# 2065| ValueCategory = prvalue(load)
|
||||
# 2066| getStmt(6): [ReturnStmt] return ...
|
||||
# 2068| [TopLevelFunction] void test_constant_folding_use(int)
|
||||
# 2068| <params>:
|
||||
# 2068| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 2068| Type = [IntType] int
|
||||
# 2070| [TopLevelFunction] void test_constant_folding()
|
||||
# 2070| <params>:
|
||||
# 2070| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2071| getStmt(0): [DeclStmt] declaration
|
||||
# 2071| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 2071| Type = [SpecifiedType] const int
|
||||
# 2071| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 2071| getExpr(): [Literal] 116
|
||||
# 2071| Type = [IntType] int
|
||||
# 2071| Value = [Literal] 116
|
||||
# 2071| ValueCategory = prvalue
|
||||
# 2072| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2072| getExpr(): [FunctionCall] call to test_constant_folding_use
|
||||
# 2072| Type = [VoidType] void
|
||||
# 2072| ValueCategory = prvalue
|
||||
# 2072| getArgument(0): [VariableAccess] x
|
||||
# 2072| Type = [IntType] int
|
||||
# 2072| Value = [VariableAccess] 116
|
||||
# 2072| ValueCategory = prvalue(load)
|
||||
# 2073| getStmt(2): [ReturnStmt] return ...
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
@@ -9,3 +9,10 @@ void MyCoordsTest(int pos) {
|
||||
coords.x = coords.y = pos + 1;
|
||||
coords.x = getX(&coords);
|
||||
}
|
||||
|
||||
void CStyleCast(void *src)
|
||||
{
|
||||
char *dst = (char*)src;
|
||||
}
|
||||
|
||||
// semmle-extractor-options: --microsoft
|
||||
|
||||
@@ -2030,4 +2030,46 @@ unsigned int CommaTest(unsigned int x) {
|
||||
(CommaTestHelper(x), 10);
|
||||
}
|
||||
|
||||
void NewDeleteMem() {
|
||||
int* x = new int; // No constructor
|
||||
*x = 6;
|
||||
delete x;
|
||||
}
|
||||
|
||||
class Base2 {
|
||||
public:
|
||||
void operator delete(void* p) {
|
||||
}
|
||||
virtual ~Base2() {};
|
||||
};
|
||||
|
||||
class Derived2 : public Base2 {
|
||||
int i;
|
||||
public:
|
||||
~Derived2() {};
|
||||
|
||||
void operator delete(void* p) {
|
||||
}
|
||||
};
|
||||
|
||||
// Delete is kind-of virtual in these cases
|
||||
int virtual_delete()
|
||||
{
|
||||
Base2* b1 = new Base2{};
|
||||
delete b1;
|
||||
|
||||
Base2* b2 = new Derived2{};
|
||||
delete b2;
|
||||
|
||||
Derived2* d = new Derived2{};
|
||||
delete d;
|
||||
}
|
||||
|
||||
void test_constant_folding_use(int);
|
||||
|
||||
void test_constant_folding() {
|
||||
const int x = 116;
|
||||
test_constant_folding_use(x);
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++17 --clang
|
||||
|
||||
@@ -978,6 +978,20 @@
|
||||
| ir.c:10:19:10:25 | ChiTotal | total:m9_13 |
|
||||
| ir.c:10:19:10:25 | SideEffect | ~m9_13 |
|
||||
| ir.c:10:20:10:25 | Unary | r10_2 |
|
||||
| ir.c:13:6:13:15 | ChiPartial | partial:m13_3 |
|
||||
| ir.c:13:6:13:15 | ChiTotal | total:m13_2 |
|
||||
| ir.c:13:6:13:15 | SideEffect | m13_3 |
|
||||
| ir.c:13:23:13:25 | Address | &:r13_5 |
|
||||
| ir.c:13:23:13:25 | Address | &:r13_5 |
|
||||
| ir.c:13:23:13:25 | Address | &:r13_7 |
|
||||
| ir.c:13:23:13:25 | Address | &:r13_7 |
|
||||
| ir.c:13:23:13:25 | Load | m13_6 |
|
||||
| ir.c:13:23:13:25 | SideEffect | m13_8 |
|
||||
| ir.c:15:11:15:13 | Address | &:r15_1 |
|
||||
| ir.c:15:17:15:26 | StoreValue | r15_4 |
|
||||
| ir.c:15:24:15:26 | Address | &:r15_2 |
|
||||
| ir.c:15:24:15:26 | Load | m13_6 |
|
||||
| ir.c:15:24:15:26 | Unary | r15_3 |
|
||||
| ir.cpp:1:6:1:14 | ChiPartial | partial:m1_3 |
|
||||
| ir.cpp:1:6:1:14 | ChiTotal | total:m1_2 |
|
||||
| ir.cpp:1:6:1:14 | SideEffect | m1_3 |
|
||||
@@ -4873,10 +4887,60 @@
|
||||
| ir.cpp:1011:12:1011:12 | Unary | r1011_3 |
|
||||
| ir.cpp:1015:6:1015:19 | ChiPartial | partial:m1015_3 |
|
||||
| ir.cpp:1015:6:1015:19 | ChiTotal | total:m1015_2 |
|
||||
| ir.cpp:1015:6:1015:19 | SideEffect | m1015_3 |
|
||||
| ir.cpp:1015:6:1015:19 | SideEffect | ~m1020_5 |
|
||||
| ir.cpp:1016:3:1016:35 | CallTarget | func:r1016_1 |
|
||||
| ir.cpp:1016:3:1016:35 | ChiPartial | partial:m1016_4 |
|
||||
| ir.cpp:1016:3:1016:35 | ChiTotal | total:m1015_4 |
|
||||
| ir.cpp:1016:3:1016:35 | SideEffect | ~m1015_4 |
|
||||
| ir.cpp:1016:10:1016:35 | Arg(0) | 0:r1016_2 |
|
||||
| ir.cpp:1017:3:1017:38 | CallTarget | func:r1017_1 |
|
||||
| ir.cpp:1017:3:1017:38 | ChiPartial | partial:m1017_4 |
|
||||
| ir.cpp:1017:3:1017:38 | ChiTotal | total:m1016_5 |
|
||||
| ir.cpp:1017:3:1017:38 | SideEffect | ~m1016_5 |
|
||||
| ir.cpp:1017:10:1017:38 | Arg(0) | 0:r1017_2 |
|
||||
| ir.cpp:1018:3:1018:44 | CallTarget | func:r1018_1 |
|
||||
| ir.cpp:1018:3:1018:44 | ChiPartial | partial:m1018_4 |
|
||||
| ir.cpp:1018:3:1018:44 | ChiTotal | total:m1017_5 |
|
||||
| ir.cpp:1018:3:1018:44 | SideEffect | ~m1017_5 |
|
||||
| ir.cpp:1018:10:1018:44 | Arg(0) | 0:r1018_2 |
|
||||
| ir.cpp:1019:3:1019:43 | CallTarget | func:r1019_1 |
|
||||
| ir.cpp:1019:3:1019:43 | ChiPartial | partial:m1019_4 |
|
||||
| ir.cpp:1019:3:1019:43 | ChiTotal | total:m1018_5 |
|
||||
| ir.cpp:1019:3:1019:43 | SideEffect | ~m1018_5 |
|
||||
| ir.cpp:1019:10:1019:43 | Arg(0) | 0:r1019_2 |
|
||||
| ir.cpp:1020:3:1020:47 | CallTarget | func:r1020_1 |
|
||||
| ir.cpp:1020:3:1020:47 | ChiPartial | partial:m1020_4 |
|
||||
| ir.cpp:1020:3:1020:47 | ChiTotal | total:m1019_5 |
|
||||
| ir.cpp:1020:3:1020:47 | SideEffect | ~m1019_5 |
|
||||
| ir.cpp:1020:10:1020:47 | Arg(0) | 0:r1020_2 |
|
||||
| ir.cpp:1024:6:1024:24 | ChiPartial | partial:m1024_3 |
|
||||
| ir.cpp:1024:6:1024:24 | ChiTotal | total:m1024_2 |
|
||||
| ir.cpp:1024:6:1024:24 | SideEffect | m1024_3 |
|
||||
| ir.cpp:1024:6:1024:24 | SideEffect | ~m1029_5 |
|
||||
| ir.cpp:1025:3:1025:37 | CallTarget | func:r1025_1 |
|
||||
| ir.cpp:1025:3:1025:37 | ChiPartial | partial:m1025_4 |
|
||||
| ir.cpp:1025:3:1025:37 | ChiTotal | total:m1024_4 |
|
||||
| ir.cpp:1025:3:1025:37 | SideEffect | ~m1024_4 |
|
||||
| ir.cpp:1025:12:1025:37 | Arg(0) | 0:r1025_2 |
|
||||
| ir.cpp:1026:3:1026:40 | CallTarget | func:r1026_1 |
|
||||
| ir.cpp:1026:3:1026:40 | ChiPartial | partial:m1026_4 |
|
||||
| ir.cpp:1026:3:1026:40 | ChiTotal | total:m1025_5 |
|
||||
| ir.cpp:1026:3:1026:40 | SideEffect | ~m1025_5 |
|
||||
| ir.cpp:1026:12:1026:40 | Arg(0) | 0:r1026_2 |
|
||||
| ir.cpp:1027:3:1027:46 | CallTarget | func:r1027_1 |
|
||||
| ir.cpp:1027:3:1027:46 | ChiPartial | partial:m1027_4 |
|
||||
| ir.cpp:1027:3:1027:46 | ChiTotal | total:m1026_5 |
|
||||
| ir.cpp:1027:3:1027:46 | SideEffect | ~m1026_5 |
|
||||
| ir.cpp:1027:12:1027:46 | Arg(0) | 0:r1027_2 |
|
||||
| ir.cpp:1028:3:1028:45 | CallTarget | func:r1028_1 |
|
||||
| ir.cpp:1028:3:1028:45 | ChiPartial | partial:m1028_4 |
|
||||
| ir.cpp:1028:3:1028:45 | ChiTotal | total:m1027_5 |
|
||||
| ir.cpp:1028:3:1028:45 | SideEffect | ~m1027_5 |
|
||||
| ir.cpp:1028:12:1028:45 | Arg(0) | 0:r1028_2 |
|
||||
| ir.cpp:1029:3:1029:49 | CallTarget | func:r1029_1 |
|
||||
| ir.cpp:1029:3:1029:49 | ChiPartial | partial:m1029_4 |
|
||||
| ir.cpp:1029:3:1029:49 | ChiTotal | total:m1028_5 |
|
||||
| ir.cpp:1029:3:1029:49 | SideEffect | ~m1028_5 |
|
||||
| ir.cpp:1029:12:1029:49 | Arg(0) | 0:r1029_2 |
|
||||
| ir.cpp:1034:6:1034:20 | ChiPartial | partial:m1034_3 |
|
||||
| ir.cpp:1034:6:1034:20 | ChiTotal | total:m1034_2 |
|
||||
| ir.cpp:1034:6:1034:20 | SideEffect | m1034_3 |
|
||||
@@ -9562,6 +9626,186 @@
|
||||
| ir.cpp:2030:22:2030:22 | Arg(0) | 0:r2030_3 |
|
||||
| ir.cpp:2030:22:2030:22 | Load | m2026_6 |
|
||||
| ir.cpp:2030:26:2030:27 | Unary | r2030_7 |
|
||||
| ir.cpp:2033:6:2033:17 | ChiPartial | partial:m2033_3 |
|
||||
| ir.cpp:2033:6:2033:17 | ChiTotal | total:m2033_2 |
|
||||
| ir.cpp:2033:6:2033:17 | SideEffect | ~m2036_6 |
|
||||
| ir.cpp:2034:8:2034:8 | Address | &:r2034_1 |
|
||||
| ir.cpp:2034:12:2034:18 | Address | &:r2034_4 |
|
||||
| ir.cpp:2034:12:2034:18 | Arg(0) | 0:r2034_3 |
|
||||
| ir.cpp:2034:12:2034:18 | CallTarget | func:r2034_2 |
|
||||
| ir.cpp:2034:12:2034:18 | ChiPartial | partial:m2034_5 |
|
||||
| ir.cpp:2034:12:2034:18 | ChiTotal | total:m2033_4 |
|
||||
| ir.cpp:2034:12:2034:18 | SideEffect | ~m2033_4 |
|
||||
| ir.cpp:2034:12:2034:18 | StoreValue | r2034_8 |
|
||||
| ir.cpp:2034:12:2034:18 | Unary | r2034_4 |
|
||||
| ir.cpp:2035:3:2035:4 | Address | &:r2035_4 |
|
||||
| ir.cpp:2035:3:2035:8 | ChiPartial | partial:m2035_5 |
|
||||
| ir.cpp:2035:3:2035:8 | ChiTotal | total:m2034_7 |
|
||||
| ir.cpp:2035:4:2035:4 | Address | &:r2035_2 |
|
||||
| ir.cpp:2035:4:2035:4 | Load | m2034_9 |
|
||||
| ir.cpp:2035:4:2035:4 | Unary | r2035_3 |
|
||||
| ir.cpp:2035:8:2035:8 | StoreValue | r2035_1 |
|
||||
| ir.cpp:2036:3:2036:10 | CallTarget | func:r2036_1 |
|
||||
| ir.cpp:2036:3:2036:10 | ChiPartial | partial:m2036_5 |
|
||||
| ir.cpp:2036:3:2036:10 | ChiTotal | total:m2034_6 |
|
||||
| ir.cpp:2036:3:2036:10 | SideEffect | ~m2034_6 |
|
||||
| ir.cpp:2036:10:2036:10 | Address | &:r2036_2 |
|
||||
| ir.cpp:2036:10:2036:10 | Arg(0) | 0:r2036_3 |
|
||||
| ir.cpp:2036:10:2036:10 | Load | m2034_9 |
|
||||
| ir.cpp:2039:7:2039:7 | Address | &:r2039_5 |
|
||||
| ir.cpp:2039:7:2039:7 | Address | &:r2039_5 |
|
||||
| ir.cpp:2039:7:2039:7 | Address | &:r2039_7 |
|
||||
| ir.cpp:2039:7:2039:7 | Address | &:r2039_7 |
|
||||
| ir.cpp:2039:7:2039:7 | ChiPartial | partial:m2039_3 |
|
||||
| ir.cpp:2039:7:2039:7 | ChiTotal | total:m2039_2 |
|
||||
| ir.cpp:2039:7:2039:7 | Load | m2039_6 |
|
||||
| ir.cpp:2039:7:2039:7 | SideEffect | m2039_3 |
|
||||
| ir.cpp:2039:7:2039:7 | SideEffect | m2039_8 |
|
||||
| ir.cpp:2041:10:2041:24 | ChiPartial | partial:m2041_3 |
|
||||
| ir.cpp:2041:10:2041:24 | ChiTotal | total:m2041_2 |
|
||||
| ir.cpp:2041:10:2041:24 | SideEffect | m2041_3 |
|
||||
| ir.cpp:2041:32:2041:32 | Address | &:r2041_5 |
|
||||
| ir.cpp:2041:32:2041:32 | Address | &:r2041_5 |
|
||||
| ir.cpp:2041:32:2041:32 | Address | &:r2041_7 |
|
||||
| ir.cpp:2041:32:2041:32 | Address | &:r2041_7 |
|
||||
| ir.cpp:2041:32:2041:32 | Load | m2041_6 |
|
||||
| ir.cpp:2041:32:2041:32 | SideEffect | m2041_8 |
|
||||
| ir.cpp:2043:13:2043:18 | Address | &:r2043_5 |
|
||||
| ir.cpp:2043:13:2043:18 | Address | &:r2043_5 |
|
||||
| ir.cpp:2043:13:2043:18 | Address | &:r2043_7 |
|
||||
| ir.cpp:2043:13:2043:18 | Address | &:r2043_7 |
|
||||
| ir.cpp:2043:13:2043:18 | ChiPartial | partial:m2043_3 |
|
||||
| ir.cpp:2043:13:2043:18 | ChiTotal | total:m2043_2 |
|
||||
| ir.cpp:2043:13:2043:18 | Load | m2043_6 |
|
||||
| ir.cpp:2043:13:2043:18 | SideEffect | m2043_3 |
|
||||
| ir.cpp:2043:13:2043:18 | SideEffect | m2043_8 |
|
||||
| ir.cpp:2046:7:2046:7 | Address | &:r2046_5 |
|
||||
| ir.cpp:2046:7:2046:7 | Address | &:r2046_5 |
|
||||
| ir.cpp:2046:7:2046:7 | Address | &:r2046_7 |
|
||||
| ir.cpp:2046:7:2046:7 | Address | &:r2046_7 |
|
||||
| ir.cpp:2046:7:2046:7 | Address | &:r2046_9 |
|
||||
| ir.cpp:2046:7:2046:7 | Arg(this) | this:r2046_9 |
|
||||
| ir.cpp:2046:7:2046:7 | CallTarget | func:r2046_10 |
|
||||
| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_3 |
|
||||
| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_12 |
|
||||
| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_14 |
|
||||
| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_2 |
|
||||
| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_4 |
|
||||
| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_8 |
|
||||
| ir.cpp:2046:7:2046:7 | Load | m2046_6 |
|
||||
| ir.cpp:2046:7:2046:7 | SideEffect | m2046_15 |
|
||||
| ir.cpp:2046:7:2046:7 | SideEffect | ~m2046_4 |
|
||||
| ir.cpp:2046:7:2046:7 | SideEffect | ~m2046_13 |
|
||||
| ir.cpp:2046:7:2046:7 | Unary | m2046_6 |
|
||||
| ir.cpp:2049:5:2049:13 | Address | &:r2049_5 |
|
||||
| ir.cpp:2049:5:2049:13 | Address | &:r2049_5 |
|
||||
| ir.cpp:2049:5:2049:13 | Address | &:r2049_7 |
|
||||
| ir.cpp:2049:5:2049:13 | Address | &:r2049_7 |
|
||||
| ir.cpp:2049:5:2049:13 | ChiPartial | partial:m2049_3 |
|
||||
| ir.cpp:2049:5:2049:13 | ChiTotal | total:m2049_2 |
|
||||
| ir.cpp:2049:5:2049:13 | Load | m2049_6 |
|
||||
| ir.cpp:2049:5:2049:13 | SideEffect | m2049_8 |
|
||||
| ir.cpp:2049:5:2049:13 | SideEffect | ~m2049_14 |
|
||||
| ir.cpp:2049:5:2049:13 | Unary | m2049_6 |
|
||||
| ir.cpp:2049:18:2049:18 | Arg(this) | this:r2049_10 |
|
||||
| ir.cpp:2049:18:2049:18 | CallTarget | func:r2049_11 |
|
||||
| ir.cpp:2049:18:2049:18 | ChiPartial | partial:m2049_13 |
|
||||
| ir.cpp:2049:18:2049:18 | ChiTotal | total:m2049_4 |
|
||||
| ir.cpp:2049:18:2049:18 | SideEffect | ~m2049_4 |
|
||||
| ir.cpp:2051:10:2051:24 | ChiPartial | partial:m2051_3 |
|
||||
| ir.cpp:2051:10:2051:24 | ChiTotal | total:m2051_2 |
|
||||
| ir.cpp:2051:10:2051:24 | SideEffect | m2051_3 |
|
||||
| ir.cpp:2051:32:2051:32 | Address | &:r2051_5 |
|
||||
| ir.cpp:2051:32:2051:32 | Address | &:r2051_5 |
|
||||
| ir.cpp:2051:32:2051:32 | Address | &:r2051_7 |
|
||||
| ir.cpp:2051:32:2051:32 | Address | &:r2051_7 |
|
||||
| ir.cpp:2051:32:2051:32 | Load | m2051_6 |
|
||||
| ir.cpp:2051:32:2051:32 | SideEffect | m2051_8 |
|
||||
| ir.cpp:2056:5:2056:18 | ChiPartial | partial:m2056_3 |
|
||||
| ir.cpp:2056:5:2056:18 | ChiTotal | total:m2056_2 |
|
||||
| ir.cpp:2058:12:2058:13 | Address | &:r2058_1 |
|
||||
| ir.cpp:2058:17:2058:27 | Address | &:r2058_4 |
|
||||
| ir.cpp:2058:17:2058:27 | Address | &:r2058_8 |
|
||||
| ir.cpp:2058:17:2058:27 | Arg(0) | 0:r2058_3 |
|
||||
| ir.cpp:2058:17:2058:27 | Arg(this) | this:r2058_8 |
|
||||
| ir.cpp:2058:17:2058:27 | CallTarget | func:r2058_2 |
|
||||
| ir.cpp:2058:17:2058:27 | CallTarget | func:r2058_9 |
|
||||
| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_5 |
|
||||
| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_11 |
|
||||
| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_13 |
|
||||
| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2056_4 |
|
||||
| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2058_6 |
|
||||
| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2058_7 |
|
||||
| ir.cpp:2058:17:2058:27 | SideEffect | ~m2056_4 |
|
||||
| ir.cpp:2058:17:2058:27 | SideEffect | ~m2058_6 |
|
||||
| ir.cpp:2058:17:2058:27 | StoreValue | r2058_8 |
|
||||
| ir.cpp:2058:17:2058:27 | Unary | r2058_4 |
|
||||
| ir.cpp:2059:5:2059:13 | CallTarget | func:r2059_1 |
|
||||
| ir.cpp:2059:5:2059:13 | ChiPartial | partial:m2059_5 |
|
||||
| ir.cpp:2059:5:2059:13 | ChiTotal | total:m2058_12 |
|
||||
| ir.cpp:2059:5:2059:13 | SideEffect | ~m2058_12 |
|
||||
| ir.cpp:2059:12:2059:13 | Address | &:r2059_2 |
|
||||
| ir.cpp:2059:12:2059:13 | Arg(0) | 0:r2059_3 |
|
||||
| ir.cpp:2059:12:2059:13 | Load | m2058_15 |
|
||||
| ir.cpp:2061:12:2061:13 | Address | &:r2061_1 |
|
||||
| ir.cpp:2061:17:2061:30 | Address | &:r2061_4 |
|
||||
| ir.cpp:2061:17:2061:30 | Address | &:r2061_8 |
|
||||
| ir.cpp:2061:17:2061:30 | Arg(0) | 0:r2061_3 |
|
||||
| ir.cpp:2061:17:2061:30 | Arg(this) | this:r2061_8 |
|
||||
| ir.cpp:2061:17:2061:30 | CallTarget | func:r2061_2 |
|
||||
| ir.cpp:2061:17:2061:30 | CallTarget | func:r2061_9 |
|
||||
| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_5 |
|
||||
| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_11 |
|
||||
| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_13 |
|
||||
| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2059_6 |
|
||||
| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2061_6 |
|
||||
| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2061_7 |
|
||||
| ir.cpp:2061:17:2061:30 | SideEffect | ~m2059_6 |
|
||||
| ir.cpp:2061:17:2061:30 | SideEffect | ~m2061_6 |
|
||||
| ir.cpp:2061:17:2061:30 | StoreValue | r2061_15 |
|
||||
| ir.cpp:2061:17:2061:30 | Unary | r2061_4 |
|
||||
| ir.cpp:2061:17:2061:30 | Unary | r2061_8 |
|
||||
| ir.cpp:2062:5:2062:13 | CallTarget | func:r2062_1 |
|
||||
| ir.cpp:2062:5:2062:13 | ChiPartial | partial:m2062_5 |
|
||||
| ir.cpp:2062:5:2062:13 | ChiTotal | total:m2061_12 |
|
||||
| ir.cpp:2062:5:2062:13 | SideEffect | ~m2061_12 |
|
||||
| ir.cpp:2062:12:2062:13 | Address | &:r2062_2 |
|
||||
| ir.cpp:2062:12:2062:13 | Arg(0) | 0:r2062_3 |
|
||||
| ir.cpp:2062:12:2062:13 | Load | m2061_16 |
|
||||
| ir.cpp:2064:15:2064:15 | Address | &:r2064_1 |
|
||||
| ir.cpp:2064:19:2064:32 | Address | &:r2064_4 |
|
||||
| ir.cpp:2064:19:2064:32 | Address | &:r2064_8 |
|
||||
| ir.cpp:2064:19:2064:32 | Arg(0) | 0:r2064_3 |
|
||||
| ir.cpp:2064:19:2064:32 | Arg(this) | this:r2064_8 |
|
||||
| ir.cpp:2064:19:2064:32 | CallTarget | func:r2064_2 |
|
||||
| ir.cpp:2064:19:2064:32 | CallTarget | func:r2064_9 |
|
||||
| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_5 |
|
||||
| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_11 |
|
||||
| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_13 |
|
||||
| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2062_6 |
|
||||
| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2064_6 |
|
||||
| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2064_7 |
|
||||
| ir.cpp:2064:19:2064:32 | SideEffect | ~m2062_6 |
|
||||
| ir.cpp:2064:19:2064:32 | SideEffect | ~m2064_6 |
|
||||
| ir.cpp:2064:19:2064:32 | StoreValue | r2064_8 |
|
||||
| ir.cpp:2064:19:2064:32 | Unary | r2064_4 |
|
||||
| ir.cpp:2065:5:2065:12 | CallTarget | func:r2065_1 |
|
||||
| ir.cpp:2065:5:2065:12 | ChiPartial | partial:m2065_5 |
|
||||
| ir.cpp:2065:5:2065:12 | ChiTotal | total:m2064_12 |
|
||||
| ir.cpp:2065:5:2065:12 | SideEffect | ~m2064_12 |
|
||||
| ir.cpp:2065:12:2065:12 | Address | &:r2065_2 |
|
||||
| ir.cpp:2065:12:2065:12 | Arg(0) | 0:r2065_3 |
|
||||
| ir.cpp:2065:12:2065:12 | Load | m2064_15 |
|
||||
| ir.cpp:2070:6:2070:26 | ChiPartial | partial:m2070_3 |
|
||||
| ir.cpp:2070:6:2070:26 | ChiTotal | total:m2070_2 |
|
||||
| ir.cpp:2070:6:2070:26 | SideEffect | ~m2072_5 |
|
||||
| ir.cpp:2071:13:2071:13 | Address | &:r2071_1 |
|
||||
| ir.cpp:2071:16:2071:19 | StoreValue | r2071_2 |
|
||||
| ir.cpp:2072:3:2072:27 | CallTarget | func:r2072_1 |
|
||||
| ir.cpp:2072:3:2072:27 | ChiPartial | partial:m2072_4 |
|
||||
| ir.cpp:2072:3:2072:27 | ChiTotal | total:m2070_4 |
|
||||
| ir.cpp:2072:3:2072:27 | SideEffect | ~m2070_4 |
|
||||
| ir.cpp:2072:29:2072:29 | Arg(0) | 0:r2072_2 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |
|
||||
|
||||
@@ -766,6 +766,26 @@ ir.c:
|
||||
# 7| v7_7(void) = AliasedUse : ~m?
|
||||
# 7| v7_8(void) = ExitFunction :
|
||||
|
||||
# 13| void CStyleCast(void*)
|
||||
# 13| Block 0
|
||||
# 13| v13_1(void) = EnterFunction :
|
||||
# 13| mu13_2(unknown) = AliasedDefinition :
|
||||
# 13| mu13_3(unknown) = InitializeNonLocal :
|
||||
# 13| r13_4(glval<void *>) = VariableAddress[src] :
|
||||
# 13| mu13_5(void *) = InitializeParameter[src] : &:r13_4
|
||||
# 13| r13_6(void *) = Load[src] : &:r13_4, ~m?
|
||||
# 13| mu13_7(unknown) = InitializeIndirection[src] : &:r13_6
|
||||
# 15| r15_1(glval<char *>) = VariableAddress[dst] :
|
||||
# 15| r15_2(glval<void *>) = VariableAddress[src] :
|
||||
# 15| r15_3(void *) = Load[src] : &:r15_2, ~m?
|
||||
# 15| r15_4(char *) = Convert : r15_3
|
||||
# 15| mu15_5(char *) = Store[dst] : &:r15_1, r15_4
|
||||
# 16| v16_1(void) = NoOp :
|
||||
# 13| v13_8(void) = ReturnIndirection[src] : &:r13_6, ~m?
|
||||
# 13| v13_9(void) = ReturnVoid :
|
||||
# 13| v13_10(void) = AliasedUse : ~m?
|
||||
# 13| v13_11(void) = ExitFunction :
|
||||
|
||||
ir.cpp:
|
||||
# 1| void Constants()
|
||||
# 1| Block 0
|
||||
@@ -5643,43 +5663,63 @@ ir.cpp:
|
||||
|
||||
# 1015| void OperatorDelete()
|
||||
# 1015| Block 0
|
||||
# 1015| v1015_1(void) = EnterFunction :
|
||||
# 1015| mu1015_2(unknown) = AliasedDefinition :
|
||||
# 1015| mu1015_3(unknown) = InitializeNonLocal :
|
||||
# 1016| r1016_1(int *) = Constant[0] :
|
||||
# 1016| v1016_2(void) = NoOp :
|
||||
# 1017| r1017_1(String *) = Constant[0] :
|
||||
# 1017| v1017_2(void) = NoOp :
|
||||
# 1018| r1018_1(SizedDealloc *) = Constant[0] :
|
||||
# 1018| v1018_2(void) = NoOp :
|
||||
# 1019| r1019_1(Overaligned *) = Constant[0] :
|
||||
# 1019| v1019_2(void) = NoOp :
|
||||
# 1020| r1020_1(PolymorphicBase *) = Constant[0] :
|
||||
# 1020| v1020_2(void) = NoOp :
|
||||
# 1021| v1021_1(void) = NoOp :
|
||||
# 1015| v1015_4(void) = ReturnVoid :
|
||||
# 1015| v1015_5(void) = AliasedUse : ~m?
|
||||
# 1015| v1015_6(void) = ExitFunction :
|
||||
# 1015| v1015_1(void) = EnterFunction :
|
||||
# 1015| mu1015_2(unknown) = AliasedDefinition :
|
||||
# 1015| mu1015_3(unknown) = InitializeNonLocal :
|
||||
# 1016| r1016_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 1016| r1016_2(int *) = Constant[0] :
|
||||
# 1016| v1016_3(void) = Call[operator delete] : func:r1016_1, 0:r1016_2
|
||||
# 1016| mu1016_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1017| r1017_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 1017| r1017_2(String *) = Constant[0] :
|
||||
# 1017| v1017_3(void) = Call[operator delete] : func:r1017_1, 0:r1017_2
|
||||
# 1017| mu1017_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1018| r1018_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 1018| r1018_2(SizedDealloc *) = Constant[0] :
|
||||
# 1018| v1018_3(void) = Call[operator delete] : func:r1018_1, 0:r1018_2
|
||||
# 1018| mu1018_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1019| r1019_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 1019| r1019_2(Overaligned *) = Constant[0] :
|
||||
# 1019| v1019_3(void) = Call[operator delete] : func:r1019_1, 0:r1019_2
|
||||
# 1019| mu1019_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1020| r1020_1(glval<unknown>) = VirtualDeleteFunctionAddress :
|
||||
# 1020| r1020_2(PolymorphicBase *) = Constant[0] :
|
||||
# 1020| v1020_3(void) = Call[?] : func:r1020_1, 0:r1020_2
|
||||
# 1020| mu1020_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1021| v1021_1(void) = NoOp :
|
||||
# 1015| v1015_4(void) = ReturnVoid :
|
||||
# 1015| v1015_5(void) = AliasedUse : ~m?
|
||||
# 1015| v1015_6(void) = ExitFunction :
|
||||
|
||||
# 1024| void OperatorDeleteArray()
|
||||
# 1024| Block 0
|
||||
# 1024| v1024_1(void) = EnterFunction :
|
||||
# 1024| mu1024_2(unknown) = AliasedDefinition :
|
||||
# 1024| mu1024_3(unknown) = InitializeNonLocal :
|
||||
# 1025| r1025_1(int *) = Constant[0] :
|
||||
# 1025| v1025_2(void) = NoOp :
|
||||
# 1026| r1026_1(String *) = Constant[0] :
|
||||
# 1026| v1026_2(void) = NoOp :
|
||||
# 1027| r1027_1(SizedDealloc *) = Constant[0] :
|
||||
# 1027| v1027_2(void) = NoOp :
|
||||
# 1028| r1028_1(Overaligned *) = Constant[0] :
|
||||
# 1028| v1028_2(void) = NoOp :
|
||||
# 1029| r1029_1(PolymorphicBase *) = Constant[0] :
|
||||
# 1029| v1029_2(void) = NoOp :
|
||||
# 1030| v1030_1(void) = NoOp :
|
||||
# 1024| v1024_4(void) = ReturnVoid :
|
||||
# 1024| v1024_5(void) = AliasedUse : ~m?
|
||||
# 1024| v1024_6(void) = ExitFunction :
|
||||
# 1024| v1024_1(void) = EnterFunction :
|
||||
# 1024| mu1024_2(unknown) = AliasedDefinition :
|
||||
# 1024| mu1024_3(unknown) = InitializeNonLocal :
|
||||
# 1025| r1025_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1025| r1025_2(int *) = Constant[0] :
|
||||
# 1025| v1025_3(void) = Call[operator delete[]] : func:r1025_1, 0:r1025_2
|
||||
# 1025| mu1025_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1026| r1026_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1026| r1026_2(String *) = Constant[0] :
|
||||
# 1026| v1026_3(void) = Call[operator delete[]] : func:r1026_1, 0:r1026_2
|
||||
# 1026| mu1026_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1027| r1027_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1027| r1027_2(SizedDealloc *) = Constant[0] :
|
||||
# 1027| v1027_3(void) = Call[operator delete[]] : func:r1027_1, 0:r1027_2
|
||||
# 1027| mu1027_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1028| r1028_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1028| r1028_2(Overaligned *) = Constant[0] :
|
||||
# 1028| v1028_3(void) = Call[operator delete[]] : func:r1028_1, 0:r1028_2
|
||||
# 1028| mu1028_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1029| r1029_1(glval<unknown>) = FunctionAddress[operator delete[]] :
|
||||
# 1029| r1029_2(PolymorphicBase *) = Constant[0] :
|
||||
# 1029| v1029_3(void) = Call[operator delete[]] : func:r1029_1, 0:r1029_2
|
||||
# 1029| mu1029_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 1030| v1030_1(void) = NoOp :
|
||||
# 1024| v1024_4(void) = ReturnVoid :
|
||||
# 1024| v1024_5(void) = AliasedUse : ~m?
|
||||
# 1024| v1024_6(void) = ExitFunction :
|
||||
|
||||
# 1034| void EmptyStructInit()
|
||||
# 1034| Block 0
|
||||
@@ -11071,6 +11111,215 @@ ir.cpp:
|
||||
# 2028| mu2028_13(unsigned int) = Store[#temp2028:7] : &:r2028_12, r2030_8
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 2033| void NewDeleteMem()
|
||||
# 2033| Block 0
|
||||
# 2033| v2033_1(void) = EnterFunction :
|
||||
# 2033| mu2033_2(unknown) = AliasedDefinition :
|
||||
# 2033| mu2033_3(unknown) = InitializeNonLocal :
|
||||
# 2034| r2034_1(glval<int *>) = VariableAddress[x] :
|
||||
# 2034| r2034_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 2034| r2034_3(unsigned long) = Constant[4] :
|
||||
# 2034| r2034_4(void *) = Call[operator new] : func:r2034_2, 0:r2034_3
|
||||
# 2034| mu2034_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2034| mu2034_6(unknown) = ^InitializeDynamicAllocation : &:r2034_4
|
||||
# 2034| r2034_7(int *) = Convert : r2034_4
|
||||
# 2034| mu2034_8(int *) = Store[x] : &:r2034_1, r2034_7
|
||||
# 2035| r2035_1(int) = Constant[6] :
|
||||
# 2035| r2035_2(glval<int *>) = VariableAddress[x] :
|
||||
# 2035| r2035_3(int *) = Load[x] : &:r2035_2, ~m?
|
||||
# 2035| r2035_4(glval<int>) = CopyValue : r2035_3
|
||||
# 2035| mu2035_5(int) = Store[?] : &:r2035_4, r2035_1
|
||||
# 2036| r2036_1(glval<unknown>) = FunctionAddress[operator delete] :
|
||||
# 2036| r2036_2(glval<int *>) = VariableAddress[x] :
|
||||
# 2036| r2036_3(int *) = Load[x] : &:r2036_2, ~m?
|
||||
# 2036| v2036_4(void) = Call[operator delete] : func:r2036_1, 0:r2036_3
|
||||
# 2036| mu2036_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2037| v2037_1(void) = NoOp :
|
||||
# 2033| v2033_4(void) = ReturnVoid :
|
||||
# 2033| v2033_5(void) = AliasedUse : ~m?
|
||||
# 2033| v2033_6(void) = ExitFunction :
|
||||
|
||||
# 2039| void Base2::Base2()
|
||||
# 2039| Block 0
|
||||
# 2039| v2039_1(void) = EnterFunction :
|
||||
# 2039| mu2039_2(unknown) = AliasedDefinition :
|
||||
# 2039| mu2039_3(unknown) = InitializeNonLocal :
|
||||
# 2039| r2039_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2039| mu2039_5(glval<Base2>) = InitializeParameter[#this] : &:r2039_4
|
||||
# 2039| r2039_6(glval<Base2>) = Load[#this] : &:r2039_4, ~m?
|
||||
# 2039| mu2039_7(Base2) = InitializeIndirection[#this] : &:r2039_6
|
||||
# 2039| v2039_8(void) = NoOp :
|
||||
# 2039| v2039_9(void) = ReturnIndirection[#this] : &:r2039_6, ~m?
|
||||
# 2039| v2039_10(void) = ReturnVoid :
|
||||
# 2039| v2039_11(void) = AliasedUse : ~m?
|
||||
# 2039| v2039_12(void) = ExitFunction :
|
||||
|
||||
# 2041| void Base2::operator delete(void*)
|
||||
# 2041| Block 0
|
||||
# 2041| v2041_1(void) = EnterFunction :
|
||||
# 2041| mu2041_2(unknown) = AliasedDefinition :
|
||||
# 2041| mu2041_3(unknown) = InitializeNonLocal :
|
||||
# 2041| r2041_4(glval<void *>) = VariableAddress[p] :
|
||||
# 2041| mu2041_5(void *) = InitializeParameter[p] : &:r2041_4
|
||||
# 2041| r2041_6(void *) = Load[p] : &:r2041_4, ~m?
|
||||
# 2041| mu2041_7(unknown) = InitializeIndirection[p] : &:r2041_6
|
||||
# 2042| v2042_1(void) = NoOp :
|
||||
# 2041| v2041_8(void) = ReturnIndirection[p] : &:r2041_6, ~m?
|
||||
# 2041| v2041_9(void) = ReturnVoid :
|
||||
# 2041| v2041_10(void) = AliasedUse : ~m?
|
||||
# 2041| v2041_11(void) = ExitFunction :
|
||||
|
||||
# 2043| void Base2::~Base2()
|
||||
# 2043| Block 0
|
||||
# 2043| v2043_1(void) = EnterFunction :
|
||||
# 2043| mu2043_2(unknown) = AliasedDefinition :
|
||||
# 2043| mu2043_3(unknown) = InitializeNonLocal :
|
||||
# 2043| r2043_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2043| mu2043_5(glval<Base2>) = InitializeParameter[#this] : &:r2043_4
|
||||
# 2043| r2043_6(glval<Base2>) = Load[#this] : &:r2043_4, ~m?
|
||||
# 2043| mu2043_7(Base2) = InitializeIndirection[#this] : &:r2043_6
|
||||
# 2043| v2043_8(void) = NoOp :
|
||||
# 2043| v2043_9(void) = ReturnIndirection[#this] : &:r2043_6, ~m?
|
||||
# 2043| v2043_10(void) = ReturnVoid :
|
||||
# 2043| v2043_11(void) = AliasedUse : ~m?
|
||||
# 2043| v2043_12(void) = ExitFunction :
|
||||
|
||||
# 2046| void Derived2::Derived2()
|
||||
# 2046| Block 0
|
||||
# 2046| v2046_1(void) = EnterFunction :
|
||||
# 2046| mu2046_2(unknown) = AliasedDefinition :
|
||||
# 2046| mu2046_3(unknown) = InitializeNonLocal :
|
||||
# 2046| r2046_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2046| mu2046_5(glval<Derived2>) = InitializeParameter[#this] : &:r2046_4
|
||||
# 2046| r2046_6(glval<Derived2>) = Load[#this] : &:r2046_4, ~m?
|
||||
# 2046| mu2046_7(Derived2) = InitializeIndirection[#this] : &:r2046_6
|
||||
# 2046| r2046_8(glval<Base2>) = ConvertToNonVirtualBase[Derived2 : Base2] : mu2046_5
|
||||
# 2046| r2046_9(glval<unknown>) = FunctionAddress[Base2] :
|
||||
# 2046| v2046_10(void) = Call[Base2] : func:r2046_9, this:r2046_8
|
||||
# 2046| mu2046_11(unknown) = ^CallSideEffect : ~m?
|
||||
# 2046| mu2046_12(Base2) = ^IndirectMayWriteSideEffect[-1] : &:r2046_8
|
||||
# 2046| v2046_13(void) = NoOp :
|
||||
# 2046| v2046_14(void) = ReturnIndirection[#this] : &:r2046_6, ~m?
|
||||
# 2046| v2046_15(void) = ReturnVoid :
|
||||
# 2046| v2046_16(void) = AliasedUse : ~m?
|
||||
# 2046| v2046_17(void) = ExitFunction :
|
||||
|
||||
# 2049| void Derived2::~Derived2()
|
||||
# 2049| Block 0
|
||||
# 2049| v2049_1(void) = EnterFunction :
|
||||
# 2049| mu2049_2(unknown) = AliasedDefinition :
|
||||
# 2049| mu2049_3(unknown) = InitializeNonLocal :
|
||||
# 2049| r2049_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 2049| mu2049_5(glval<Derived2>) = InitializeParameter[#this] : &:r2049_4
|
||||
# 2049| r2049_6(glval<Derived2>) = Load[#this] : &:r2049_4, ~m?
|
||||
# 2049| mu2049_7(Derived2) = InitializeIndirection[#this] : &:r2049_6
|
||||
# 2049| v2049_8(void) = NoOp :
|
||||
# 2049| r2049_9(glval<Base2>) = ConvertToNonVirtualBase[Derived2 : Base2] : mu2049_5
|
||||
# 2049| r2049_10(glval<unknown>) = FunctionAddress[~Base2] :
|
||||
# 2049| v2049_11(void) = Call[~Base2] : func:r2049_10, this:r2049_9
|
||||
# 2049| mu2049_12(unknown) = ^CallSideEffect : ~m?
|
||||
# 2049| v2049_13(void) = ReturnIndirection[#this] : &:r2049_6, ~m?
|
||||
# 2049| v2049_14(void) = ReturnVoid :
|
||||
# 2049| v2049_15(void) = AliasedUse : ~m?
|
||||
# 2049| v2049_16(void) = ExitFunction :
|
||||
|
||||
# 2051| void Derived2::operator delete(void*)
|
||||
# 2051| Block 0
|
||||
# 2051| v2051_1(void) = EnterFunction :
|
||||
# 2051| mu2051_2(unknown) = AliasedDefinition :
|
||||
# 2051| mu2051_3(unknown) = InitializeNonLocal :
|
||||
# 2051| r2051_4(glval<void *>) = VariableAddress[p] :
|
||||
# 2051| mu2051_5(void *) = InitializeParameter[p] : &:r2051_4
|
||||
# 2051| r2051_6(void *) = Load[p] : &:r2051_4, ~m?
|
||||
# 2051| mu2051_7(unknown) = InitializeIndirection[p] : &:r2051_6
|
||||
# 2052| v2052_1(void) = NoOp :
|
||||
# 2051| v2051_8(void) = ReturnIndirection[p] : &:r2051_6, ~m?
|
||||
# 2051| v2051_9(void) = ReturnVoid :
|
||||
# 2051| v2051_10(void) = AliasedUse : ~m?
|
||||
# 2051| v2051_11(void) = ExitFunction :
|
||||
|
||||
# 2056| int virtual_delete()
|
||||
# 2056| Block 0
|
||||
# 2056| v2056_1(void) = EnterFunction :
|
||||
# 2056| mu2056_2(unknown) = AliasedDefinition :
|
||||
# 2056| mu2056_3(unknown) = InitializeNonLocal :
|
||||
# 2058| r2058_1(glval<Base2 *>) = VariableAddress[b1] :
|
||||
# 2058| r2058_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 2058| r2058_3(unsigned long) = Constant[8] :
|
||||
# 2058| r2058_4(void *) = Call[operator new] : func:r2058_2, 0:r2058_3
|
||||
# 2058| mu2058_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2058| mu2058_6(unknown) = ^InitializeDynamicAllocation : &:r2058_4
|
||||
# 2058| r2058_7(Base2 *) = Convert : r2058_4
|
||||
# 2058| r2058_8(glval<unknown>) = FunctionAddress[Base2] :
|
||||
# 2058| v2058_9(void) = Call[Base2] : func:r2058_8, this:r2058_7
|
||||
# 2058| mu2058_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2058| mu2058_11(Base2) = ^IndirectMayWriteSideEffect[-1] : &:r2058_7
|
||||
# 2058| mu2058_12(Base2 *) = Store[b1] : &:r2058_1, r2058_7
|
||||
# 2059| r2059_1(glval<unknown>) = VirtualDeleteFunctionAddress :
|
||||
# 2059| r2059_2(glval<Base2 *>) = VariableAddress[b1] :
|
||||
# 2059| r2059_3(Base2 *) = Load[b1] : &:r2059_2, ~m?
|
||||
# 2059| v2059_4(void) = Call[?] : func:r2059_1, 0:r2059_3
|
||||
# 2059| mu2059_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2061| r2061_1(glval<Base2 *>) = VariableAddress[b2] :
|
||||
# 2061| r2061_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 2061| r2061_3(unsigned long) = Constant[16] :
|
||||
# 2061| r2061_4(void *) = Call[operator new] : func:r2061_2, 0:r2061_3
|
||||
# 2061| mu2061_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2061| mu2061_6(unknown) = ^InitializeDynamicAllocation : &:r2061_4
|
||||
# 2061| r2061_7(Derived2 *) = Convert : r2061_4
|
||||
# 2061| r2061_8(glval<unknown>) = FunctionAddress[Derived2] :
|
||||
# 2061| v2061_9(void) = Call[Derived2] : func:r2061_8, this:r2061_7
|
||||
# 2061| mu2061_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2061| mu2061_11(Derived2) = ^IndirectMayWriteSideEffect[-1] : &:r2061_7
|
||||
# 2061| r2061_12(Base2 *) = ConvertToNonVirtualBase[Derived2 : Base2] : r2061_7
|
||||
# 2061| mu2061_13(Base2 *) = Store[b2] : &:r2061_1, r2061_12
|
||||
# 2062| r2062_1(glval<unknown>) = VirtualDeleteFunctionAddress :
|
||||
# 2062| r2062_2(glval<Base2 *>) = VariableAddress[b2] :
|
||||
# 2062| r2062_3(Base2 *) = Load[b2] : &:r2062_2, ~m?
|
||||
# 2062| v2062_4(void) = Call[?] : func:r2062_1, 0:r2062_3
|
||||
# 2062| mu2062_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2064| r2064_1(glval<Derived2 *>) = VariableAddress[d] :
|
||||
# 2064| r2064_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 2064| r2064_3(unsigned long) = Constant[16] :
|
||||
# 2064| r2064_4(void *) = Call[operator new] : func:r2064_2, 0:r2064_3
|
||||
# 2064| mu2064_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2064| mu2064_6(unknown) = ^InitializeDynamicAllocation : &:r2064_4
|
||||
# 2064| r2064_7(Derived2 *) = Convert : r2064_4
|
||||
# 2064| r2064_8(glval<unknown>) = FunctionAddress[Derived2] :
|
||||
# 2064| v2064_9(void) = Call[Derived2] : func:r2064_8, this:r2064_7
|
||||
# 2064| mu2064_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2064| mu2064_11(Derived2) = ^IndirectMayWriteSideEffect[-1] : &:r2064_7
|
||||
# 2064| mu2064_12(Derived2 *) = Store[d] : &:r2064_1, r2064_7
|
||||
# 2065| r2065_1(glval<unknown>) = VirtualDeleteFunctionAddress :
|
||||
# 2065| r2065_2(glval<Derived2 *>) = VariableAddress[d] :
|
||||
# 2065| r2065_3(Derived2 *) = Load[d] : &:r2065_2, ~m?
|
||||
# 2065| v2065_4(void) = Call[?] : func:r2065_1, 0:r2065_3
|
||||
# 2065| mu2065_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2066| v2066_1(void) = Unreached :
|
||||
|
||||
# 2056| Block 1
|
||||
# 2056| r2056_4(glval<int>) = VariableAddress[#return] :
|
||||
# 2056| v2056_5(void) = ReturnValue : &:r2056_4, ~m?
|
||||
# 2056| v2056_6(void) = AliasedUse : ~m?
|
||||
# 2056| v2056_7(void) = ExitFunction :
|
||||
|
||||
# 2070| void test_constant_folding()
|
||||
# 2070| Block 0
|
||||
# 2070| v2070_1(void) = EnterFunction :
|
||||
# 2070| mu2070_2(unknown) = AliasedDefinition :
|
||||
# 2070| mu2070_3(unknown) = InitializeNonLocal :
|
||||
# 2071| r2071_1(glval<int>) = VariableAddress[x] :
|
||||
# 2071| r2071_2(int) = Constant[116] :
|
||||
# 2071| mu2071_3(int) = Store[x] : &:r2071_1, r2071_2
|
||||
# 2072| r2072_1(glval<unknown>) = FunctionAddress[test_constant_folding_use] :
|
||||
# 2072| r2072_2(int) = Constant[116] :
|
||||
# 2072| v2072_3(void) = Call[test_constant_folding_use] : func:r2072_1, 0:r2072_2
|
||||
# 2072| mu2072_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2073| v2073_1(void) = NoOp :
|
||||
# 2070| v2070_4(void) = ReturnVoid :
|
||||
# 2070| v2070_5(void) = AliasedUse : ~m?
|
||||
# 2070| v2070_6(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -10,7 +10,7 @@ void m(int i, bool cond, int x, int y) {
|
||||
|
||||
int seven = 7;
|
||||
if (mul % c2 == seven) {
|
||||
mod(mul); // congruent 3 mod 42, 7 mod 43
|
||||
mod(mul); // $ mod=0,3,42
|
||||
}
|
||||
|
||||
int j = cond
|
||||
@@ -19,13 +19,11 @@ void m(int i, bool cond, int x, int y) {
|
||||
mod(j); // $ mod=0,3,4
|
||||
|
||||
if (x % c1 == 3 && y % c1 == 7) {
|
||||
// Need implies_v2
|
||||
mod(x + y); // $ MISSING: 0,10,42
|
||||
mod(x + y); // $ mod=0,10,42
|
||||
}
|
||||
|
||||
if (x % c1 == 3 && y % c1 == 7) {
|
||||
// Need implies_v2
|
||||
mod(x - y); // $ MISSING: mod=0,38,42
|
||||
mod(x - y); // $ mod=0,38,42
|
||||
}
|
||||
|
||||
if (cond) {
|
||||
|
||||
@@ -1008,12 +1008,12 @@ label:
|
||||
|
||||
void test_overflow() {
|
||||
const int x = 2147483647; // 2^31-1
|
||||
range(x);
|
||||
range(x); // $ range===2147483647
|
||||
const int y = 256;
|
||||
range(y);
|
||||
range(y); // $ range===256
|
||||
if ((x + y) <= 512) {
|
||||
range(x);
|
||||
range(y);
|
||||
range(x); // $ range===2147483647
|
||||
range(y); // $ range===256
|
||||
range(x + y); // $ range===-2147483393
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ edges
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a |
|
||||
| test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a |
|
||||
| test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a |
|
||||
| test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... |
|
||||
| test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a |
|
||||
@@ -28,6 +29,8 @@ edges
|
||||
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
|
||||
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
|
||||
| test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a |
|
||||
| test_free.cpp:252:7:252:7 | p | test_free.cpp:255:10:255:10 | p |
|
||||
| test_free.cpp:260:9:260:9 | p | test_free.cpp:263:12:263:12 | p |
|
||||
nodes
|
||||
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
|
||||
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
|
||||
@@ -51,6 +54,8 @@ nodes
|
||||
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
|
||||
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
|
||||
| test_free.cpp:72:14:72:14 | a | semmle.label | a |
|
||||
| test_free.cpp:83:12:83:12 | a | semmle.label | a |
|
||||
| test_free.cpp:85:12:85:12 | a | semmle.label | a |
|
||||
| test_free.cpp:101:10:101:10 | a | semmle.label | a |
|
||||
| test_free.cpp:103:10:103:10 | a | semmle.label | a |
|
||||
| test_free.cpp:128:10:128:11 | * ... | semmle.label | * ... |
|
||||
@@ -63,6 +68,10 @@ nodes
|
||||
| test_free.cpp:207:10:207:10 | a | semmle.label | a |
|
||||
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
|
||||
| test_free.cpp:209:10:209:10 | a | semmle.label | a |
|
||||
| test_free.cpp:252:7:252:7 | p | semmle.label | p |
|
||||
| test_free.cpp:255:10:255:10 | p | semmle.label | p |
|
||||
| test_free.cpp:260:9:260:9 | p | semmle.label | p |
|
||||
| test_free.cpp:263:12:263:12 | p | semmle.label | p |
|
||||
subpaths
|
||||
#select
|
||||
| test_free.cpp:14:10:14:10 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:14:10:14:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
|
||||
@@ -84,6 +93,7 @@ subpaths
|
||||
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:85:12:85:12 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
|
||||
| test_free.cpp:103:10:103:10 | a | test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:101:5:101:8 | call to free | call to free |
|
||||
| test_free.cpp:129:10:129:11 | * ... | test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... | Memory pointed to by '* ...' may already have been freed by $@. | test_free.cpp:128:5:128:8 | call to free | call to free |
|
||||
| test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:152:22:152:25 | call to free | call to free |
|
||||
@@ -94,3 +104,5 @@ subpaths
|
||||
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free |
|
||||
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free |
|
||||
| test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free |
|
||||
| test_free.cpp:255:10:255:10 | p | test_free.cpp:252:7:252:7 | p | test_free.cpp:255:10:255:10 | p | Memory pointed to by 'p' may already have been freed by $@. | test_free.cpp:252:2:252:5 | call to free | call to free |
|
||||
| test_free.cpp:263:12:263:12 | p | test_free.cpp:260:9:260:9 | p | test_free.cpp:263:12:263:12 | p | Memory pointed to by 'p' may already have been freed by $@. | test_free.cpp:260:2:260:9 | delete | delete |
|
||||
|
||||
@@ -92,6 +92,10 @@
|
||||
| test_free.cpp:233:14:233:15 | * ... |
|
||||
| test_free.cpp:239:14:239:15 | * ... |
|
||||
| test_free.cpp:245:10:245:11 | * ... |
|
||||
| test_free.cpp:252:7:252:7 | p |
|
||||
| test_free.cpp:255:10:255:10 | p |
|
||||
| test_free.cpp:260:9:260:9 | p |
|
||||
| test_free.cpp:263:12:263:12 | p |
|
||||
| virtual.cpp:18:10:18:10 | a |
|
||||
| virtual.cpp:19:10:19:10 | c |
|
||||
| virtual.cpp:38:10:38:10 | b |
|
||||
|
||||
@@ -12,3 +12,5 @@
|
||||
| test.cpp:157:3:157:26 | new[] | This memory is never freed. |
|
||||
| test.cpp:169:14:169:19 | call to strdup | This memory is never freed. |
|
||||
| test_free.cpp:167:15:167:21 | call to realloc | This memory is never freed. |
|
||||
| test_free.cpp:253:14:253:19 | call to malloc | This memory is never freed. |
|
||||
| test_free.cpp:261:6:261:12 | new | This memory is never freed. |
|
||||
|
||||
@@ -9,6 +9,7 @@ edges
|
||||
| test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a |
|
||||
| test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a |
|
||||
| test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a |
|
||||
| test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a |
|
||||
| test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a |
|
||||
| test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a |
|
||||
@@ -27,6 +28,8 @@ edges
|
||||
| test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... |
|
||||
| test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... |
|
||||
| test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... |
|
||||
| test_free.cpp:252:7:252:7 | p | test_free.cpp:254:6:254:6 | p |
|
||||
| test_free.cpp:260:9:260:9 | p | test_free.cpp:262:6:262:6 | p |
|
||||
nodes
|
||||
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
|
||||
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
|
||||
@@ -41,6 +44,8 @@ nodes
|
||||
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
|
||||
| test_free.cpp:69:10:69:10 | a | semmle.label | a |
|
||||
| test_free.cpp:71:9:71:9 | a | semmle.label | a |
|
||||
| test_free.cpp:83:12:83:12 | a | semmle.label | a |
|
||||
| test_free.cpp:84:5:84:5 | a | semmle.label | a |
|
||||
| test_free.cpp:90:10:90:10 | a | semmle.label | a |
|
||||
| test_free.cpp:90:10:90:10 | a | semmle.label | a |
|
||||
| test_free.cpp:91:5:91:5 | a | semmle.label | a |
|
||||
@@ -63,6 +68,10 @@ nodes
|
||||
| test_free.cpp:245:10:245:11 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... |
|
||||
| test_free.cpp:252:7:252:7 | p | semmle.label | p |
|
||||
| test_free.cpp:254:6:254:6 | p | semmle.label | p |
|
||||
| test_free.cpp:260:9:260:9 | p | semmle.label | p |
|
||||
| test_free.cpp:262:6:262:6 | p | semmle.label | p |
|
||||
subpaths
|
||||
#select
|
||||
| test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
|
||||
@@ -75,6 +84,7 @@ subpaths
|
||||
| test_free.cpp:45:5:45:5 | a | test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:44:22:44:25 | call to free | call to free |
|
||||
| test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free |
|
||||
| test_free.cpp:84:5:84:5 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a | Memory may have been previously freed by $@. | test_free.cpp:83:5:83:13 | delete | delete |
|
||||
| test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free |
|
||||
| test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free |
|
||||
| test_free.cpp:96:9:96:9 | a | test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a | Memory may have been previously freed by $@. | test_free.cpp:95:5:95:8 | call to free | call to free |
|
||||
@@ -93,3 +103,5 @@ subpaths
|
||||
| test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free |
|
||||
| test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free |
|
||||
| test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free |
|
||||
| test_free.cpp:254:6:254:6 | p | test_free.cpp:252:7:252:7 | p | test_free.cpp:254:6:254:6 | p | Memory may have been previously freed by $@. | test_free.cpp:252:2:252:5 | call to free | call to free |
|
||||
| test_free.cpp:262:6:262:6 | p | test_free.cpp:260:9:260:9 | p | test_free.cpp:262:6:262:6 | p | Memory may have been previously freed by $@. | test_free.cpp:260:2:260:9 | delete | delete |
|
||||
|
||||
@@ -81,8 +81,8 @@ public:
|
||||
void test_new1() {
|
||||
A *a = new A();
|
||||
delete(a);
|
||||
a->f(); // BAD [NOT DETECTED]
|
||||
delete(a); // BAD [NOT DETECTED]
|
||||
a->f(); // BAD
|
||||
delete(a); // BAD
|
||||
}
|
||||
|
||||
void test_dereference1(A *a) {
|
||||
@@ -244,4 +244,21 @@ void test_loop3(char ** a, char ** b) {
|
||||
void test_deref(char **a) {
|
||||
free(*a);
|
||||
use(*a); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
// Refs
|
||||
|
||||
void test_ref(char *&p) {
|
||||
free(p);
|
||||
p = (char *)malloc(sizeof(char)*10);
|
||||
use(p); // GOOD [FALSE POSITIVE]
|
||||
free(p); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
|
||||
void test_ref_delete(int *&p) {
|
||||
delete p;
|
||||
p = new int;
|
||||
use(p); // GOOD [FALSE POSITIVE]
|
||||
delete p; // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
@@ -156,3 +156,10 @@ void fmt_via_strcpy(char *data) {
|
||||
strcpy(data, "some string");
|
||||
printf(data); // BAD
|
||||
}
|
||||
|
||||
void fmt_with_assignment() {
|
||||
const char *x, *y;
|
||||
|
||||
x = y = "a";
|
||||
printf(y); // GOOD
|
||||
}
|
||||
|
||||
@@ -6,3 +6,5 @@
|
||||
| test.cpp:39:23:39:28 | ... == ... | This '==' operator has no effect. The assignment ('=') operator was probably intended. |
|
||||
| test.cpp:42:23:42:28 | ... == ... | This '==' operator has no effect. The assignment ('=') operator was probably intended. |
|
||||
| test.cpp:51:13:51:13 | call to operator== | This '==' operator has no effect. The assignment ('=') operator was probably intended. |
|
||||
| test.cpp:72:3:72:8 | ... == ... | This '==' operator has no effect. The assignment ('=') operator was probably intended. |
|
||||
| test.cpp:73:3:73:12 | ... == ... | This '==' operator has no effect. The assignment ('=') operator was probably intended. |
|
||||
|
||||
@@ -61,3 +61,14 @@ template<typename T1, typename T2>
|
||||
auto sfinaeTrick(T1 x1, T2 x2) -> decltype(x1 == x2, bool()) { // GOOD
|
||||
return x1 == x2;
|
||||
}
|
||||
|
||||
void report_error(const char*);
|
||||
|
||||
#define DOES_NOT_THROW(E) do { try { E; } catch (...) { report_error(""); } } while(0)
|
||||
#define ID(X) (X)
|
||||
|
||||
void test_inside_macro_expansion(int x, int y) {
|
||||
DOES_NOT_THROW(x == y); // GOOD
|
||||
x == y; // BAD
|
||||
x == ID(y); // BAD
|
||||
}
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
edges
|
||||
| test.c:8:27:8:30 | argv | test.c:17:11:17:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection |
|
||||
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection |
|
||||
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection |
|
||||
nodes
|
||||
| test.c:8:27:8:30 | argv | semmle.label | argv |
|
||||
| test.c:8:27:8:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.c:8:27:8:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
|
||||
| test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection |
|
||||
@@ -21,12 +15,8 @@ nodes
|
||||
| test.c:57:10:57:16 | access to array indirection | semmle.label | access to array indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv | user input (a command-line argument) |
|
||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) |
|
||||
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) |
|
||||
| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
edges
|
||||
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
||||
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
||||
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
|
||||
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
|
||||
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:45:22:52 | userName indirection |
|
||||
| test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:50:35:50:43 | envCflags indirection |
|
||||
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection |
|
||||
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument |
|
||||
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:35:50:43 | envCflags indirection |
|
||||
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection |
|
||||
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection |
|
||||
| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument |
|
||||
@@ -71,7 +72,6 @@ edges
|
||||
| test.cpp:220:19:220:26 | filename indirection | test.cpp:220:19:220:26 | filename indirection |
|
||||
nodes
|
||||
| test.cpp:15:27:15:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:15:27:15:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:22:13:22:20 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:22:45:22:52 | userName indirection | semmle.label | userName indirection |
|
||||
| test.cpp:23:12:23:19 | command1 indirection | semmle.label | command1 indirection |
|
||||
@@ -154,7 +154,6 @@ subpaths
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
#select
|
||||
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | argv indirection | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | argv indirection | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | argv indirection | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | argv indirection | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:51:10:51:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:47:21:47:26 | call to getenv indirection | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (string read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (string read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument |
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
edges
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
||||
subpaths
|
||||
| test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection |
|
||||
nodes
|
||||
| test.c:15:20:15:23 | argv | semmle.label | argv |
|
||||
| test.c:15:20:15:23 | argv | semmle.label | argv |
|
||||
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
|
||||
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
|
||||
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
|
||||
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
|
||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
||||
| test.c:14:27:14:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
|
||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:15:20:15:23 | argv | user input (argv) |
|
||||
| test.cpp:43:27:43:33 | access to array | test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:43:27:43:30 | argv | user input (argv) |
|
||||
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
|
||||
@@ -4,38 +4,29 @@ edges
|
||||
| test.cpp:18:10:18:15 | str indirection [post update] [string] | test.cpp:19:5:19:7 | str indirection [string] |
|
||||
| test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... |
|
||||
| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:16:11:16:21 | mk_string_t indirection [string] |
|
||||
| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:19:5:19:7 | str indirection [string] |
|
||||
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:42:13:42:15 | str indirection [string] |
|
||||
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:72:17:72:19 | str indirection [string] |
|
||||
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:80:17:80:19 | str indirection [string] |
|
||||
| test.cpp:42:13:42:15 | str indirection [string] | test.cpp:42:18:42:23 | string |
|
||||
| test.cpp:42:13:42:15 | str indirection [string] | test.cpp:42:18:42:23 | string indirection |
|
||||
| test.cpp:42:18:42:23 | string indirection | test.cpp:42:18:42:23 | string |
|
||||
| test.cpp:72:17:72:19 | str indirection [string] | test.cpp:72:22:72:27 | string |
|
||||
| test.cpp:72:17:72:19 | str indirection [string] | test.cpp:72:22:72:27 | string indirection |
|
||||
| test.cpp:72:22:72:27 | string indirection | test.cpp:72:22:72:27 | string |
|
||||
| test.cpp:80:17:80:19 | str indirection [string] | test.cpp:80:22:80:27 | string |
|
||||
| test.cpp:80:17:80:19 | str indirection [string] | test.cpp:80:22:80:27 | string indirection |
|
||||
| test.cpp:80:22:80:27 | string indirection | test.cpp:80:22:80:27 | string |
|
||||
| test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] | test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] |
|
||||
| test.cpp:90:5:90:34 | ... = ... | test.cpp:90:10:90:15 | str indirection [post update] [string] |
|
||||
| test.cpp:90:10:90:15 | str indirection [post update] [string] | test.cpp:91:5:91:7 | str indirection [string] |
|
||||
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... |
|
||||
| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] |
|
||||
| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:91:5:91:7 | str indirection [string] |
|
||||
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:99:13:99:15 | str indirection [string] |
|
||||
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:129:17:129:19 | str indirection [string] |
|
||||
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:137:17:137:19 | str indirection [string] |
|
||||
| test.cpp:99:13:99:15 | str indirection [string] | test.cpp:99:18:99:23 | string |
|
||||
| test.cpp:99:13:99:15 | str indirection [string] | test.cpp:99:18:99:23 | string indirection |
|
||||
| test.cpp:99:18:99:23 | string indirection | test.cpp:99:18:99:23 | string |
|
||||
| test.cpp:129:17:129:19 | str indirection [string] | test.cpp:129:22:129:27 | string |
|
||||
| test.cpp:129:17:129:19 | str indirection [string] | test.cpp:129:22:129:27 | string indirection |
|
||||
| test.cpp:129:22:129:27 | string indirection | test.cpp:129:22:129:27 | string |
|
||||
| test.cpp:137:17:137:19 | str indirection [string] | test.cpp:137:22:137:27 | string |
|
||||
| test.cpp:137:17:137:19 | str indirection [string] | test.cpp:137:22:137:27 | string indirection |
|
||||
| test.cpp:137:22:137:27 | string indirection | test.cpp:137:22:137:27 | string |
|
||||
| test.cpp:147:5:147:34 | ... = ... | test.cpp:147:10:147:15 | str indirection [post update] [string] |
|
||||
| test.cpp:147:10:147:15 | str indirection [post update] [string] | test.cpp:148:5:148:7 | str indirection [string] |
|
||||
| test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... |
|
||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:148:5:148:7 | str indirection [string] |
|
||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:152:13:152:15 | str indirection [string] |
|
||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:154:13:154:15 | str indirection [string] |
|
||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:156:13:156:15 | str indirection [string] |
|
||||
@@ -46,32 +37,14 @@ edges
|
||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:203:17:203:19 | str indirection [string] |
|
||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:207:17:207:19 | str indirection [string] |
|
||||
| test.cpp:152:13:152:15 | str indirection [string] | test.cpp:152:18:152:23 | string |
|
||||
| test.cpp:152:13:152:15 | str indirection [string] | test.cpp:152:18:152:23 | string indirection |
|
||||
| test.cpp:152:18:152:23 | string indirection | test.cpp:152:18:152:23 | string |
|
||||
| test.cpp:154:13:154:15 | str indirection [string] | test.cpp:154:18:154:23 | string |
|
||||
| test.cpp:154:13:154:15 | str indirection [string] | test.cpp:154:18:154:23 | string indirection |
|
||||
| test.cpp:154:18:154:23 | string indirection | test.cpp:154:18:154:23 | string |
|
||||
| test.cpp:156:13:156:15 | str indirection [string] | test.cpp:156:18:156:23 | string |
|
||||
| test.cpp:156:13:156:15 | str indirection [string] | test.cpp:156:18:156:23 | string indirection |
|
||||
| test.cpp:156:18:156:23 | string indirection | test.cpp:156:18:156:23 | string |
|
||||
| test.cpp:175:17:175:19 | str indirection [string] | test.cpp:175:22:175:27 | string |
|
||||
| test.cpp:175:17:175:19 | str indirection [string] | test.cpp:175:22:175:27 | string indirection |
|
||||
| test.cpp:175:22:175:27 | string indirection | test.cpp:175:22:175:27 | string |
|
||||
| test.cpp:187:17:187:19 | str indirection [string] | test.cpp:187:22:187:27 | string |
|
||||
| test.cpp:187:17:187:19 | str indirection [string] | test.cpp:187:22:187:27 | string indirection |
|
||||
| test.cpp:187:22:187:27 | string indirection | test.cpp:187:22:187:27 | string |
|
||||
| test.cpp:195:17:195:19 | str indirection [string] | test.cpp:195:22:195:27 | string |
|
||||
| test.cpp:195:17:195:19 | str indirection [string] | test.cpp:195:22:195:27 | string indirection |
|
||||
| test.cpp:195:22:195:27 | string indirection | test.cpp:195:22:195:27 | string |
|
||||
| test.cpp:199:17:199:19 | str indirection [string] | test.cpp:199:22:199:27 | string |
|
||||
| test.cpp:199:17:199:19 | str indirection [string] | test.cpp:199:22:199:27 | string indirection |
|
||||
| test.cpp:199:22:199:27 | string indirection | test.cpp:199:22:199:27 | string |
|
||||
| test.cpp:203:17:203:19 | str indirection [string] | test.cpp:203:22:203:27 | string |
|
||||
| test.cpp:203:17:203:19 | str indirection [string] | test.cpp:203:22:203:27 | string indirection |
|
||||
| test.cpp:203:22:203:27 | string indirection | test.cpp:203:22:203:27 | string |
|
||||
| test.cpp:207:17:207:19 | str indirection [string] | test.cpp:207:22:207:27 | string |
|
||||
| test.cpp:207:17:207:19 | str indirection [string] | test.cpp:207:22:207:27 | string indirection |
|
||||
| test.cpp:207:22:207:27 | string indirection | test.cpp:207:22:207:27 | string |
|
||||
| test.cpp:214:24:214:24 | p | test.cpp:216:10:216:10 | p |
|
||||
| test.cpp:220:43:220:48 | call to malloc | test.cpp:222:15:222:20 | buffer |
|
||||
| test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p |
|
||||
@@ -83,8 +56,6 @@ edges
|
||||
| test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer |
|
||||
| test.cpp:242:22:242:27 | buffer | test.cpp:242:16:242:19 | set_string output argument [string] |
|
||||
| test.cpp:243:12:243:14 | str indirection [string] | test.cpp:243:12:243:21 | string |
|
||||
| test.cpp:243:12:243:14 | str indirection [string] | test.cpp:243:16:243:21 | string indirection |
|
||||
| test.cpp:243:16:243:21 | string indirection | test.cpp:243:12:243:21 | string |
|
||||
| test.cpp:249:20:249:27 | call to my_alloc | test.cpp:250:12:250:12 | p |
|
||||
| test.cpp:256:17:256:22 | call to malloc | test.cpp:257:12:257:12 | p |
|
||||
| test.cpp:262:22:262:27 | call to malloc | test.cpp:266:12:266:12 | p |
|
||||
@@ -98,13 +69,10 @@ nodes
|
||||
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | semmle.label | call to mk_string_t indirection [string] |
|
||||
| test.cpp:42:13:42:15 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:42:18:42:23 | string | semmle.label | string |
|
||||
| test.cpp:42:18:42:23 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:72:17:72:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:72:22:72:27 | string | semmle.label | string |
|
||||
| test.cpp:72:22:72:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:80:17:80:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:80:22:80:27 | string | semmle.label | string |
|
||||
| test.cpp:80:22:80:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] | semmle.label | mk_string_t_plus_one indirection [string] |
|
||||
| test.cpp:90:5:90:34 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:90:10:90:15 | str indirection [post update] [string] | semmle.label | str indirection [post update] [string] |
|
||||
@@ -113,44 +81,32 @@ nodes
|
||||
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | semmle.label | call to mk_string_t_plus_one indirection [string] |
|
||||
| test.cpp:99:13:99:15 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:99:18:99:23 | string | semmle.label | string |
|
||||
| test.cpp:99:18:99:23 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:129:17:129:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:129:22:129:27 | string | semmle.label | string |
|
||||
| test.cpp:129:22:129:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:137:17:137:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:137:22:137:27 | string | semmle.label | string |
|
||||
| test.cpp:137:22:137:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:147:5:147:34 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:147:10:147:15 | str indirection [post update] [string] | semmle.label | str indirection [post update] [string] |
|
||||
| test.cpp:147:19:147:24 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:148:5:148:7 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:152:13:152:15 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:152:18:152:23 | string | semmle.label | string |
|
||||
| test.cpp:152:18:152:23 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:154:13:154:15 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:154:18:154:23 | string | semmle.label | string |
|
||||
| test.cpp:154:18:154:23 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:156:13:156:15 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:156:18:156:23 | string | semmle.label | string |
|
||||
| test.cpp:156:18:156:23 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:175:17:175:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:175:22:175:27 | string | semmle.label | string |
|
||||
| test.cpp:175:22:175:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:187:17:187:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:187:22:187:27 | string | semmle.label | string |
|
||||
| test.cpp:187:22:187:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:195:17:195:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:195:22:195:27 | string | semmle.label | string |
|
||||
| test.cpp:195:22:195:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:199:17:199:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:199:22:199:27 | string | semmle.label | string |
|
||||
| test.cpp:199:22:199:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:203:17:203:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:203:22:203:27 | string | semmle.label | string |
|
||||
| test.cpp:203:22:203:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:207:17:207:19 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:207:22:207:27 | string | semmle.label | string |
|
||||
| test.cpp:207:22:207:27 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:214:24:214:24 | p | semmle.label | p |
|
||||
| test.cpp:216:10:216:10 | p | semmle.label | p |
|
||||
| test.cpp:220:43:220:48 | call to malloc | semmle.label | call to malloc |
|
||||
@@ -165,7 +121,6 @@ nodes
|
||||
| test.cpp:242:22:242:27 | buffer | semmle.label | buffer |
|
||||
| test.cpp:243:12:243:14 | str indirection [string] | semmle.label | str indirection [string] |
|
||||
| test.cpp:243:12:243:21 | string | semmle.label | string |
|
||||
| test.cpp:243:16:243:21 | string indirection | semmle.label | string indirection |
|
||||
| test.cpp:249:20:249:27 | call to my_alloc | semmle.label | call to my_alloc |
|
||||
| test.cpp:250:12:250:12 | p | semmle.label | p |
|
||||
| test.cpp:256:17:256:22 | call to malloc | semmle.label | call to malloc |
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
edges
|
||||
| main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection |
|
||||
| main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
||||
| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection |
|
||||
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:9:53:12 | memcpy output argument |
|
||||
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src indirection |
|
||||
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src indirection |
|
||||
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
|
||||
| overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
|
||||
| overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
|
||||
| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 indirection |
|
||||
| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 indirection |
|
||||
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | src indirection |
|
||||
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | src indirection |
|
||||
| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | src indirection |
|
||||
@@ -24,23 +17,17 @@ edges
|
||||
| overflowdestination.cpp:76:30:76:32 | src indirection | overflowdestination.cpp:57:52:57:54 | src indirection |
|
||||
nodes
|
||||
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
|
||||
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection |
|
||||
| main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection |
|
||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection |
|
||||
| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
|
||||
| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
|
||||
| overflowdestination.cpp:43:8:43:10 | fgets output argument | semmle.label | fgets output argument |
|
||||
| overflowdestination.cpp:46:15:46:17 | src indirection | semmle.label | src indirection |
|
||||
| overflowdestination.cpp:50:52:50:54 | src indirection | semmle.label | src indirection |
|
||||
| overflowdestination.cpp:53:9:53:12 | memcpy output argument | semmle.label | memcpy output argument |
|
||||
| overflowdestination.cpp:53:15:53:17 | src indirection | semmle.label | src indirection |
|
||||
| overflowdestination.cpp:53:15:53:17 | src indirection | semmle.label | src indirection |
|
||||
| overflowdestination.cpp:54:9:54:12 | memcpy output argument | semmle.label | memcpy output argument |
|
||||
| overflowdestination.cpp:57:52:57:54 | src indirection | semmle.label | src indirection |
|
||||
| overflowdestination.cpp:64:16:64:19 | src2 indirection | semmle.label | src2 indirection |
|
||||
| overflowdestination.cpp:64:16:64:19 | src2 indirection | semmle.label | src2 indirection |
|
||||
| overflowdestination.cpp:73:8:73:10 | fgets output argument | semmle.label | fgets output argument |
|
||||
| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | semmle.label | overflowdest_test2 output argument |
|
||||
| overflowdestination.cpp:75:30:75:32 | src indirection | semmle.label | src indirection |
|
||||
@@ -50,11 +37,6 @@ subpaths
|
||||
| overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument |
|
||||
#select
|
||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:46:2:46:7 | call to memcpy | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:64:2:64:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:64:16:64:19 | src2 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
| overflowdestination.cpp:64:2:64:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:64:16:64:19 | src2 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
edges
|
||||
| test1.c:7:26:7:29 | argv | test1.c:9:9:9:9 | i |
|
||||
| test1.c:7:26:7:29 | argv | test1.c:11:9:11:9 | i |
|
||||
| test1.c:7:26:7:29 | argv | test1.c:13:9:13:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:9:9:9:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:9:9:9:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:11:9:11:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:11:9:11:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:13:9:13:9 | i |
|
||||
| test1.c:7:26:7:29 | argv indirection | test1.c:13:9:13:9 | i |
|
||||
| test1.c:9:9:9:9 | i | test1.c:16:16:16:16 | i |
|
||||
| test1.c:11:9:11:9 | i | test1.c:32:16:32:16 | i |
|
||||
@@ -15,8 +9,6 @@ edges
|
||||
| test1.c:32:16:32:16 | i | test1.c:33:11:33:11 | i |
|
||||
| test1.c:48:16:48:16 | i | test1.c:53:15:53:15 | j |
|
||||
nodes
|
||||
| test1.c:7:26:7:29 | argv | semmle.label | argv |
|
||||
| test1.c:7:26:7:29 | argv indirection | semmle.label | argv indirection |
|
||||
| test1.c:7:26:7:29 | argv indirection | semmle.label | argv indirection |
|
||||
| test1.c:9:9:9:9 | i | semmle.label | i |
|
||||
| test1.c:11:9:11:9 | i | semmle.label | i |
|
||||
@@ -29,12 +21,6 @@ nodes
|
||||
| test1.c:53:15:53:15 | j | semmle.label | j |
|
||||
subpaths
|
||||
#select
|
||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv indirection | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv indirection | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv indirection | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv indirection | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv indirection | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv indirection | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
edges
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:43:38:43:44 | tainted |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:44:38:44:63 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:46:38:46:63 | ... + ... |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:49:32:49:35 | size |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:50:26:50:29 | size |
|
||||
| test.cpp:39:27:39:30 | argv | test.cpp:53:35:53:60 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... |
|
||||
| test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... |
|
||||
| test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... |
|
||||
@@ -47,8 +35,6 @@ edges
|
||||
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:355:35:355:38 | size |
|
||||
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:356:35:356:38 | size |
|
||||
nodes
|
||||
| test.cpp:39:27:39:30 | argv | semmle.label | argv |
|
||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.cpp:43:38:43:44 | tainted | semmle.label | tainted |
|
||||
| test.cpp:44:38:44:63 | ... * ... | semmle.label | ... * ... |
|
||||
@@ -92,23 +78,11 @@ nodes
|
||||
| test.cpp:356:35:356:38 | size | semmle.label | size |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:23 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:31 | call to getenv indirection | user input (an environment variable) |
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
testFailures
|
||||
failures
|
||||
@@ -45,58 +45,6 @@ edges
|
||||
| test.cpp:53:5:53:23 | ... = ... | test.cpp:51:33:51:35 | end |
|
||||
| test.cpp:53:12:53:23 | ... + ... | test.cpp:53:5:53:23 | ... = ... |
|
||||
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:67:9:67:14 | ... = ... |
|
||||
| test.cpp:80:9:80:16 | mk_array indirection [end] | test.cpp:89:19:89:26 | call to mk_array [end] |
|
||||
| test.cpp:80:9:80:16 | mk_array indirection [end] | test.cpp:119:18:119:25 | call to mk_array [end] |
|
||||
| test.cpp:82:5:82:28 | ... = ... | test.cpp:82:9:82:13 | arr indirection [post update] [begin] |
|
||||
| test.cpp:82:9:82:13 | arr indirection [post update] [begin] | test.cpp:83:15:83:17 | arr indirection [begin] |
|
||||
| test.cpp:82:17:82:22 | call to malloc | test.cpp:82:5:82:28 | ... = ... |
|
||||
| test.cpp:83:5:83:30 | ... = ... | test.cpp:83:9:83:11 | arr indirection [post update] [end] |
|
||||
| test.cpp:83:9:83:11 | arr indirection [post update] [end] | test.cpp:80:9:80:16 | mk_array indirection [end] |
|
||||
| test.cpp:83:15:83:17 | arr indirection [begin] | test.cpp:83:19:83:23 | begin indirection |
|
||||
| test.cpp:83:15:83:30 | ... + ... | test.cpp:83:5:83:30 | ... = ... |
|
||||
| test.cpp:83:19:83:23 | begin indirection | test.cpp:83:5:83:30 | ... = ... |
|
||||
| test.cpp:83:19:83:23 | begin indirection | test.cpp:83:15:83:30 | ... + ... |
|
||||
| test.cpp:89:19:89:26 | call to mk_array [end] | test.cpp:91:36:91:38 | arr indirection [end] |
|
||||
| test.cpp:89:19:89:26 | call to mk_array [end] | test.cpp:95:36:95:38 | arr indirection [end] |
|
||||
| test.cpp:91:36:91:38 | arr indirection [end] | test.cpp:91:40:91:42 | end indirection |
|
||||
| test.cpp:91:36:91:38 | arr indirection [end] | test.cpp:96:9:96:14 | ... = ... |
|
||||
| test.cpp:91:40:91:42 | end indirection | test.cpp:96:9:96:14 | ... = ... |
|
||||
| test.cpp:95:36:95:38 | arr indirection [end] | test.cpp:95:40:95:42 | end indirection |
|
||||
| test.cpp:95:36:95:38 | arr indirection [end] | test.cpp:96:9:96:14 | ... = ... |
|
||||
| test.cpp:95:40:95:42 | end indirection | test.cpp:96:9:96:14 | ... = ... |
|
||||
| test.cpp:104:27:104:29 | arr [end] | test.cpp:105:36:105:38 | arr indirection [end] |
|
||||
| test.cpp:104:27:104:29 | arr [end] | test.cpp:109:36:109:38 | arr indirection [end] |
|
||||
| test.cpp:105:36:105:38 | arr indirection [end] | test.cpp:105:40:105:42 | end indirection |
|
||||
| test.cpp:105:36:105:38 | arr indirection [end] | test.cpp:110:9:110:14 | ... = ... |
|
||||
| test.cpp:105:40:105:42 | end indirection | test.cpp:110:9:110:14 | ... = ... |
|
||||
| test.cpp:109:36:109:38 | arr indirection [end] | test.cpp:109:40:109:42 | end indirection |
|
||||
| test.cpp:109:36:109:38 | arr indirection [end] | test.cpp:110:9:110:14 | ... = ... |
|
||||
| test.cpp:109:40:109:42 | end indirection | test.cpp:110:9:110:14 | ... = ... |
|
||||
| test.cpp:119:18:119:25 | call to mk_array [end] | test.cpp:104:27:104:29 | arr [end] |
|
||||
| test.cpp:141:10:141:19 | mk_array_p indirection [end] | test.cpp:150:20:150:29 | call to mk_array_p indirection [end] |
|
||||
| test.cpp:141:10:141:19 | mk_array_p indirection [end] | test.cpp:180:19:180:28 | call to mk_array_p indirection [end] |
|
||||
| test.cpp:143:5:143:29 | ... = ... | test.cpp:143:10:143:14 | arr indirection [post update] [begin] |
|
||||
| test.cpp:143:10:143:14 | arr indirection [post update] [begin] | test.cpp:144:16:144:18 | arr indirection [begin] |
|
||||
| test.cpp:143:18:143:23 | call to malloc | test.cpp:143:5:143:29 | ... = ... |
|
||||
| test.cpp:144:5:144:32 | ... = ... | test.cpp:144:10:144:12 | arr indirection [post update] [end] |
|
||||
| test.cpp:144:10:144:12 | arr indirection [post update] [end] | test.cpp:141:10:141:19 | mk_array_p indirection [end] |
|
||||
| test.cpp:144:16:144:18 | arr indirection [begin] | test.cpp:144:21:144:25 | begin indirection |
|
||||
| test.cpp:144:16:144:32 | ... + ... | test.cpp:144:5:144:32 | ... = ... |
|
||||
| test.cpp:144:21:144:25 | begin indirection | test.cpp:144:5:144:32 | ... = ... |
|
||||
| test.cpp:144:21:144:25 | begin indirection | test.cpp:144:16:144:32 | ... + ... |
|
||||
| test.cpp:150:20:150:29 | call to mk_array_p indirection [end] | test.cpp:156:37:156:39 | arr indirection [end] |
|
||||
| test.cpp:156:37:156:39 | arr indirection [end] | test.cpp:156:42:156:44 | end indirection |
|
||||
| test.cpp:156:37:156:39 | arr indirection [end] | test.cpp:157:9:157:14 | ... = ... |
|
||||
| test.cpp:156:42:156:44 | end indirection | test.cpp:157:9:157:14 | ... = ... |
|
||||
| test.cpp:165:29:165:31 | arr indirection [end] | test.cpp:166:37:166:39 | arr indirection [end] |
|
||||
| test.cpp:165:29:165:31 | arr indirection [end] | test.cpp:170:37:170:39 | arr indirection [end] |
|
||||
| test.cpp:166:37:166:39 | arr indirection [end] | test.cpp:166:42:166:44 | end indirection |
|
||||
| test.cpp:166:37:166:39 | arr indirection [end] | test.cpp:171:9:171:14 | ... = ... |
|
||||
| test.cpp:166:42:166:44 | end indirection | test.cpp:171:9:171:14 | ... = ... |
|
||||
| test.cpp:170:37:170:39 | arr indirection [end] | test.cpp:170:42:170:44 | end indirection |
|
||||
| test.cpp:170:37:170:39 | arr indirection [end] | test.cpp:171:9:171:14 | ... = ... |
|
||||
| test.cpp:170:42:170:44 | end indirection | test.cpp:171:9:171:14 | ... = ... |
|
||||
| test.cpp:180:19:180:28 | call to mk_array_p indirection [end] | test.cpp:165:29:165:31 | arr indirection [end] |
|
||||
| test.cpp:194:23:194:28 | call to malloc | test.cpp:195:17:195:23 | ... + ... |
|
||||
| test.cpp:194:23:194:28 | call to malloc | test.cpp:195:17:195:23 | ... + ... |
|
||||
| test.cpp:194:23:194:28 | call to malloc | test.cpp:201:5:201:19 | ... = ... |
|
||||
@@ -233,6 +181,18 @@ edges
|
||||
| test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array |
|
||||
| test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array |
|
||||
| test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array |
|
||||
| test.cpp:792:60:792:62 | end | test.cpp:800:40:800:43 | mk_array_no_field_flow output argument |
|
||||
| test.cpp:792:60:792:62 | end | test.cpp:832:40:832:43 | mk_array_no_field_flow output argument |
|
||||
| test.cpp:793:14:793:19 | call to malloc | test.cpp:794:5:794:24 | ... = ... |
|
||||
| test.cpp:793:14:793:19 | call to malloc | test.cpp:794:12:794:24 | ... + ... |
|
||||
| test.cpp:794:5:794:24 | ... = ... | test.cpp:792:60:792:62 | end |
|
||||
| test.cpp:794:12:794:24 | ... + ... | test.cpp:794:5:794:24 | ... = ... |
|
||||
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | test.cpp:807:7:807:12 | ... = ... |
|
||||
| test.cpp:815:52:815:54 | end | test.cpp:815:52:815:54 | end |
|
||||
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... |
|
||||
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... |
|
||||
| test.cpp:832:40:832:43 | mk_array_no_field_flow output argument | test.cpp:833:37:833:39 | end |
|
||||
| test.cpp:833:37:833:39 | end | test.cpp:815:52:815:54 | end |
|
||||
nodes
|
||||
| test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:5:15:5:22 | ... + ... | semmle.label | ... + ... |
|
||||
@@ -260,48 +220,6 @@ nodes
|
||||
| test.cpp:53:12:53:23 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:60:34:60:37 | mk_array output argument | semmle.label | mk_array output argument |
|
||||
| test.cpp:67:9:67:14 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:80:9:80:16 | mk_array indirection [end] | semmle.label | mk_array indirection [end] |
|
||||
| test.cpp:82:5:82:28 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:82:9:82:13 | arr indirection [post update] [begin] | semmle.label | arr indirection [post update] [begin] |
|
||||
| test.cpp:82:17:82:22 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:83:5:83:30 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:83:9:83:11 | arr indirection [post update] [end] | semmle.label | arr indirection [post update] [end] |
|
||||
| test.cpp:83:15:83:17 | arr indirection [begin] | semmle.label | arr indirection [begin] |
|
||||
| test.cpp:83:15:83:30 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:83:19:83:23 | begin indirection | semmle.label | begin indirection |
|
||||
| test.cpp:89:19:89:26 | call to mk_array [end] | semmle.label | call to mk_array [end] |
|
||||
| test.cpp:91:36:91:38 | arr indirection [end] | semmle.label | arr indirection [end] |
|
||||
| test.cpp:91:40:91:42 | end indirection | semmle.label | end indirection |
|
||||
| test.cpp:95:36:95:38 | arr indirection [end] | semmle.label | arr indirection [end] |
|
||||
| test.cpp:95:40:95:42 | end indirection | semmle.label | end indirection |
|
||||
| test.cpp:96:9:96:14 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:104:27:104:29 | arr [end] | semmle.label | arr [end] |
|
||||
| test.cpp:105:36:105:38 | arr indirection [end] | semmle.label | arr indirection [end] |
|
||||
| test.cpp:105:40:105:42 | end indirection | semmle.label | end indirection |
|
||||
| test.cpp:109:36:109:38 | arr indirection [end] | semmle.label | arr indirection [end] |
|
||||
| test.cpp:109:40:109:42 | end indirection | semmle.label | end indirection |
|
||||
| test.cpp:110:9:110:14 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:119:18:119:25 | call to mk_array [end] | semmle.label | call to mk_array [end] |
|
||||
| test.cpp:141:10:141:19 | mk_array_p indirection [end] | semmle.label | mk_array_p indirection [end] |
|
||||
| test.cpp:143:5:143:29 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:143:10:143:14 | arr indirection [post update] [begin] | semmle.label | arr indirection [post update] [begin] |
|
||||
| test.cpp:143:18:143:23 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:144:5:144:32 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:144:10:144:12 | arr indirection [post update] [end] | semmle.label | arr indirection [post update] [end] |
|
||||
| test.cpp:144:16:144:18 | arr indirection [begin] | semmle.label | arr indirection [begin] |
|
||||
| test.cpp:144:16:144:32 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:144:21:144:25 | begin indirection | semmle.label | begin indirection |
|
||||
| test.cpp:150:20:150:29 | call to mk_array_p indirection [end] | semmle.label | call to mk_array_p indirection [end] |
|
||||
| test.cpp:156:37:156:39 | arr indirection [end] | semmle.label | arr indirection [end] |
|
||||
| test.cpp:156:42:156:44 | end indirection | semmle.label | end indirection |
|
||||
| test.cpp:157:9:157:14 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:165:29:165:31 | arr indirection [end] | semmle.label | arr indirection [end] |
|
||||
| test.cpp:166:37:166:39 | arr indirection [end] | semmle.label | arr indirection [end] |
|
||||
| test.cpp:166:42:166:44 | end indirection | semmle.label | end indirection |
|
||||
| test.cpp:170:37:170:39 | arr indirection [end] | semmle.label | arr indirection [end] |
|
||||
| test.cpp:170:42:170:44 | end indirection | semmle.label | end indirection |
|
||||
| test.cpp:171:9:171:14 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:180:19:180:28 | call to mk_array_p indirection [end] | semmle.label | call to mk_array_p indirection [end] |
|
||||
| test.cpp:194:23:194:28 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... |
|
||||
@@ -394,6 +312,17 @@ nodes
|
||||
| test.cpp:772:16:772:29 | access to array | semmle.label | access to array |
|
||||
| test.cpp:781:14:781:27 | new[] | semmle.label | new[] |
|
||||
| test.cpp:786:18:786:27 | access to array | semmle.label | access to array |
|
||||
| test.cpp:792:60:792:62 | end | semmle.label | end |
|
||||
| test.cpp:793:14:793:19 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:794:5:794:24 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:794:12:794:24 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | semmle.label | mk_array_no_field_flow output argument |
|
||||
| test.cpp:807:7:807:12 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:815:52:815:54 | end | semmle.label | end |
|
||||
| test.cpp:815:52:815:54 | end | semmle.label | end |
|
||||
| test.cpp:821:7:821:12 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:832:40:832:43 | mk_array_no_field_flow output argument | semmle.label | mk_array_no_field_flow output argument |
|
||||
| test.cpp:833:37:833:39 | end | semmle.label | end |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:6:14:6:15 | * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size |
|
||||
@@ -404,10 +333,6 @@ subpaths
|
||||
| test.cpp:42:14:42:15 | * ... | test.cpp:40:15:40:20 | call to malloc | test.cpp:42:14:42:15 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:40:15:40:20 | call to malloc | call to malloc | test.cpp:41:20:41:27 | ... - ... | ... - ... |
|
||||
| test.cpp:44:14:44:21 | * ... | test.cpp:40:15:40:20 | call to malloc | test.cpp:44:14:44:21 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:40:15:40:20 | call to malloc | call to malloc | test.cpp:41:20:41:27 | ... - ... | ... - ... |
|
||||
| test.cpp:67:9:67:14 | ... = ... | test.cpp:52:19:52:24 | call to malloc | test.cpp:67:9:67:14 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:52:19:52:24 | call to malloc | call to malloc | test.cpp:53:20:53:23 | size | size |
|
||||
| test.cpp:96:9:96:14 | ... = ... | test.cpp:82:17:82:22 | call to malloc | test.cpp:96:9:96:14 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:82:17:82:22 | call to malloc | call to malloc | test.cpp:83:27:83:30 | size | size |
|
||||
| test.cpp:110:9:110:14 | ... = ... | test.cpp:82:17:82:22 | call to malloc | test.cpp:110:9:110:14 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:82:17:82:22 | call to malloc | call to malloc | test.cpp:83:27:83:30 | size | size |
|
||||
| test.cpp:157:9:157:14 | ... = ... | test.cpp:143:18:143:23 | call to malloc | test.cpp:157:9:157:14 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:143:18:143:23 | call to malloc | call to malloc | test.cpp:144:29:144:32 | size | size |
|
||||
| test.cpp:171:9:171:14 | ... = ... | test.cpp:143:18:143:23 | call to malloc | test.cpp:171:9:171:14 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:143:18:143:23 | call to malloc | call to malloc | test.cpp:144:29:144:32 | size | size |
|
||||
| test.cpp:201:5:201:19 | ... = ... | test.cpp:194:23:194:28 | call to malloc | test.cpp:201:5:201:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:194:23:194:28 | call to malloc | call to malloc | test.cpp:195:21:195:23 | len | len |
|
||||
| test.cpp:213:5:213:13 | ... = ... | test.cpp:205:23:205:28 | call to malloc | test.cpp:213:5:213:13 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:205:23:205:28 | call to malloc | call to malloc | test.cpp:206:21:206:23 | len | len |
|
||||
| test.cpp:232:3:232:20 | ... = ... | test.cpp:231:18:231:30 | new[] | test.cpp:232:3:232:20 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:231:18:231:30 | new[] | new[] | test.cpp:232:11:232:15 | index | index |
|
||||
@@ -434,3 +359,5 @@ subpaths
|
||||
| test.cpp:772:16:772:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:767:22:767:28 | ... + ... | ... + ... |
|
||||
| test.cpp:772:16:772:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:772:22:772:28 | ... + ... | ... + ... |
|
||||
| test.cpp:786:18:786:27 | access to array | test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:781:14:781:27 | new[] | new[] | test.cpp:786:20:786:26 | ... + ... | ... + ... |
|
||||
| test.cpp:807:7:807:12 | ... = ... | test.cpp:793:14:793:19 | call to malloc | test.cpp:807:7:807:12 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:793:14:793:19 | call to malloc | call to malloc | test.cpp:794:21:794:24 | size | size |
|
||||
| test.cpp:821:7:821:12 | ... = ... | test.cpp:793:14:793:19 | call to malloc | test.cpp:821:7:821:12 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:793:14:793:19 | call to malloc | call to malloc | test.cpp:794:21:794:24 | size | size |
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user