mirror of
https://github.com/github/codeql.git
synced 2026-05-16 20:27:06 +02:00
Compare commits
641 Commits
codeql-cli
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d82318839 | ||
|
|
71ab804274 | ||
|
|
1a8932bc28 | ||
|
|
c653f1ce8c | ||
|
|
e812682991 | ||
|
|
aebe9f6992 | ||
|
|
769e3469a4 | ||
|
|
0a6243d07b | ||
|
|
ca12348ecb | ||
|
|
d1f8336be6 | ||
|
|
31f1f50a64 | ||
|
|
dc9092c9ec | ||
|
|
2daf50500c | ||
|
|
2f058ffb4d | ||
|
|
711c474049 | ||
|
|
ce31f8641a | ||
|
|
727a38a409 | ||
|
|
661e68dab5 | ||
|
|
7e2a775a2a | ||
|
|
967963a653 | ||
|
|
eaef544a26 | ||
|
|
40ff75db07 | ||
|
|
a8d240dd72 | ||
|
|
ac394dc80c | ||
|
|
b1e0bc03ab | ||
|
|
367ecf75d5 | ||
|
|
2aa093c95c | ||
|
|
92e91f596f | ||
|
|
a67218a027 | ||
|
|
19539ab6d8 | ||
|
|
2b2ea597ce | ||
|
|
331f308997 | ||
|
|
e124b07611 | ||
|
|
dcc2b2c50d | ||
|
|
00e77a3ddb | ||
|
|
569bb991d4 | ||
|
|
a9ce2e10ad | ||
|
|
ab288d0d4c | ||
|
|
e5de4f2d67 | ||
|
|
73fe20f33b | ||
|
|
1f3a3492ae | ||
|
|
9bad1e60db | ||
|
|
9b5bf519a1 | ||
|
|
279605b486 | ||
|
|
acf2f761a6 | ||
|
|
1a13a0e4c9 | ||
|
|
52b273ae23 | ||
|
|
8055c5d9e3 | ||
|
|
020eb4aed7 | ||
|
|
040a288bb3 | ||
|
|
37212737fb | ||
|
|
ac484e5a04 | ||
|
|
a8ae2e2525 | ||
|
|
52a36ce41c | ||
|
|
4dd23d4767 | ||
|
|
726e0928ed | ||
|
|
83cef78200 | ||
|
|
0e9a7c84d1 | ||
|
|
ff82eb95f5 | ||
|
|
6563414370 | ||
|
|
fbf6727809 | ||
|
|
16cb6c2044 | ||
|
|
85a45b0155 | ||
|
|
0c93641b54 | ||
|
|
ce1d0d2375 | ||
|
|
038afc4008 | ||
|
|
037c76d840 | ||
|
|
11142df4d0 | ||
|
|
7a96b11a0a | ||
|
|
19ac9e089a | ||
|
|
c7efde3b7a | ||
|
|
9c2322dd82 | ||
|
|
114c17ad57 | ||
|
|
040395485e | ||
|
|
bf22c6dae0 | ||
|
|
0bb6a64e81 | ||
|
|
0a8dfbafe4 | ||
|
|
fd82a06b93 | ||
|
|
4adc373dfe | ||
|
|
3418ec8a81 | ||
|
|
bda8a804ec | ||
|
|
d99a763ef7 | ||
|
|
5399d88d15 | ||
|
|
eeda4355f1 | ||
|
|
e43c368222 | ||
|
|
30b7fadbb8 | ||
|
|
6e63df9e32 | ||
|
|
0e1c45e84b | ||
|
|
df64e0bc5f | ||
|
|
f89fedcbaf | ||
|
|
a693c6d9b4 | ||
|
|
a97510a2fc | ||
|
|
15d1105d8d | ||
|
|
9133a13fc7 | ||
|
|
6d9f3d4a3e | ||
|
|
10f6329b3e | ||
|
|
f907fd21ad | ||
|
|
0e95f41900 | ||
|
|
ac4ad0cbc0 | ||
|
|
24572848f3 | ||
|
|
07fc84de8c | ||
|
|
cb128da5aa | ||
|
|
bb97df1d71 | ||
|
|
20ff7def73 | ||
|
|
86b4f27d12 | ||
|
|
a7547d516a | ||
|
|
1719fd8acb | ||
|
|
0f1106b2f6 | ||
|
|
bbf3fa7506 | ||
|
|
abdae2c437 | ||
|
|
bf2174ffce | ||
|
|
0b7b7ea1b8 | ||
|
|
ef0a1d2873 | ||
|
|
e0515269c5 | ||
|
|
4e913592fa | ||
|
|
2eb8d13439 | ||
|
|
a8816a6d1c | ||
|
|
d54e3d73ab | ||
|
|
d182eae868 | ||
|
|
664dac6b28 | ||
|
|
dd1dbdf4ec | ||
|
|
148bc26b09 | ||
|
|
54031a8187 | ||
|
|
a8468a6178 | ||
|
|
1466f11a92 | ||
|
|
6d90877c52 | ||
|
|
f488f23a48 | ||
|
|
89bdb7f437 | ||
|
|
86ceeebd89 | ||
|
|
3563c7ef03 | ||
|
|
e64826db1b | ||
|
|
af749e221b | ||
|
|
f237d2aeda | ||
|
|
5198f52351 | ||
|
|
22e8da2928 | ||
|
|
eb81946adc | ||
|
|
b4dabee770 | ||
|
|
434fa20646 | ||
|
|
1086abca63 | ||
|
|
b76795fd28 | ||
|
|
fd3738b10e | ||
|
|
31d4d0ca57 | ||
|
|
75772664f2 | ||
|
|
f388a0f10c | ||
|
|
bd0137a721 | ||
|
|
051d63a5a9 | ||
|
|
47bf556223 | ||
|
|
7b5f51b1e2 | ||
|
|
ef9544cbef | ||
|
|
903e4f59f0 | ||
|
|
140c3189e3 | ||
|
|
3bd0c3b2c2 | ||
|
|
ef82ea7541 | ||
|
|
551006c15e | ||
|
|
ffa998eb4a | ||
|
|
b6507e795a | ||
|
|
5d55265910 | ||
|
|
1fd459e8fc | ||
|
|
6c8105fd1c | ||
|
|
0a137c7b02 | ||
|
|
8d1965db59 | ||
|
|
cfdf163b40 | ||
|
|
81facd2fd6 | ||
|
|
e620bfa9c6 | ||
|
|
d892a04506 | ||
|
|
939d6f973f | ||
|
|
65bc62c10a | ||
|
|
b0a13fb661 | ||
|
|
4474b54662 | ||
|
|
46b47db78e | ||
|
|
7beafc933d | ||
|
|
0e93f5ac1a | ||
|
|
62382fc5a2 | ||
|
|
840ca9118e | ||
|
|
a3b39c8210 | ||
|
|
14d046ef18 | ||
|
|
c6426d8858 | ||
|
|
0d017a9343 | ||
|
|
62f4d8e53e | ||
|
|
b1deeaff05 | ||
|
|
a7f0966fcb | ||
|
|
ca1a27dc75 | ||
|
|
8079788a5f | ||
|
|
cdf4dd16f0 | ||
|
|
377ef59c3a | ||
|
|
efff0149d0 | ||
|
|
ab11068d6d | ||
|
|
e4699e092d | ||
|
|
6aeef17f99 | ||
|
|
297a17975d | ||
|
|
9563705eb3 | ||
|
|
bb282b94dd | ||
|
|
f6b1d1f235 | ||
|
|
b76449714a | ||
|
|
5226c77abf | ||
|
|
00d311205b | ||
|
|
794bc44a41 | ||
|
|
692d7036a0 | ||
|
|
a86de9de2f | ||
|
|
18c7e73805 | ||
|
|
d8bff14365 | ||
|
|
4bbaf687ad | ||
|
|
ae97a23c27 | ||
|
|
c247dee11a | ||
|
|
053e172d94 | ||
|
|
897786dc99 | ||
|
|
65ec80967e | ||
|
|
00ad7854dc | ||
|
|
3c15b21385 | ||
|
|
7535a15fda | ||
|
|
95dc2f71d3 | ||
|
|
7be76405f5 | ||
|
|
0358e81117 | ||
|
|
cc178ab58f | ||
|
|
a743683d4f | ||
|
|
b8c141f292 | ||
|
|
ddd5113c02 | ||
|
|
892f97cd7a | ||
|
|
0335a4f4ce | ||
|
|
f9c2b4d23c | ||
|
|
7c7c10ea11 | ||
|
|
f2935caa5c | ||
|
|
bba152da13 | ||
|
|
9f84653283 | ||
|
|
aedd3badf7 | ||
|
|
5ea30e95a5 | ||
|
|
f7b2de800b | ||
|
|
914a605a87 | ||
|
|
994d990f37 | ||
|
|
dc3b78dd7c | ||
|
|
a6480a4ca1 | ||
|
|
4a501e5b3c | ||
|
|
9eaa4e19ad | ||
|
|
74448c092a | ||
|
|
e62a0805db | ||
|
|
fbb0ffcadd | ||
|
|
3ab6f222d0 | ||
|
|
df5e753ee0 | ||
|
|
540c20e143 | ||
|
|
699dddcfbe | ||
|
|
bbeee8f38d | ||
|
|
f7cdcd4981 | ||
|
|
03f01a0121 | ||
|
|
a513598a4d | ||
|
|
408a550467 | ||
|
|
2e66392353 | ||
|
|
cb733dcf85 | ||
|
|
4bb725cbf5 | ||
|
|
234623ec0d | ||
|
|
5c4543f167 | ||
|
|
e9b5394cd5 | ||
|
|
6ff0054e52 | ||
|
|
f92c106972 | ||
|
|
8212f5de1b | ||
|
|
b86643fab2 | ||
|
|
cba247788a | ||
|
|
f9934ed5e7 | ||
|
|
4dd368f7a6 | ||
|
|
80513d846d | ||
|
|
ff32cf90fd | ||
|
|
e6f4263eff | ||
|
|
bf4e3a7d1c | ||
|
|
dd0c721e8c | ||
|
|
20bb631456 | ||
|
|
606a8fed0c | ||
|
|
8a670fe9a2 | ||
|
|
e5e0b4c537 | ||
|
|
bc98712da5 | ||
|
|
32f5667bb6 | ||
|
|
c582ea626d | ||
|
|
1c1a6f13df | ||
|
|
9c5c8c8362 | ||
|
|
464e2e4291 | ||
|
|
18fa91bde4 | ||
|
|
a75a004942 | ||
|
|
474a4f8abd | ||
|
|
1410574f76 | ||
|
|
1657b314c1 | ||
|
|
688b9955a0 | ||
|
|
b82ffd40e7 | ||
|
|
fd85c44129 | ||
|
|
386defc3c7 | ||
|
|
c22cbf5b01 | ||
|
|
fb06e9f6b2 | ||
|
|
acf3a99dff | ||
|
|
4ede553b21 | ||
|
|
5f5bcf686d | ||
|
|
dab8e237e6 | ||
|
|
5b1fb8789a | ||
|
|
5b6e76c030 | ||
|
|
1cfac50749 | ||
|
|
403a1ac483 | ||
|
|
2257df5c6f | ||
|
|
8fbe62ccae | ||
|
|
788100d475 | ||
|
|
03a125de38 | ||
|
|
4bd79c0eb3 | ||
|
|
07223031e8 | ||
|
|
acd52192d1 | ||
|
|
7197c64e2d | ||
|
|
2683e40038 | ||
|
|
12213a0a08 | ||
|
|
bfea40fca0 | ||
|
|
d57160db5c | ||
|
|
da5e3d64ac | ||
|
|
dd97584eff | ||
|
|
1abd81ec34 | ||
|
|
f43e929d1a | ||
|
|
6b63492d6b | ||
|
|
72f73553ca | ||
|
|
759b74791c | ||
|
|
047a8b400e | ||
|
|
ee967e62e1 | ||
|
|
3dc6918356 | ||
|
|
a0f91fbc15 | ||
|
|
62b16c0fa3 | ||
|
|
20f795c03a | ||
|
|
1a155b3a30 | ||
|
|
94113521d1 | ||
|
|
d8645cc960 | ||
|
|
b2b5aa18b2 | ||
|
|
303a2bb63a | ||
|
|
ea7d9c97fd | ||
|
|
8d358a9f64 | ||
|
|
cf441d1a30 | ||
|
|
6f7f68fee8 | ||
|
|
797fee9c9e | ||
|
|
63a5b49846 | ||
|
|
47a9a8b82a | ||
|
|
515e93522f | ||
|
|
d2e6746e7f | ||
|
|
942a4ed925 | ||
|
|
ebe6ee5257 | ||
|
|
c7ee5b2912 | ||
|
|
fbc689227d | ||
|
|
50f9354ca8 | ||
|
|
e176b32a83 | ||
|
|
6c5e5966c3 | ||
|
|
648c06ce27 | ||
|
|
0bf29f0a62 | ||
|
|
b7df26e6c9 | ||
|
|
b1e0287a7c | ||
|
|
47f94e2ebe | ||
|
|
2b4b512611 | ||
|
|
2ebb80b632 | ||
|
|
67e8f17c4c | ||
|
|
1f409b0456 | ||
|
|
c0d82cb73e | ||
|
|
c55354b544 | ||
|
|
350d5bf0ce | ||
|
|
8e64880e86 | ||
|
|
671904d58c | ||
|
|
aca3970c33 | ||
|
|
fe6b27bcf8 | ||
|
|
a24a57c586 | ||
|
|
a4ab163532 | ||
|
|
d19c83228e | ||
|
|
cf9c3d5dd1 | ||
|
|
14de39a854 | ||
|
|
245ce2208e | ||
|
|
bf22f4a870 | ||
|
|
7ce7b58ce0 | ||
|
|
e74e5b3613 | ||
|
|
95ce0cd640 | ||
|
|
976c627d52 | ||
|
|
3bea642d5c | ||
|
|
fd485d06aa | ||
|
|
0471287cdd | ||
|
|
4810657515 | ||
|
|
d953a9a523 | ||
|
|
f1bdd6bdda | ||
|
|
f2c849c737 | ||
|
|
2afcc611ce | ||
|
|
b66153be97 | ||
|
|
a14c2ae8ab | ||
|
|
ef124695a5 | ||
|
|
67222f8f7e | ||
|
|
cda4ca68f8 | ||
|
|
7410522660 | ||
|
|
b405c5fc02 | ||
|
|
92bdd637a3 | ||
|
|
21aa025db2 | ||
|
|
ebee35b385 | ||
|
|
23869fc8e6 | ||
|
|
007d08ea63 | ||
|
|
9ecac04709 | ||
|
|
c15d3ab08a | ||
|
|
875ab74c28 | ||
|
|
66743fb0db | ||
|
|
e0c7849f52 | ||
|
|
218a3877d2 | ||
|
|
db10c229de | ||
|
|
8d35db0fe6 | ||
|
|
e6f70385f4 | ||
|
|
006b682333 | ||
|
|
36b304d9a1 | ||
|
|
212d5def16 | ||
|
|
1b98dc16ba | ||
|
|
5ecdc29808 | ||
|
|
f9d391d087 | ||
|
|
3ca9d70100 | ||
|
|
61bfe7e520 | ||
|
|
cb5e3c336d | ||
|
|
339c89019a | ||
|
|
e13d6cdd57 | ||
|
|
3df3fbc65b | ||
|
|
9948052fb6 | ||
|
|
11dc467add | ||
|
|
8bbfb82f8e | ||
|
|
204be4a809 | ||
|
|
3c35683e25 | ||
|
|
0c46b493c3 | ||
|
|
31959eaf1f | ||
|
|
a0b44c0fc1 | ||
|
|
0d32192f62 | ||
|
|
b76a27bba2 | ||
|
|
71f8ccf45f | ||
|
|
132b8baa57 | ||
|
|
009ea1bcfd | ||
|
|
57cb7f8218 | ||
|
|
c1f18edfed | ||
|
|
f072e41d50 | ||
|
|
e1e29f277c | ||
|
|
060133d3e9 | ||
|
|
70a2d16b1a | ||
|
|
c5ed96b4f8 | ||
|
|
f2e04c0cb2 | ||
|
|
c5dbaa6bfd | ||
|
|
8be9b8b818 | ||
|
|
e2511cdbe4 | ||
|
|
8058096d7d | ||
|
|
6665248c19 | ||
|
|
ae59ea3152 | ||
|
|
3f10dd06f2 | ||
|
|
65db990c97 | ||
|
|
bb86ce5749 | ||
|
|
698109ae10 | ||
|
|
77ef63a051 | ||
|
|
54d7805e4a | ||
|
|
d3ee5f65db | ||
|
|
37f8fa3413 | ||
|
|
10da4d14d9 | ||
|
|
2da00986c0 | ||
|
|
fbf70c688f | ||
|
|
67d0415942 | ||
|
|
0d734983b4 | ||
|
|
d6f657cfd7 | ||
|
|
e4d41194b4 | ||
|
|
3112bf4682 | ||
|
|
75f66c2191 | ||
|
|
5a348a5048 | ||
|
|
5b46256fdb | ||
|
|
29ffeb6da5 | ||
|
|
2cc762b85a | ||
|
|
22e72d2fed | ||
|
|
de727bf1b5 | ||
|
|
ec3cc6376f | ||
|
|
0787cc5e51 | ||
|
|
f842eee784 | ||
|
|
d0e169ebda | ||
|
|
66010b5c96 | ||
|
|
c324b2aed8 | ||
|
|
eb7d0244c2 | ||
|
|
493b37774f | ||
|
|
6d597bea0d | ||
|
|
8a5b907912 | ||
|
|
d96f29d6c2 | ||
|
|
51bed86778 | ||
|
|
29258ad8c2 | ||
|
|
4ef1ac9250 | ||
|
|
15bc3c282f | ||
|
|
216d6c0827 | ||
|
|
b174aa65a3 | ||
|
|
f41b70af78 | ||
|
|
2494b7d801 | ||
|
|
2c8ed6479a | ||
|
|
639642fb67 | ||
|
|
0410ed734b | ||
|
|
9f3dd6300f | ||
|
|
32d6c5ac3d | ||
|
|
1626344560 | ||
|
|
aa7c677e13 | ||
|
|
008585eeba | ||
|
|
8886092cd0 | ||
|
|
be54a41593 | ||
|
|
c68d36eb79 | ||
|
|
b407c86d03 | ||
|
|
57c1bf5835 | ||
|
|
497592a4d4 | ||
|
|
ce0159c005 | ||
|
|
7e912f0de0 | ||
|
|
9b2019db6b | ||
|
|
499ab0892f | ||
|
|
9ad05fe51c | ||
|
|
7e9bf2a880 | ||
|
|
24a63ae94d | ||
|
|
625c47fa9c | ||
|
|
1e75c73825 | ||
|
|
f8b29ad70e | ||
|
|
d358f8e4f2 | ||
|
|
b996f7b3ce | ||
|
|
8f0f6963bb | ||
|
|
04f0fb0483 | ||
|
|
d6b0746b30 | ||
|
|
4d28c0d2a9 | ||
|
|
e36b9f4d3c | ||
|
|
37eb81097f | ||
|
|
6267506a77 | ||
|
|
1055e773ef | ||
|
|
4387c73d12 | ||
|
|
6dbb5c5fdb | ||
|
|
e2c673417f | ||
|
|
6eac48caba | ||
|
|
a9d8643f5a | ||
|
|
a26d11bcea | ||
|
|
058bf32ad0 | ||
|
|
d99ad01efa | ||
|
|
251888a0bd | ||
|
|
925e99cdb2 | ||
|
|
f0df7cd5c5 | ||
|
|
d4ea45bdaf | ||
|
|
843f7694fd | ||
|
|
3a982de16f | ||
|
|
9c3667dbf7 | ||
|
|
fd54350ba8 | ||
|
|
f084829154 | ||
|
|
20836c7088 | ||
|
|
fbd7946cfd | ||
|
|
0b8a917584 | ||
|
|
46c553e802 | ||
|
|
a961e276c1 | ||
|
|
51eb487022 | ||
|
|
c96735e17a | ||
|
|
db1d24a900 | ||
|
|
e79f5905e7 | ||
|
|
ec902827f6 | ||
|
|
b9e96e4a27 | ||
|
|
21fbb1b051 | ||
|
|
f48b1e57d7 | ||
|
|
aa5e14f59f | ||
|
|
8b376e7a35 | ||
|
|
025fbc874f | ||
|
|
bdae54714a | ||
|
|
64122ba867 | ||
|
|
7392440475 | ||
|
|
b5ae8ace0d | ||
|
|
1bf747ef3a | ||
|
|
254634075f | ||
|
|
f013d9d373 | ||
|
|
fc75e44238 | ||
|
|
4f5c43a3c6 | ||
|
|
3f53186ad1 | ||
|
|
60879bd367 | ||
|
|
82bd1d7b0b | ||
|
|
237bf5653a | ||
|
|
bd36847ca2 | ||
|
|
c2571160c3 | ||
|
|
0488d1d295 | ||
|
|
df212807a0 | ||
|
|
7ed73bc4ed | ||
|
|
9016997b51 | ||
|
|
d94d4591da | ||
|
|
c4a0f36a08 | ||
|
|
3ff950660b | ||
|
|
9838da5395 | ||
|
|
a3dc19fd31 | ||
|
|
5c454944a9 | ||
|
|
2a91bb8c54 | ||
|
|
7e23ccd383 | ||
|
|
128bc99f90 | ||
|
|
2f7b946c9f | ||
|
|
b9785ea7b2 | ||
|
|
f791b0ebbf | ||
|
|
b6cf64cff3 | ||
|
|
7d8872bb99 | ||
|
|
6663420d39 | ||
|
|
b94c4a6e1b | ||
|
|
bac7e46b0f | ||
|
|
15cf695188 | ||
|
|
90f3670f3d | ||
|
|
a944443d39 | ||
|
|
c0eeb7a34e | ||
|
|
3a4a841844 | ||
|
|
16a7d68780 | ||
|
|
2eb93b7a3b | ||
|
|
d8985f9f5b | ||
|
|
c79a3eb6ae | ||
|
|
53539226a8 | ||
|
|
19bb8fe22d | ||
|
|
d814decc17 | ||
|
|
d1160f86e1 | ||
|
|
1b571f8992 | ||
|
|
8fc4fae7d2 | ||
|
|
5cb71ce7e5 | ||
|
|
174966164d | ||
|
|
b105d0cf9a | ||
|
|
9cfef6e42f | ||
|
|
5653c3f972 | ||
|
|
40e06b7877 | ||
|
|
8013c2a074 | ||
|
|
bbabf1dfcc | ||
|
|
2d010f69c6 | ||
|
|
984c7ab85a | ||
|
|
4513fd1b52 | ||
|
|
820f4a5571 | ||
|
|
85d1d079c8 | ||
|
|
3a404cec67 | ||
|
|
47720e0998 | ||
|
|
f20d4e22fe | ||
|
|
54c7c5e8be | ||
|
|
8a7c3c19fe | ||
|
|
ec5a8b49c8 | ||
|
|
ac3cb7f6c4 | ||
|
|
a17c704f46 | ||
|
|
d899267acb | ||
|
|
5f6de79c09 | ||
|
|
a09505afc2 | ||
|
|
5148054612 | ||
|
|
221e281f73 | ||
|
|
0ea27c6e9b | ||
|
|
da275b374f | ||
|
|
a47ffc6833 | ||
|
|
bb2083d10a | ||
|
|
bc81201c2e | ||
|
|
cf8f2a38c3 | ||
|
|
a6b092d8c1 | ||
|
|
4d97c42ee5 | ||
|
|
501f617eaa | ||
|
|
34fb1c4a9f | ||
|
|
0813199c7f | ||
|
|
a925c23d14 | ||
|
|
6bd3c8c07b | ||
|
|
6378c5e22f | ||
|
|
63123f3984 | ||
|
|
ba4f8612eb | ||
|
|
ad1284853b | ||
|
|
eb25d0df66 | ||
|
|
85636ccab7 | ||
|
|
b8f6877aba | ||
|
|
09fa2a7d50 | ||
|
|
94e9848d61 |
8
.bazelrc
8
.bazelrc
@@ -1,4 +1,12 @@
|
||||
common --enable_platform_specific_config
|
||||
common --enable_bzlmod
|
||||
# because we use --override_module with `%workspace%`, the lock file is not stable
|
||||
common --lockfile_mode=off
|
||||
|
||||
# when building from this repository in isolation, the internal repository will not be found at ..
|
||||
# where `MODULE.bazel` looks for it. The following will get us past the module loading phase, so
|
||||
# that we can build things that do not rely on that
|
||||
common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
|
||||
|
||||
build --repo_env=CC=clang --repo_env=CXX=clang++
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.3.1
|
||||
7.0.2
|
||||
|
||||
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -74,3 +74,7 @@ javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/auto
|
||||
|
||||
# Auto-generated modeling for Python
|
||||
python/ql/lib/semmle/python/frameworks/data/internal/subclass-capture/*.yml linguist-generated=true
|
||||
|
||||
# auto-generated bazel lock file
|
||||
ruby/extractor/cargo-bazel-lock.json linguist-generated=true
|
||||
ruby/extractor/cargo-bazel-lock.json -merge
|
||||
|
||||
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
@@ -20,7 +20,7 @@ JS:
|
||||
|
||||
Kotlin:
|
||||
- java/kotlin-extractor/**/*
|
||||
- java/ql/test/kotlin/**/*
|
||||
- java/ql/test-kotlin*/**/*
|
||||
|
||||
Python:
|
||||
- python/**/*
|
||||
|
||||
2
.github/workflows/compile-queries.yml
vendored
2
.github/workflows/compile-queries.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
with:
|
||||
key: all-queries
|
||||
- name: check formatting
|
||||
run: find */ql -type f \( -name "*.qll" -o -name "*.ql" \) -print0 | xargs -0 -n 3000 -P 10 codeql query format -q --check-only
|
||||
run: find shared */ql -type f \( -name "*.qll" -o -name "*.ql" \) -print0 | xargs -0 -n 3000 -P 10 codeql query format -q --check-only
|
||||
- name: compile queries - check-only
|
||||
# run with --check-only if running in a PR (github.sha != main)
|
||||
if : ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
73
.github/workflows/ruby-build.yml
vendored
73
.github/workflows/ruby-build.yml
vendored
@@ -51,9 +51,11 @@ jobs:
|
||||
run: |
|
||||
brew install gnu-tar
|
||||
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
|
||||
- name: Install cargo-cross
|
||||
if: runner.os == 'Linux'
|
||||
run: cargo install cross --version 0.2.5
|
||||
- name: Prepare Windows
|
||||
if: runner.os == 'Windows'
|
||||
shell: powershell
|
||||
run: |
|
||||
git config --global core.longpaths true
|
||||
- uses: ./.github/actions/os-version
|
||||
id: os_version
|
||||
- name: Cache entire extractor
|
||||
@@ -82,16 +84,8 @@ jobs:
|
||||
- name: Run tests
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd extractor && cargo test --verbose
|
||||
# On linux, build the extractor via cross in a centos7 container.
|
||||
# This ensures we don't depend on glibc > 2.17.
|
||||
- name: Release build (linux)
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && runner.os == 'Linux'
|
||||
run: |
|
||||
cd extractor
|
||||
cross build --release
|
||||
mv target/x86_64-unknown-linux-gnu/release/codeql-extractor-ruby target/release/
|
||||
- name: Release build (windows and macos)
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && runner.os != 'Linux'
|
||||
- name: Release build
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd extractor && cargo build --release
|
||||
- name: Generate dbscheme
|
||||
if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}}
|
||||
@@ -123,7 +117,7 @@ jobs:
|
||||
- name: Cache compilation cache
|
||||
id: query-cache
|
||||
uses: ./.github/actions/cache-query-compilation
|
||||
with:
|
||||
with:
|
||||
key: ruby-build
|
||||
- name: Build Query Pack
|
||||
run: |
|
||||
@@ -235,54 +229,3 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls
|
||||
|
||||
# This is a copy of the 'test' job that runs in a centos7 container.
|
||||
# This tests that the extractor works correctly on systems with an old glibc.
|
||||
test-centos7:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ${{ github.workspace }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: centos:centos7
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
needs: [package]
|
||||
steps:
|
||||
- name: Install gh cli
|
||||
run: |
|
||||
yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
|
||||
# fetch-codeql requires unzip and jq
|
||||
# jq is available in epel-release (https://docs.fedoraproject.org/en-US/epel/)
|
||||
yum install -y gh unzip epel-release
|
||||
yum install -y jq
|
||||
- uses: actions/checkout@v3
|
||||
- name: Fetch CodeQL
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
|
||||
# Due to a bug in Actions, we can't use runner.temp in the run blocks here.
|
||||
# https://github.com/actions/runner/issues/2185
|
||||
|
||||
- name: Download Ruby bundle
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: codeql-ruby-bundle
|
||||
path: ${{ runner.temp }}
|
||||
- name: Unzip Ruby bundle
|
||||
shell: bash
|
||||
run: unzip -q -d "$RUNNER_TEMP"/ruby-bundle "$RUNNER_TEMP"/codeql-ruby-bundle.zip
|
||||
|
||||
- name: Run QL test
|
||||
shell: bash
|
||||
run: |
|
||||
codeql test run --search-path "$RUNNER_TEMP"/ruby-bundle --additional-packs "$RUNNER_TEMP"/ruby-bundle ruby/ql/test/library-tests/ast/constants/
|
||||
- name: Create database
|
||||
shell: bash
|
||||
run: |
|
||||
codeql database create --search-path "$RUNNER_TEMP"/ruby-bundle --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database
|
||||
- name: Analyze database
|
||||
shell: bash
|
||||
run: |
|
||||
codeql database analyze --search-path "$RUNNER_TEMP"/ruby-bundle --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -39,6 +39,9 @@
|
||||
# local bazel options
|
||||
/local.bazelrc
|
||||
|
||||
# generated cmake directory
|
||||
/.bazel-cmake
|
||||
|
||||
# CLion project files
|
||||
/.clwb
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
# Bazel (excluding BUILD.bazel files)
|
||||
WORKSPACE.bazel @github/codeql-ci-reviewers
|
||||
MODULE.bazel @github/codeql-ci-reviewers
|
||||
.bazelversion @github/codeql-ci-reviewers
|
||||
.bazelrc @github/codeql-ci-reviewers
|
||||
**/*.bzl @github/codeql-ci-reviewers
|
||||
|
||||
53
MODULE.bazel
Normal file
53
MODULE.bazel
Normal file
@@ -0,0 +1,53 @@
|
||||
module(
|
||||
name = "codeql",
|
||||
version = "0.0",
|
||||
)
|
||||
|
||||
# this points to our internal repository when `codeql` is checked out as a submodule thereof
|
||||
# when building things from `codeql` independently this is stubbed out in `.bazelrc`
|
||||
bazel_dep(name = "semmle_code", version = "0.0")
|
||||
local_path_override(
|
||||
module_name = "semmle_code",
|
||||
path = "..",
|
||||
)
|
||||
|
||||
# see https://registry.bazel.build/ for a list of available packages
|
||||
|
||||
bazel_dep(name = "platforms", version = "0.0.8")
|
||||
bazel_dep(name = "rules_pkg", version = "0.9.1")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.0.3")
|
||||
bazel_dep(name = "rules_python", version = "0.31.0")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.5.0")
|
||||
bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl")
|
||||
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
|
||||
bazel_dep(name = "fmt", version = "10.0.0")
|
||||
|
||||
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
|
||||
pip.parse(
|
||||
hub_name = "codegen_deps",
|
||||
python_version = "3.11",
|
||||
requirements_lock = "//misc/codegen:requirements_lock.txt",
|
||||
)
|
||||
use_repo(pip, "codegen_deps")
|
||||
|
||||
swift_deps = use_extension("//swift/third_party:load.bzl", "swift_deps")
|
||||
use_repo(
|
||||
swift_deps,
|
||||
"binlog",
|
||||
"picosha2",
|
||||
"swift_prebuilt_darwin_x86_64",
|
||||
"swift_prebuilt_linux",
|
||||
"swift_toolchain_linux",
|
||||
"swift_toolchain_macos",
|
||||
)
|
||||
|
||||
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
|
||||
node.toolchain(
|
||||
name = "nodejs",
|
||||
node_version = "18.15.0",
|
||||
)
|
||||
use_repo(node, "nodejs", "nodejs_toolchains")
|
||||
|
||||
register_toolchains(
|
||||
"@nodejs_toolchains//:all",
|
||||
)
|
||||
@@ -1,12 +1,2 @@
|
||||
# Please notice that any bazel targets and definitions in this repository are currently experimental
|
||||
# and for internal use only.
|
||||
|
||||
workspace(name = "codeql")
|
||||
|
||||
load("//misc/bazel:workspace.bzl", "codeql_workspace")
|
||||
|
||||
codeql_workspace()
|
||||
|
||||
load("//misc/bazel:workspace_deps.bzl", "codeql_workspace_deps")
|
||||
|
||||
codeql_workspace_deps()
|
||||
# please use MODULE.bazel to add dependencies
|
||||
# this empty file is required by internal repositories, don't remove it
|
||||
|
||||
@@ -431,13 +431,6 @@
|
||||
"java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp",
|
||||
"java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qhelp"
|
||||
],
|
||||
"IDE Contextual Queries": [
|
||||
"cpp/ql/lib/IDEContextual.qll",
|
||||
"csharp/ql/lib/IDEContextual.qll",
|
||||
"java/ql/lib/IDEContextual.qll",
|
||||
"javascript/ql/lib/IDEContextual.qll",
|
||||
"python/ql/lib/analysis/IDEContextual.qll"
|
||||
],
|
||||
"CryptoAlgorithms Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
|
||||
"python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
|
||||
using Semmle.Autobuild.Shared;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Autobuild.Cpp
|
||||
{
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
## 0.12.9
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.12.8
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.12.7
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added destructors for named objects to the intermediate representation.
|
||||
|
||||
## 0.12.6
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
import semmle.files.FileSystem
|
||||
private import codeql.util.FileSystem
|
||||
|
||||
/**
|
||||
* Returns the `File` matching the given source file name as encoded by the VS
|
||||
@@ -10,13 +11,5 @@ import semmle.files.FileSystem
|
||||
*/
|
||||
cached
|
||||
File getFileBySourceArchiveName(string name) {
|
||||
// The name provided for a file in the source archive by the VS Code extension
|
||||
// has some differences from the absolute path in the database:
|
||||
// 1. colons are replaced by underscores
|
||||
// 2. there's a leading slash, even for Windows paths: "C:/foo/bar" ->
|
||||
// "/C_/foo/bar"
|
||||
// 3. double slashes in UNC prefixes are replaced with a single slash
|
||||
// We can handle 2 and 3 together by unconditionally adding a leading slash
|
||||
// before replacing double slashes.
|
||||
name = ("/" + result.getAbsolutePath().replaceAll(":", "_")).replaceAll("//", "/")
|
||||
result = IdeContextual<File>::getFileBySourceArchiveName(name)
|
||||
}
|
||||
|
||||
5
cpp/ql/lib/change-notes/released/0.12.7.md
Normal file
5
cpp/ql/lib/change-notes/released/0.12.7.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.12.7
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added destructors for named objects to the intermediate representation.
|
||||
3
cpp/ql/lib/change-notes/released/0.12.8.md
Normal file
3
cpp/ql/lib/change-notes/released/0.12.8.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.12.8
|
||||
|
||||
No user-facing changes.
|
||||
3
cpp/ql/lib/change-notes/released/0.12.9.md
Normal file
3
cpp/ql/lib/change-notes/released/0.12.9.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.12.9
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.12.6
|
||||
lastReleaseVersion: 0.12.9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.12.6
|
||||
version: 0.12.9
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -60,4 +60,6 @@ Element exprEnclosingElement(Expr e) {
|
||||
)
|
||||
else result = de.getDeclaration()
|
||||
)
|
||||
or
|
||||
result.(Stmt).getAnImplicitDestructorCall() = e
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// NOTE: There are two copies of this file, and they must be kept identical:
|
||||
// - semmle/code/cpp/controlflow/SubBasicBlocks.qll
|
||||
// - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll
|
||||
// - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll [now DEPRECATED]
|
||||
//
|
||||
// The second one is a private copy of the `SubBasicBlocks` library for
|
||||
// internal use by the data flow library. Having an extra copy prevents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides a local analysis for identifying where a variable address
|
||||
* is effectively taken. Array-like offsets are allowed to pass through but
|
||||
* not field-like offsets.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import DataFlowPrivate
|
||||
private import DataFlowUtil
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*/
|
||||
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<CppOldDataFlow>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*/
|
||||
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<CppOldDataFlow>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides consistency queries for checking invariants in the language-specific
|
||||
* data-flow classes and predicates.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides C++-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import DataFlowUtil
|
||||
private import DataFlowDispatch
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides C++-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides a class for handling variables in the data flow analysis.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// NOTE: There are two copies of this file, and they must be kept identical:
|
||||
// - semmle/code/cpp/controlflow/SubBasicBlocks.qll
|
||||
// - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll
|
||||
// - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll [now DEPRECATED]
|
||||
//
|
||||
// The second one is a private copy of the `SubBasicBlocks` library for
|
||||
// internal use by the data flow library. Having an extra copy prevents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides C++-specific definitions for use in the taint tracking library.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) taint-tracking analyses.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `Global` and `GlobalWithState` instead.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public
|
||||
|
||||
module Private {
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `Global` and `GlobalWithState` instead.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public
|
||||
|
||||
module Private {
|
||||
|
||||
@@ -34,7 +34,7 @@ private import Node0ToString
|
||||
cached
|
||||
private newtype TIRDataFlowNode =
|
||||
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
|
||||
TVariableNode(Variable var, int indirectionIndex) {
|
||||
TGlobalLikeVariableNode(GlobalLikeVariable var, int indirectionIndex) {
|
||||
indirectionIndex =
|
||||
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
} or
|
||||
@@ -55,29 +55,12 @@ private newtype TIRDataFlowNode =
|
||||
TFinalParameterNode(Parameter p, int indirectionIndex) {
|
||||
exists(Ssa::FinalParameterUse use |
|
||||
use.getParameter() = p and
|
||||
use.getIndirectionIndex() = indirectionIndex and
|
||||
parameterIsRedefined(p)
|
||||
use.getIndirectionIndex() = indirectionIndex
|
||||
)
|
||||
} or
|
||||
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
|
||||
TInitialGlobalValue(Ssa::GlobalDef globalUse)
|
||||
|
||||
/**
|
||||
* Holds if the value of `*p` (or `**p`, `***p`, etc.) is redefined somewhere in the body
|
||||
* of the enclosing function of `p`.
|
||||
*
|
||||
* Only parameters satisfying this predicate will generate a `FinalParameterNode` transferring
|
||||
* flow out of the function.
|
||||
*/
|
||||
private predicate parameterIsRedefined(Parameter p) {
|
||||
exists(Ssa::Def def |
|
||||
def.getSourceVariable().getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() = p and
|
||||
def.getIndirectionIndex() = 0 and
|
||||
def.getIndirection() > 1 and
|
||||
not def.getValue().asInstruction() instanceof InitializeParameterInstruction
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand that is defined by a `FieldAddressInstruction`.
|
||||
*/
|
||||
@@ -413,7 +396,7 @@ class Node extends TIRDataFlowNode {
|
||||
* modeling flow in and out of global variables.
|
||||
*/
|
||||
Variable asVariable() {
|
||||
this = TVariableNode(result, getMinIndirectionsForType(result.getUnspecifiedType()))
|
||||
this = TGlobalLikeVariableNode(result, getMinIndirectionsForType(result.getUnspecifiedType()))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -423,7 +406,7 @@ class Node extends TIRDataFlowNode {
|
||||
*/
|
||||
Variable asIndirectVariable(int indirectionIndex) {
|
||||
indirectionIndex > getMinIndirectionsForType(result.getUnspecifiedType()) and
|
||||
this = TVariableNode(result, indirectionIndex)
|
||||
this = TGlobalLikeVariableNode(result, indirectionIndex)
|
||||
}
|
||||
|
||||
/** Gets an indirection of this node's underlying variable, if any. */
|
||||
@@ -1768,15 +1751,18 @@ class DefinitionByReferenceNode extends IndirectArgumentOutNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Node` corresponding to a variable in the program, as opposed to the
|
||||
* value of that variable at some particular point. This can be used for
|
||||
* modeling flow in and out of global variables.
|
||||
* A `Node` corresponding to a global (or `static` local) variable in the
|
||||
* program, as opposed to the value of that variable at some particular point.
|
||||
* This is used to model flow through global variables (and `static` local
|
||||
* variables).
|
||||
*
|
||||
* There is no `VariableNode` for non-`static` local variables.
|
||||
*/
|
||||
class VariableNode extends Node, TVariableNode {
|
||||
class VariableNode extends Node, TGlobalLikeVariableNode {
|
||||
Variable v;
|
||||
int indirectionIndex;
|
||||
|
||||
VariableNode() { this = TVariableNode(v, indirectionIndex) }
|
||||
VariableNode() { this = TGlobalLikeVariableNode(v, indirectionIndex) }
|
||||
|
||||
/** Gets the variable corresponding to this node. */
|
||||
Variable getVariable() { result = v }
|
||||
|
||||
@@ -4,7 +4,11 @@ private import DataFlowUtil
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
|
||||
private import semmle.code.cpp.models.interfaces.Taint as Taint
|
||||
private import semmle.code.cpp.models.interfaces.PartialFlow as PartialFlow
|
||||
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
|
||||
private import DataFlowPrivate
|
||||
private import ssa0.SsaInternals as SsaInternals0
|
||||
import SsaInternalsCommon
|
||||
@@ -138,12 +142,11 @@ private newtype TDefOrUseImpl =
|
||||
isIteratorUse(container, iteratorAddress, _, indirectionIndex)
|
||||
} or
|
||||
TFinalParameterUse(Parameter p, int indirectionIndex) {
|
||||
// Avoid creating parameter nodes if there is no definitions of the variable other than the initializaion.
|
||||
exists(SsaInternals0::Def def |
|
||||
def.getSourceVariable().getBaseVariable().(BaseIRVariable).getIRVariable().getAst() = p and
|
||||
not def.getValue().asInstruction() instanceof InitializeParameterInstruction and
|
||||
underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex)
|
||||
)
|
||||
underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex) and
|
||||
// Only create an SSA read for the final use of a parameter if there's
|
||||
// actually a body of the enclosing function. If there's no function body
|
||||
// then we'll never need to flow out of the function anyway.
|
||||
p.getFunction().hasDefinition()
|
||||
}
|
||||
|
||||
private predicate isGlobalUse(
|
||||
@@ -796,10 +799,58 @@ private Node getAPriorDefinition(SsaDefOrUse defOrUse) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate inOut(FIO::FunctionInput input, FIO::FunctionOutput output) {
|
||||
exists(int indirectionIndex |
|
||||
input.isQualifierObject(indirectionIndex) and
|
||||
output.isQualifierObject(indirectionIndex)
|
||||
or
|
||||
exists(int i |
|
||||
input.isParameterDeref(i, indirectionIndex) and
|
||||
output.isParameterDeref(i, indirectionIndex)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there should not be use-use flow out of `n`. That is, `n` is
|
||||
* an out-barrier to use-use flow. This includes:
|
||||
*
|
||||
* - an input to a call that would be assumed to have use-use flow to the same
|
||||
* argument as an output, but this flow should be blocked because the
|
||||
* function is modeled with another flow to that output (for example the
|
||||
* first argument of `strcpy`).
|
||||
* - a conversion that flows to such an input.
|
||||
*/
|
||||
private predicate modeledFlowBarrier(Node n) {
|
||||
exists(
|
||||
FIO::FunctionInput input, FIO::FunctionOutput output, CallInstruction call,
|
||||
PartialFlow::PartialFlowFunction partialFlowFunc
|
||||
|
|
||||
n = callInput(call, input) and
|
||||
inOut(input, output) and
|
||||
exists(callOutput(call, output)) and
|
||||
partialFlowFunc = call.getStaticCallTarget() and
|
||||
not partialFlowFunc.isPartialWrite(output)
|
||||
|
|
||||
call.getStaticCallTarget().(DataFlow::DataFlowFunction).hasDataFlow(_, output)
|
||||
or
|
||||
call.getStaticCallTarget().(Taint::TaintFunction).hasTaintFlow(_, output)
|
||||
)
|
||||
or
|
||||
exists(Operand operand, Instruction instr, Node n0, int indirectionIndex |
|
||||
modeledFlowBarrier(n0) and
|
||||
nodeHasInstruction(n0, instr, indirectionIndex) and
|
||||
conversionFlow(operand, instr, false, _) and
|
||||
nodeHasOperand(n, operand, indirectionIndex)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
|
||||
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
|
||||
exists(Node nFrom, boolean uncertain, SsaDefOrUse defOrUse |
|
||||
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and nodeFrom != nodeTo
|
||||
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and
|
||||
not modeledFlowBarrier(nFrom) and
|
||||
nodeFrom != nodeTo
|
||||
|
|
||||
if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom
|
||||
)
|
||||
|
||||
@@ -11,6 +11,7 @@ private import InstructionTag
|
||||
private import TranslatedCondition
|
||||
private import TranslatedElement
|
||||
private import TranslatedExpr
|
||||
private import TranslatedCall
|
||||
private import TranslatedStmt
|
||||
private import TranslatedFunction
|
||||
private import TranslatedGlobalVar
|
||||
|
||||
@@ -85,10 +85,14 @@ newtype TInstructionTag =
|
||||
// The next three cases handle generation of branching for __except handling.
|
||||
TryExceptCompareNegativeOneBranch() or
|
||||
TryExceptCompareZeroBranch() or
|
||||
TryExceptCompareOneBranch()
|
||||
TryExceptCompareOneBranch() or
|
||||
ImplicitDestructorTag(int index) {
|
||||
exists(Expr e | exists(e.getImplicitDestructorCall(index))) or
|
||||
exists(Stmt s | exists(s.getImplicitDestructorCall(index)))
|
||||
}
|
||||
|
||||
class InstructionTag extends TInstructionTag {
|
||||
final string toString() { result = "Tag" }
|
||||
final string toString() { result = getInstructionTagId(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,4 +259,8 @@ string getInstructionTagId(TInstructionTag tag) {
|
||||
tag = TryExceptCompareZeroBranch() and result = "TryExceptCompareZeroBranch"
|
||||
or
|
||||
tag = TryExceptCompareOneBranch() and result = "TryExceptCompareOneBranch"
|
||||
or
|
||||
exists(int index |
|
||||
tag = ImplicitDestructorTag(index) and result = "ImplicitDestructor(" + index + ")"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ private CallInstruction getTranslatedCallInstruction(Call call) {
|
||||
* of a higher-level constructor (e.g. the allocator call in a `NewExpr`).
|
||||
*/
|
||||
abstract class TranslatedCall extends TranslatedExpr {
|
||||
final override TranslatedElement getChild(int id) {
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
// We choose the child's id in the order of evaluation.
|
||||
// The qualifier is evaluated before the call target, because the value of
|
||||
// the call target may depend on the value of the qualifier for virtual
|
||||
@@ -47,13 +47,19 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
else result = this.getFirstCallTargetInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getSideEffects().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getSideEffects() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = CallTag() and
|
||||
opcode instanceof Opcode::Call and
|
||||
resultType = getTypeForPRValue(this.getCallResultType())
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getQualifier() and
|
||||
result = this.getFirstCallTargetInstruction(kind)
|
||||
or
|
||||
@@ -87,7 +93,7 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = CallTag() and
|
||||
result = this.getSideEffects().getFirstInstruction(kind)
|
||||
}
|
||||
@@ -225,7 +231,7 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement te, EdgeKind kind) {
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement te, EdgeKind kind) {
|
||||
exists(int i |
|
||||
this.getChild(i) = te and
|
||||
if exists(this.getChild(i + 1))
|
||||
@@ -234,6 +240,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result = this.getChild(max(int i | exists(this.getChild(i))))
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
|
||||
none()
|
||||
}
|
||||
@@ -246,7 +256,18 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if exists(this.getAChild())
|
||||
then result = this.getChild(max(int i | exists(this.getChild(i)))).getALastInstruction()
|
||||
else
|
||||
// If there are no side effects, the "last" instruction should be the parent call's last
|
||||
// instruction, so that implicit destructors can be inserted in the right place.
|
||||
result = this.getParent().getInstruction(CallTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Gets the primary instruction to be associated with each side effect instruction. */
|
||||
abstract Instruction getPrimaryInstruction();
|
||||
@@ -273,8 +294,8 @@ abstract class TranslatedDirectCall extends TranslatedCall {
|
||||
resultType = getFunctionGLValueType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedCall.super.getInstructionSuccessor(tag, kind)
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedCall.super.getInstructionSuccessorInternal(tag, kind)
|
||||
or
|
||||
tag = CallTargetTag() and
|
||||
result = this.getFirstArgumentOrCallInstruction(kind)
|
||||
@@ -367,6 +388,16 @@ class TranslatedStructorCall extends TranslatedFunctionCall {
|
||||
context = this.getParent() and
|
||||
result = context.getReceiver()
|
||||
)
|
||||
or
|
||||
exists(Stmt parent |
|
||||
expr = parent.getAnImplicitDestructorCall() and
|
||||
result = getTranslatedExpr(expr.getQualifier().getFullyConverted()).getResult()
|
||||
)
|
||||
or
|
||||
exists(Expr parent |
|
||||
expr = parent.getAnImplicitDestructorCall() and
|
||||
result = getTranslatedExpr(expr.getQualifier().getFullyConverted()).getResult()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasQualifier() { any() }
|
||||
@@ -416,19 +447,25 @@ private int initializeAllocationGroup() { result = 3 }
|
||||
abstract class TranslatedSideEffect extends TranslatedElement {
|
||||
final override TranslatedElement getChild(int n) { none() }
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
|
||||
tag = OnlyInstructionTag() and
|
||||
this.sideEffectInstruction(opcode, type)
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
result = this.getParent().getChildSuccessor(this, kind) and
|
||||
tag = OnlyInstructionTag()
|
||||
}
|
||||
|
||||
@@ -50,19 +50,29 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
|
||||
{
|
||||
TranslatedFlexibleCondition() { this = TTranslatedFlexibleCondition(expr) }
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
|
||||
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getOperand().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getOperand().getALastInstruction()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
abstract TranslatedCondition getOperand();
|
||||
}
|
||||
@@ -88,12 +98,16 @@ class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
|
||||
abstract class TranslatedNativeCondition extends TranslatedCondition, TTranslatedNativeCondition {
|
||||
TranslatedNativeCondition() { this = TTranslatedNativeCondition(expr) }
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeCondition, ConditionContext {
|
||||
override BinaryLogicalOperation expr;
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
|
||||
|
||||
final override TranslatedElement getChild(int id) {
|
||||
id = 0 and result = this.getLeftOperand()
|
||||
or
|
||||
@@ -104,11 +118,19 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
|
||||
result = this.getLeftOperand().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getLeftOperand().getALastInstruction()
|
||||
or
|
||||
result = this.getRightOperand().getALastInstruction()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final TranslatedCondition getLeftOperand() {
|
||||
result = getTranslatedCondition(expr.getLeftOperand().getFullyConverted())
|
||||
@@ -162,19 +184,25 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
|
||||
result = this.getValueExpr().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(ValueConditionConditionalBranchTag())
|
||||
}
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = ValueConditionConditionalBranchTag() and
|
||||
opcode instanceof Opcode::ConditionalBranch and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getValueExpr() and
|
||||
result = this.getInstruction(ValueConditionConditionalBranchTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = ValueConditionConditionalBranchTag() and
|
||||
(
|
||||
kind instanceof TrueEdge and
|
||||
|
||||
@@ -60,6 +60,10 @@ abstract class TranslatedLocalVariableDeclaration extends TranslatedVariableInit
|
||||
*/
|
||||
abstract LocalVariable getVariable();
|
||||
|
||||
final override TranslatedElement getChild(int id) {
|
||||
result = TranslatedVariableInitialization.super.getChildInternal(id)
|
||||
}
|
||||
|
||||
final override Type getTargetType() { result = getVariableType(this.getVariable()) }
|
||||
|
||||
final override TranslatedInitialization getInitialization() {
|
||||
@@ -152,7 +156,13 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(DynamicInitializationConditionalBranchTag())
|
||||
or
|
||||
result = this.getInstruction(DynamicInitializationFlagStoreTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = DynamicInitializationFlagAddressTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(DynamicInitializationFlagLoadTag())
|
||||
@@ -178,7 +188,7 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getInstruction(DynamicInitializationFlagConstantTag()) and
|
||||
kind instanceof GotoEdge
|
||||
|
||||
@@ -20,10 +20,14 @@ private import SideEffects
|
||||
* they were explicit nodes in the expression tree, rather than as implicit
|
||||
* nodes as in the regular AST representation.
|
||||
*/
|
||||
private Element getRealParent(Expr expr) {
|
||||
Element getRealParent(Expr expr) {
|
||||
result = expr.getParentWithConversions()
|
||||
or
|
||||
result.(Destructor).getADestruction() = expr
|
||||
or
|
||||
result.(Expr).getAnImplicitDestructorCall() = expr
|
||||
or
|
||||
result.(Stmt).getAnImplicitDestructorCall() = expr
|
||||
}
|
||||
|
||||
IRUserVariable getIRUserVariable(Declaration decl, Variable var) {
|
||||
@@ -105,12 +109,6 @@ 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.
|
||||
@@ -118,6 +116,11 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
or
|
||||
not translateFunction(getEnclosingFunction(expr)) and
|
||||
not Raw::varHasIRFunc(getEnclosingVariable(expr))
|
||||
or
|
||||
exists(DeleteOrDeleteArrayExpr deleteExpr |
|
||||
// Ignore the destructor call, because the duplicated qualifier breaks control flow.
|
||||
deleteExpr.getDestructorCall() = expr
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -608,16 +611,27 @@ newtype TTranslatedElement =
|
||||
TTranslatedInitialization(Expr expr) {
|
||||
not ignoreExpr(expr) and
|
||||
(
|
||||
exists(Initializer init | init.getExpr().getFullyConverted() = expr) or
|
||||
exists(ClassAggregateLiteral initList | initList.getAFieldExpr(_).getFullyConverted() = expr) or
|
||||
exists(Initializer init | init.getExpr().getFullyConverted() = expr)
|
||||
or
|
||||
exists(ClassAggregateLiteral initList | initList.getAFieldExpr(_).getFullyConverted() = expr)
|
||||
or
|
||||
exists(ArrayOrVectorAggregateLiteral initList |
|
||||
initList.getAnElementExpr(_).getFullyConverted() = expr
|
||||
) or
|
||||
exists(ReturnStmt returnStmt | returnStmt.getExpr().getFullyConverted() = expr) or
|
||||
exists(ConstructorFieldInit fieldInit | fieldInit.getExpr().getFullyConverted() = expr) or
|
||||
exists(NewExpr newExpr | newExpr.getInitializer().getFullyConverted() = expr) or
|
||||
exists(ThrowExpr throw | throw.getExpr().getFullyConverted() = expr) or
|
||||
exists(TemporaryObjectExpr temp | temp.getExpr() = expr) or
|
||||
)
|
||||
or
|
||||
exists(ReturnStmt returnStmt |
|
||||
returnStmt.getExpr().getFullyConverted() = expr and
|
||||
hasReturnValue(returnStmt.getEnclosingFunction())
|
||||
)
|
||||
or
|
||||
exists(ConstructorFieldInit fieldInit | fieldInit.getExpr().getFullyConverted() = expr)
|
||||
or
|
||||
exists(NewExpr newExpr | newExpr.getInitializer().getFullyConverted() = expr)
|
||||
or
|
||||
exists(ThrowExpr throw | throw.getExpr().getFullyConverted() = expr)
|
||||
or
|
||||
exists(TemporaryObjectExpr temp | temp.getExpr() = expr)
|
||||
or
|
||||
exists(LambdaExpression lambda | lambda.getInitializer().getFullyConverted() = expr)
|
||||
)
|
||||
} or
|
||||
@@ -751,8 +765,6 @@ newtype TTranslatedElement =
|
||||
// on `*this` without an `Expr`.
|
||||
TTranslatedStructorQualifierSideEffect(Call call, SideEffectOpcode opcode) {
|
||||
not ignoreSideEffects(call) and
|
||||
// Don't bother with destructor calls for now, since we won't see very many of them in the IR
|
||||
// until we start injecting implicit destructor calls.
|
||||
call instanceof ConstructorCall and
|
||||
opcode = getASideEffectOpcode(call, -1)
|
||||
} or
|
||||
@@ -866,6 +878,23 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
1 + sum(TranslatedElement child | child = this.getChildByRank(_) | child.getDescendantCount())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element has implicit destructor calls that should follow it.
|
||||
*/
|
||||
predicate hasAnImplicitDestructorCall() { none() }
|
||||
|
||||
/**
|
||||
* Gets the child index of the first destructor call that should be executed after this `TranslatedElement`
|
||||
*/
|
||||
int getFirstDestructorCallIndex() { none() }
|
||||
|
||||
/**
|
||||
* Holds if this `TranslatedElement` includes any destructor calls that must be performed after
|
||||
* it in its `getChildSuccessorInternal`, `getInstructionSuccessorInternal`, and
|
||||
* `getALastInstructionInternal` relations, rather than needing them inserted.
|
||||
*/
|
||||
predicate handlesDestructorsExplicitly() { none() }
|
||||
|
||||
private int getUniqueId() {
|
||||
if not exists(this.getParent())
|
||||
then result = 0
|
||||
@@ -901,15 +930,81 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
/**
|
||||
* Gets the successor instruction of the instruction that was generated by
|
||||
* this element for tag `tag`. The successor edge kind is specified by `kind`.
|
||||
* This predicate does not usually include destructors, which are inserted as
|
||||
* part of `getInstructionSuccessor` unless `handlesDestructorsExplicitly`
|
||||
* holds.
|
||||
*/
|
||||
abstract Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind);
|
||||
abstract Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind);
|
||||
|
||||
/**
|
||||
* Gets the successor instruction of the instruction that was generated by
|
||||
* this element for tag `tag`. The successor edge kind is specified by `kind`.
|
||||
*/
|
||||
final Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
if
|
||||
this.hasAnImplicitDestructorCall() and
|
||||
this.getInstruction(tag) = this.getALastInstructionInternal() and
|
||||
not this.handlesDestructorsExplicitly()
|
||||
then
|
||||
result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind) and
|
||||
kind instanceof GotoEdge
|
||||
else result = this.getInstructionSuccessorInternal(tag, kind)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction within this `TranslatedElement` (including its transitive children) which
|
||||
* will be followed by an instruction outside the `TranslatedElement`.
|
||||
*/
|
||||
final Instruction getALastInstruction() {
|
||||
if this.hasAnImplicitDestructorCall() and not this.handlesDestructorsExplicitly()
|
||||
then result = this.getChild(max(int n | exists(this.getChild(n)))).getALastInstruction() // last destructor
|
||||
else result = this.getALastInstructionInternal()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction within this `TranslatedElement` (including its transitive children) which
|
||||
* will be followed by an instruction outside the `TranslatedElement`.
|
||||
* This predicate does not usually include destructors, which are inserted as
|
||||
* part of `getALastInstruction` unless `handlesDestructorsExplicitly` holds.
|
||||
*/
|
||||
abstract Instruction getALastInstructionInternal();
|
||||
|
||||
TranslatedElement getLastChild() { none() }
|
||||
|
||||
/**
|
||||
* Gets the successor instruction to which control should flow after the
|
||||
* child element specified by `child` has finished execution. The successor
|
||||
* edge kind is specified by `kind`.
|
||||
* This predicate does not usually include destructors, which are inserted as
|
||||
* part of `getChildSuccessor` unless `handlesDestructorsExplicitly` holds.
|
||||
*/
|
||||
Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
/**
|
||||
* Gets the successor instruction to which control should flow after the
|
||||
* child element specified by `child` has finished execution. The successor
|
||||
* edge kind is specified by `kind`.
|
||||
*/
|
||||
abstract Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind);
|
||||
final Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
(
|
||||
if
|
||||
// this is the last child and we need to handle destructors for it
|
||||
this.hasAnImplicitDestructorCall() and
|
||||
not this.handlesDestructorsExplicitly() and
|
||||
child = this.getLastChild()
|
||||
then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind)
|
||||
else result = this.getChildSuccessorInternal(child, kind)
|
||||
)
|
||||
or
|
||||
not this.handlesDestructorsExplicitly() and
|
||||
exists(int id |
|
||||
id >= this.getFirstDestructorCallIndex() and
|
||||
child = this.getChild(id) and
|
||||
if id = max(int n | exists(this.getChild(n)))
|
||||
then result = this.getParent().getChildSuccessor(this, kind)
|
||||
else result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instruction to which control should flow if an exception is thrown
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -114,7 +114,11 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(ExitFunctionTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = EnterFunctionTag() and
|
||||
@@ -150,7 +154,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int paramIndex | child = this.getParameter(paramIndex) |
|
||||
if
|
||||
exists(func.getParameter(paramIndex + 1)) or
|
||||
@@ -379,7 +383,13 @@ abstract class TranslatedParameter extends TranslatedElement {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.hasIndirection()
|
||||
then result = this.getInstruction(InitializerIndirectStoreTag())
|
||||
else result = this.getInstruction(InitializerStoreTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
tag = InitializerVariableAddressTag() and
|
||||
result = this.getInstruction(InitializerStoreTag())
|
||||
@@ -397,7 +407,9 @@ abstract class TranslatedParameter extends TranslatedElement {
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = InitializerVariableAddressTag() and
|
||||
@@ -611,15 +623,23 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getLastChild().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result = this.getChild(max(int id | exists(this.getChild(id))))
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Function getFunction() { result = func }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
child = this.getChild(id) and
|
||||
if exists(this.getChild(id + 1))
|
||||
@@ -678,15 +698,23 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getChild(max(int id | exists(this.getChild(id)))).getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result = this.getChild(max(int id | exists(this.getChild(id))))
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Function getFunction() { result = func }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
child = this.getChild(id) and
|
||||
if exists(this.getChild(id + 1))
|
||||
@@ -728,7 +756,20 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if exists(this.getAChild())
|
||||
then
|
||||
result =
|
||||
max(TranslatedElement child, int id | child = this.getChild(id) | child order by id)
|
||||
.getFirstInstruction(any(GotoEdge goto))
|
||||
else result = this.getParent().getChildSuccessor(this, any(GotoEdge goto))
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result = this.getChild(max(int id | exists(this.getChild(id))))
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id | child = this.getChild(id) |
|
||||
if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = this.getChild(id2))
|
||||
then
|
||||
@@ -746,7 +787,7 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
private TranslatedThisReadEffect getTranslatedThisReadEffect(Function func) {
|
||||
@@ -760,9 +801,9 @@ private TranslatedParameterReadEffect getTranslatedParameterReadEffect(Parameter
|
||||
abstract class TranslatedReadEffect extends TranslatedElement {
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
@@ -772,6 +813,10 @@ abstract class TranslatedReadEffect extends TranslatedElement {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
opcode instanceof Opcode::ReturnIndirection and
|
||||
tag = OnlyInstructionTag() and
|
||||
|
||||
@@ -27,6 +27,10 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(ExitFunctionTag())
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int n) {
|
||||
n = 1 and
|
||||
result = getTranslatedInitialization(var.getInitializer().getExpr().getFullyConverted())
|
||||
@@ -58,7 +62,7 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
type = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = EnterFunctionTag() and
|
||||
@@ -81,7 +85,7 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getChild(1) and
|
||||
result = this.getInstruction(ReturnTag()) and
|
||||
kind instanceof GotoEdge
|
||||
|
||||
@@ -35,13 +35,19 @@ abstract class InitializationContext extends TranslatedElement {
|
||||
* declarations, `return` statements, and `throw` expressions.
|
||||
*/
|
||||
abstract class TranslatedVariableInitialization extends TranslatedElement, InitializationContext {
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
|
||||
TranslatedElement getChildInternal(int id) { id = 0 and result = this.getInitialization() }
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(InitializerVariableAddressTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInitialization().getALastInstruction()
|
||||
or
|
||||
not exists(this.getInitialization()) and result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = InitializerVariableAddressTag() and
|
||||
opcode instanceof Opcode::VariableAddress and
|
||||
@@ -53,7 +59,7 @@ abstract class TranslatedVariableInitialization extends TranslatedElement, Initi
|
||||
resultType = getTypeForPRValue(this.getTargetType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
(
|
||||
tag = InitializerVariableAddressTag() and
|
||||
if this.hasUninitializedInstruction()
|
||||
@@ -71,7 +77,7 @@ abstract class TranslatedVariableInitialization extends TranslatedElement, Initi
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getInitializationSuccessor(kind)
|
||||
}
|
||||
@@ -177,7 +183,11 @@ abstract class TranslatedListInitialization extends TranslatedInitialization, In
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getChild(max(int i | exists(this.getChild(i)))).getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getChild(index) and
|
||||
if exists(this.getChild(index + 1))
|
||||
@@ -190,7 +200,9 @@ abstract class TranslatedListInitialization extends TranslatedInitialization, In
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getTargetAddress() { result = this.getContext().getTargetAddress() }
|
||||
|
||||
@@ -260,18 +272,22 @@ class TranslatedSimpleDirectInitialization extends TranslatedDirectInitializatio
|
||||
not expr instanceof StringLiteral
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(InitializerStoreTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = InitializerStoreTag() and
|
||||
opcode instanceof Opcode::Store and
|
||||
resultType = getTypeForPRValue(this.getContext().getTargetType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = InitializerStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and
|
||||
result = this.getInstruction(InitializerStoreTag()) and
|
||||
kind instanceof GotoEdge
|
||||
@@ -296,6 +312,12 @@ class TranslatedSimpleDirectInitialization extends TranslatedDirectInitializatio
|
||||
class TranslatedStringLiteralInitialization extends TranslatedDirectInitialization {
|
||||
override StringLiteral expr;
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.zeroInitRange(_, _)
|
||||
then result = this.getInstruction(ZeroPadStringStoreTag())
|
||||
else result = this.getInstruction(InitializerStoreTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
// Load the string literal to make it a prvalue of type `char[len]`
|
||||
tag = InitializerLoadStringTag() and
|
||||
@@ -337,7 +359,7 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
tag = InitializerLoadStringTag() and
|
||||
result = this.getInstruction(InitializerStoreTag())
|
||||
@@ -367,7 +389,7 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and
|
||||
result = this.getInstruction(InitializerLoadStringTag()) and
|
||||
kind instanceof GotoEdge
|
||||
@@ -457,16 +479,22 @@ class TranslatedConstructorInitialization extends TranslatedDirectInitialization
|
||||
{
|
||||
override ConstructorCall expr;
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInitializer().getALastInstruction()
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getInitializer() }
|
||||
|
||||
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
none()
|
||||
}
|
||||
@@ -558,23 +586,29 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
|
||||
this = TTranslatedExplicitFieldInitialization(ast, field, expr, position)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInitialization().getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getTargetAddress() {
|
||||
result = this.getInstruction(this.getFieldAddressTag())
|
||||
}
|
||||
|
||||
override Type getTargetType() { result = field.getUnspecifiedType() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = this.getFieldAddressTag() and
|
||||
result = this.getInitialization().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getInitialization() }
|
||||
|
||||
private TranslatedInitialization getInitialization() {
|
||||
result = getTranslatedInitialization(expr)
|
||||
}
|
||||
@@ -595,6 +629,10 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
|
||||
{
|
||||
TranslatedFieldValueInitialization() { this = TTranslatedFieldValueInitialization(ast, field) }
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(this.getFieldDefaultValueStoreTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
TranslatedFieldInitialization.super.hasInstruction(opcode, tag, resultType)
|
||||
or
|
||||
@@ -607,7 +645,7 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
|
||||
resultType = getTypeForPRValue(field.getUnspecifiedType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = this.getFieldAddressTag() and
|
||||
@@ -639,7 +677,7 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
@@ -689,7 +727,7 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
|
||||
resultType = getTypeForGLValue(this.getElementType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = this.getElementIndexTag() and
|
||||
result = this.getInstruction(this.getElementAddressTag()) and
|
||||
kind instanceof GotoEdge
|
||||
@@ -743,20 +781,24 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
|
||||
this = TTranslatedExplicitElementInitialization(initList, elementIndex, position)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInitialization().getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getTargetAddress() {
|
||||
result = this.getInstruction(this.getElementAddressTag())
|
||||
}
|
||||
|
||||
override Type getTargetType() { result = this.getElementType() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessorInternal(tag, kind)
|
||||
or
|
||||
tag = this.getElementAddressTag() and
|
||||
result = this.getInitialization().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
@@ -788,6 +830,10 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
|
||||
this = TTranslatedElementValueInitialization(initList, elementIndex, elementCount)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(this.getElementDefaultValueStoreTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
TranslatedElementInitialization.super.hasInstruction(opcode, tag, resultType)
|
||||
or
|
||||
@@ -800,8 +846,8 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
|
||||
resultType = this.getDefaultValueType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessorInternal(tag, kind)
|
||||
or
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
@@ -836,7 +882,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
@@ -876,11 +922,13 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
|
||||
|
||||
final override Function getFunction() { result = getEnclosingFunction(call) }
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getStructorCall() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getStructorCall() }
|
||||
|
||||
final TranslatedExpr getStructorCall() { result = getTranslatedExpr(call) }
|
||||
}
|
||||
|
||||
@@ -894,13 +942,17 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getStructorCall().getALastInstruction()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::ConvertToNonVirtualBase and
|
||||
resultType = getTypeForGLValue(call.getTarget().getDeclaringType())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getStructorCall().getFirstInstruction(kind)
|
||||
}
|
||||
@@ -947,11 +999,17 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
|
||||
result = this.getStructorCall().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getStructorCall().getALastInstruction()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getReceiver() {
|
||||
result = getTranslatedFunction(this.getFunction()).getInitializeThisInstruction()
|
||||
@@ -1009,6 +1067,8 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() { none() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
@@ -1017,9 +1077,9 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
|
||||
|
||||
override Declaration getFunction() { result = this.getParent().getFunction() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
TranslatedConstructorBareInit getTranslatedConstructorBareInit(ConstructorInit init) {
|
||||
|
||||
@@ -138,7 +138,7 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
result = "1"
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
// Generate -1 -> Compare condition
|
||||
tag = TryExceptGenerateNegativeOne() and
|
||||
kind instanceof GotoEdge and
|
||||
@@ -202,7 +202,7 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
child = this.getTranslatedCondition() and
|
||||
result = this.getInstruction(TryExceptGenerateNegativeOne())
|
||||
@@ -211,6 +211,14 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getTranslatedHandler() }
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getTranslatedHandler().getALastInstruction()
|
||||
or
|
||||
result = this.getInstruction(UnwindTag())
|
||||
}
|
||||
|
||||
private TranslatedExpr getTranslatedCondition() {
|
||||
result = getTranslatedExpr(tryExcept.getCondition())
|
||||
}
|
||||
@@ -235,6 +243,27 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
|
||||
|
||||
TranslatedStmt() { this = TTranslatedStmt(stmt) }
|
||||
|
||||
abstract TranslatedElement getChildInternal(int id);
|
||||
|
||||
final override TranslatedElement getChild(int id) {
|
||||
result = this.getChildInternal(id)
|
||||
or
|
||||
exists(int destructorIndex |
|
||||
result.(TranslatedExpr).getExpr() = stmt.getImplicitDestructorCall(destructorIndex) and
|
||||
id = this.getFirstDestructorCallIndex() + destructorIndex
|
||||
)
|
||||
}
|
||||
|
||||
final override int getFirstDestructorCallIndex() {
|
||||
result = max(int childId | exists(this.getChildInternal(childId))) + 1
|
||||
or
|
||||
not exists(this.getChildInternal(_)) and result = 0
|
||||
}
|
||||
|
||||
final override predicate hasAnImplicitDestructorCall() {
|
||||
exists(stmt.getAnImplicitDestructorCall())
|
||||
}
|
||||
|
||||
final override string toString() { result = stmt.toString() }
|
||||
|
||||
final override Locatable getAst() { result = stmt }
|
||||
@@ -252,25 +281,29 @@ class TranslatedEmptyStmt extends TranslatedStmt {
|
||||
stmt instanceof SwitchCase
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
override TranslatedElement getChildInternal(int id) { none() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,7 +314,7 @@ class TranslatedEmptyStmt extends TranslatedStmt {
|
||||
class TranslatedDeclStmt extends TranslatedStmt {
|
||||
override DeclStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) { result = this.getDeclarationEntry(id) }
|
||||
override TranslatedElement getChildInternal(int id) { result = this.getDeclarationEntry(id) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
@@ -294,6 +327,12 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getChild(this.getChildCount() - 1).getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getChild(this.getChildCount() - 1) }
|
||||
|
||||
private int getChildCount() { result = count(this.getDeclarationEntry(_)) }
|
||||
|
||||
IRDeclarationEntry getIRDeclarationEntry(int index) {
|
||||
@@ -318,9 +357,9 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getDeclarationEntry(index) and
|
||||
if index = (this.getChildCount() - 1)
|
||||
@@ -335,7 +374,7 @@ class TranslatedExprStmt extends TranslatedStmt {
|
||||
|
||||
TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr().getFullyConverted()) }
|
||||
|
||||
override TranslatedElement getChild(int id) { id = 0 and result = this.getExpr() }
|
||||
override TranslatedElement getChildInternal(int id) { id = 0 and result = this.getExpr() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
@@ -345,9 +384,15 @@ class TranslatedExprStmt extends TranslatedStmt {
|
||||
result = this.getExpr().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getExpr().getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override TranslatedElement getLastChild() { result = this.getExpr() }
|
||||
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getExpr() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
@@ -359,6 +404,21 @@ abstract class TranslatedReturnStmt extends TranslatedStmt {
|
||||
final TranslatedFunction getEnclosingFunction() {
|
||||
result = getTranslatedFunction(stmt.getEnclosingFunction())
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
child = this.getChild(id) and
|
||||
id >= this.getFirstDestructorCallIndex() and
|
||||
(
|
||||
result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
or
|
||||
not exists(this.getChild(id + 1)) and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,7 +428,19 @@ class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariable
|
||||
TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) }
|
||||
|
||||
final override Instruction getInitializationSuccessor(EdgeKind kind) {
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(1).getFirstInstruction(kind)
|
||||
else result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
result = TranslatedVariableInitialization.super.getChildSuccessorInternal(child, kind)
|
||||
or
|
||||
result = TranslatedReturnStmt.super.getChildSuccessorInternal(child, kind)
|
||||
}
|
||||
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
result = TranslatedVariableInitialization.super.getChildInternal(id)
|
||||
}
|
||||
|
||||
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
|
||||
@@ -390,7 +462,7 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
|
||||
stmt.hasExpr() and not hasReturnValue(stmt.getEnclosingFunction())
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and
|
||||
result = this.getExpr()
|
||||
}
|
||||
@@ -399,21 +471,31 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
|
||||
result = this.getExpr().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(max(int id | exists(this.getChild(id)))).getALastInstruction()
|
||||
else result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(1).getFirstInstruction(kind)
|
||||
else result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getExpr() and
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
or
|
||||
result = TranslatedReturnStmt.super.getChildSuccessorInternal(child, kind)
|
||||
}
|
||||
|
||||
private TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr()) }
|
||||
@@ -428,25 +510,43 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
|
||||
not stmt.hasExpr() and not hasReturnValue(stmt.getEnclosingFunction())
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
override TranslatedElement getChildInternal(int id) { none() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(max(int id | exists(this.getChild(id)))).getALastInstruction()
|
||||
else result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(0).getFirstInstruction(kind)
|
||||
else result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
this.getChild(id) = child and
|
||||
(
|
||||
result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
or
|
||||
not exists(this.getChild(id + 1)) and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -464,6 +564,16 @@ class TranslatedNoValueReturnStmt extends TranslatedReturnStmt, TranslatedVariab
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
result = TranslatedVariableInitialization.super.getChildInternal(id)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
result = TranslatedVariableInitialization.super.getChildSuccessorInternal(child, kind)
|
||||
or
|
||||
result = TranslatedReturnStmt.super.getChildSuccessorInternal(child, kind)
|
||||
}
|
||||
|
||||
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
|
||||
|
||||
final override TranslatedInitialization getInitialization() { none() }
|
||||
@@ -518,7 +628,7 @@ private class TryOrMicrosoftTryStmt extends Stmt {
|
||||
class TranslatedTryStmt extends TranslatedStmt {
|
||||
override TryOrMicrosoftTryStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getBody()
|
||||
or
|
||||
result = this.getHandler(id - 1)
|
||||
@@ -531,13 +641,23 @@ class TranslatedTryStmt extends TranslatedStmt {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getBody().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getLastChild().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
if exists(this.getFinally())
|
||||
then result = this.getFinally()
|
||||
else result = [this.getBody(), this.getHandler(_)]
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
// All non-finally children go to the successor of the `try` if
|
||||
// there is no finally block, but if there is a finally block
|
||||
// then we go to that one.
|
||||
@@ -581,7 +701,7 @@ class TranslatedTryStmt extends TranslatedStmt {
|
||||
class TranslatedBlock extends TranslatedStmt {
|
||||
override BlockStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) { result = this.getStmt(id) }
|
||||
override TranslatedElement getChildInternal(int id) { result = this.getStmt(id) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
this.isEmpty() and
|
||||
@@ -596,18 +716,26 @@ class TranslatedBlock extends TranslatedStmt {
|
||||
else result = this.getStmt(0).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.isEmpty()
|
||||
then result = this.getInstruction(OnlyInstructionTag())
|
||||
else result = this.getStmt(this.getStmtCount() - 1).getFirstInstruction(any(GotoEdge goto))
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getStmt(this.getStmtCount() - 1) }
|
||||
|
||||
private predicate isEmpty() { not exists(stmt.getStmt(0)) }
|
||||
|
||||
private TranslatedStmt getStmt(int index) { result = getTranslatedStmt(stmt.getStmt(index)) }
|
||||
|
||||
private int getStmtCount() { result = stmt.getNumStmt() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getStmt(index) and
|
||||
if index = (this.getStmtCount() - 1)
|
||||
@@ -623,14 +751,20 @@ class TranslatedBlock extends TranslatedStmt {
|
||||
abstract class TranslatedHandler extends TranslatedStmt {
|
||||
override Handler stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) { id = 1 and result = this.getBlock() }
|
||||
override TranslatedElement getChildInternal(int id) { id = 1 and result = this.getBlock() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(CatchTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getBlock().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getBlock() }
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getBlock() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
@@ -656,20 +790,20 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
result = super.getChild(id)
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
result = super.getChildInternal(id)
|
||||
or
|
||||
id = 0 and result = this.getParameter()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
result = super.getChildSuccessor(child, kind)
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
result = super.getChildSuccessorInternal(child, kind)
|
||||
or
|
||||
child = this.getParameter() and
|
||||
result = this.getBlock().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = CatchTag() and
|
||||
(
|
||||
kind instanceof GotoEdge and
|
||||
@@ -702,7 +836,7 @@ class TranslatedCatchAnyHandler extends TranslatedHandler {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = CatchTag() and
|
||||
result = this.getBlock().getFirstInstruction(kind)
|
||||
}
|
||||
@@ -717,7 +851,13 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getElse().getALastInstruction() or result = this.getThen().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getElse() or result = this.getThen() }
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getCondition()
|
||||
@@ -747,7 +887,7 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
||||
|
||||
private predicate hasElse() { exists(stmt.getElse()) }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
@@ -761,7 +901,7 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
@@ -783,7 +923,7 @@ class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getCondition()
|
||||
@@ -813,7 +953,7 @@ class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||
|
||||
private predicate hasElse() { exists(stmt.getElse()) }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
@@ -827,7 +967,7 @@ class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
@@ -838,11 +978,23 @@ class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getThen().getALastInstruction()
|
||||
or
|
||||
result = this.getElse().getALastInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
override Loop stmt;
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getCondition().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getCondition() }
|
||||
|
||||
final TranslatedCondition getCondition() {
|
||||
result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
|
||||
}
|
||||
@@ -857,7 +1009,7 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
|
||||
final predicate hasCondition() { exists(stmt.getCondition()) }
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getCondition()
|
||||
or
|
||||
id = 1 and result = this.getBody()
|
||||
@@ -867,13 +1019,15 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and result = this.getBody().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
@@ -882,13 +1036,36 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
class TranslatedWhileStmt extends TranslatedLoop {
|
||||
TranslatedWhileStmt() { stmt instanceof WhileStmt }
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getCondition()
|
||||
or
|
||||
id = 1 and result = this.getBody()
|
||||
or
|
||||
exists(int n |
|
||||
result.getAst() = stmt.getImplicitDestructorCall(n) and
|
||||
id = 2 + n
|
||||
)
|
||||
}
|
||||
|
||||
override predicate handlesDestructorsExplicitly() { any() }
|
||||
|
||||
final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getBody() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
child = this.getChild(this.getFirstDestructorCallIndex()) and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -899,7 +1076,7 @@ class TranslatedDoStmt extends TranslatedLoop {
|
||||
result = this.getBody().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getBody() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
@@ -908,7 +1085,16 @@ class TranslatedDoStmt extends TranslatedLoop {
|
||||
class TranslatedForStmt extends TranslatedLoop {
|
||||
override ForStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override predicate handlesDestructorsExplicitly() { any() }
|
||||
|
||||
final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getCondition()
|
||||
@@ -916,6 +1102,11 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
id = 2 and result = this.getUpdate()
|
||||
or
|
||||
id = 3 and result = this.getBody()
|
||||
or
|
||||
exists(int n |
|
||||
result.getAst() = stmt.getImplicitDestructorCall(n) and
|
||||
id = 4 + n
|
||||
)
|
||||
}
|
||||
|
||||
private TranslatedStmt getInitialization() {
|
||||
@@ -934,7 +1125,7 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
@@ -946,6 +1137,19 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
)
|
||||
or
|
||||
child = this.getUpdate() and result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
exists(int destructorId |
|
||||
destructorId >= this.getFirstDestructorCallIndex() and
|
||||
child = this.getChild(destructorId) and
|
||||
result = this.getChild(destructorId + 1).getFirstInstruction(kind)
|
||||
)
|
||||
or
|
||||
exists(int lastDestructorIndex |
|
||||
lastDestructorIndex =
|
||||
max(int n | exists(this.getChild(n)) and n >= this.getFirstDestructorCallIndex()) and
|
||||
child = this.getChild(lastDestructorIndex) and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,7 +1163,7 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
||||
override RangeBasedForStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getRangeVariableDeclStmt()
|
||||
@@ -988,7 +1192,13 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getFirstRangeVariableDeclStmtInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getCondition().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getCondition() }
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstRangeVariableDeclStmtInstruction(kind)
|
||||
or
|
||||
@@ -1012,7 +1222,7 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
@@ -1070,7 +1280,11 @@ class TranslatedJumpStmt extends TranslatedStmt {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override TranslatedElement getChildInternal(int id) { none() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
@@ -1078,12 +1292,12 @@ class TranslatedJumpStmt extends TranslatedStmt {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
private EdgeKind getCaseEdge(SwitchCase switchCase) {
|
||||
@@ -1114,7 +1328,13 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
else result = this.getFirstExprInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getBody().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getBody() }
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getExpr()
|
||||
@@ -1140,7 +1360,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
result = this.getExpr().getResult()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = SwitchBranchTag() and
|
||||
exists(SwitchCase switchCase |
|
||||
switchCase = stmt.getASwitchCase() and
|
||||
@@ -1154,7 +1374,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
result = this.getParent().getChildSuccessor(this, any(GotoEdge edge))
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstExprInstruction(kind)
|
||||
or
|
||||
@@ -1169,7 +1389,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
class TranslatedAsmStmt extends TranslatedStmt {
|
||||
override AsmStmt stmt;
|
||||
|
||||
override TranslatedExpr getChild(int id) {
|
||||
override TranslatedExpr getChildInternal(int id) {
|
||||
result = getTranslatedExpr(stmt.getChild(id).(Expr).getFullyConverted())
|
||||
}
|
||||
|
||||
@@ -1181,6 +1401,8 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() { result = this.getInstruction(AsmTag()) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = AsmTag() and
|
||||
opcode instanceof Opcode::InlineAsm and
|
||||
@@ -1191,7 +1413,7 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
exists(int index |
|
||||
tag = AsmTag() and
|
||||
operandTag = asmOperand(index) and
|
||||
result = this.getChild(index).getResult()
|
||||
result = this.getChildInternal(index).getResult()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1203,12 +1425,12 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
result = getUnknownType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = AsmTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getChild(index) and
|
||||
if exists(this.getChild(index + 1))
|
||||
@@ -1223,7 +1445,7 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
class TranslatedVlaDimensionStmt extends TranslatedStmt {
|
||||
override VlaDimensionStmt stmt;
|
||||
|
||||
override TranslatedExpr getChild(int id) {
|
||||
override TranslatedExpr getChildInternal(int id) {
|
||||
id = 0 and
|
||||
result = getTranslatedExpr(stmt.getDimensionExpr().getFullyConverted())
|
||||
}
|
||||
@@ -1232,13 +1454,19 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt {
|
||||
result = this.getChild(0).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getChild(0).getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getChild(0) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getChild(0) and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
@@ -1247,13 +1475,17 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt {
|
||||
class TranslatedVlaDeclarationStmt extends TranslatedStmt {
|
||||
override VlaDeclStmt stmt;
|
||||
|
||||
override TranslatedExpr getChild(int id) { none() }
|
||||
override TranslatedExpr getChildInternal(int id) { none() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
// TODO: This needs a new kind of instruction that represents initialization of a VLA.
|
||||
// For now we just emit a `NoOp` instruction so that the CFG isn't incomplete.
|
||||
@@ -1262,10 +1494,10 @@ class TranslatedVlaDeclarationStmt extends TranslatedStmt {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ private int getTypeSizeWorkaround(Type type) {
|
||||
exists(Type unspecifiedType |
|
||||
unspecifiedType = type.getUnspecifiedType() and
|
||||
(
|
||||
unspecifiedType instanceof FunctionReferenceType and
|
||||
(unspecifiedType instanceof FunctionReferenceType or unspecifiedType instanceof RoutineType) and
|
||||
result = getPointerSize()
|
||||
or
|
||||
exists(PointerToMemberType ptmType |
|
||||
@@ -176,7 +176,7 @@ private IRType getIRTypeForPRValue(Type type) {
|
||||
isPointerIshType(unspecifiedType) and
|
||||
result.(IRAddressType).getByteSize() = getTypeSize(unspecifiedType)
|
||||
or
|
||||
unspecifiedType instanceof FunctionPointerIshType and
|
||||
(unspecifiedType instanceof FunctionPointerIshType or unspecifiedType instanceof RoutineType) and
|
||||
result.(IRFunctionAddressType).getByteSize() = getTypeSize(type)
|
||||
or
|
||||
unspecifiedType instanceof VoidType and result instanceof IRVoidType
|
||||
|
||||
@@ -15,6 +15,8 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF
|
||||
i.isParameter(3) and o.isParameterDeref(0)
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput o) { o.isParameterDeref(3) }
|
||||
|
||||
override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] }
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
|
||||
|
||||
@@ -27,6 +27,8 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(2) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameter(2) and
|
||||
output.isParameterDeref(0)
|
||||
|
||||
@@ -20,6 +20,8 @@ private class InetAton extends TaintFunction, ArrayFunction {
|
||||
output.isParameterDeref(1)
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(1) }
|
||||
|
||||
override predicate hasArrayInput(int bufParam) { bufParam = 0 }
|
||||
|
||||
override predicate hasArrayOutput(int bufParam) { bufParam = 1 }
|
||||
|
||||
@@ -168,3 +168,57 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A destructor assocaited with a smart pointer. */
|
||||
private class SmartPtrDestructor extends Destructor, SideEffectFunction, AliasFunction {
|
||||
SmartPtr declaringType;
|
||||
|
||||
SmartPtrDestructor() {
|
||||
declaringType = this.getDeclaringType() and not this.isFromUninstantiatedTemplate(_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the destructor associated with the base type of this smart pointer.
|
||||
*/
|
||||
private Destructor getBaseTypeDestructor() {
|
||||
result.getDeclaringType() = declaringType.getBaseType()
|
||||
}
|
||||
|
||||
override predicate hasOnlySpecificReadSideEffects() {
|
||||
this.getBaseTypeDestructor().(SideEffectFunction).hasOnlySpecificReadSideEffects()
|
||||
or
|
||||
// If there's no declared destructor for the base type then it won't have
|
||||
// any strange read side effects.
|
||||
not exists(this.getBaseTypeDestructor())
|
||||
}
|
||||
|
||||
override predicate hasOnlySpecificWriteSideEffects() {
|
||||
this.getBaseTypeDestructor().(SideEffectFunction).hasOnlySpecificWriteSideEffects()
|
||||
or
|
||||
// If there's no declared destructor for the base type then it won't have
|
||||
// any strange write side effects.
|
||||
not exists(this.getBaseTypeDestructor())
|
||||
}
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
i = -1 and buffer = false
|
||||
}
|
||||
|
||||
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
|
||||
i = -1 and buffer = false and mustWrite = true
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int index) {
|
||||
this.getBaseTypeDestructor().(AliasFunction).parameterNeverEscapes(index)
|
||||
or
|
||||
// If there's no declared destructor for the base type then it won't cause
|
||||
// anything to escape.
|
||||
not exists(this.getBaseTypeDestructor()) and
|
||||
index = -1
|
||||
}
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) {
|
||||
// A destructor call does not have a return value
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,8 @@ private class StdSequenceContainerData extends TaintFunction {
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,6 +149,8 @@ private class StdSequenceContainerPushModel extends StdSequenceContainerPush, Ta
|
||||
input.isParameterDeref(0) and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,6 +211,8 @@ private class StdSequenceContainerInsertModel extends StdSequenceContainerInsert
|
||||
output.isReturnValue()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,6 +269,8 @@ private class StdSequenceContainerAt extends TaintFunction {
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,6 +305,8 @@ private class StdSequenceEmplaceModel extends StdSequenceEmplace, TaintFunction
|
||||
output.isReturnValue()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,6 +345,8 @@ private class StdSequenceEmplaceBackModel extends StdSequenceEmplaceBack, TaintF
|
||||
input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Iterator
|
||||
|
||||
/**
|
||||
@@ -53,6 +54,8 @@ private class StdMapInsert extends TaintFunction {
|
||||
output.isReturnValue()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,6 +78,8 @@ private class StdMapEmplace extends TaintFunction {
|
||||
input.isQualifierObject() and
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,6 +107,8 @@ private class StdMapTryEmplace extends TaintFunction {
|
||||
input.isQualifierObject() and
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,6 +122,8 @@ private class StdMapMerge extends TaintFunction {
|
||||
input.isParameterDeref(0) and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,6 +141,8 @@ private class StdMapAt extends TaintFunction {
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,6 +61,8 @@ private class StdSetInsert extends TaintFunction {
|
||||
output.isReturnValue()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,6 +84,8 @@ private class StdSetEmplace extends TaintFunction {
|
||||
input.isQualifierObject() and
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,6 +99,8 @@ private class StdSetMerge extends TaintFunction {
|
||||
input.isParameterDeref(0) and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -129,6 +129,8 @@ private class StdStringDataModel extends StdStringData, StdStringTaintFunction {
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,6 +144,8 @@ private class StdStringPush extends StdStringTaintFunction {
|
||||
input.isParameter(0) and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,6 +208,8 @@ private class StdStringAppend extends StdStringTaintFunction {
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,6 +243,8 @@ private class StdStringInsert extends StdStringTaintFunction {
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,6 +313,8 @@ private class StdStringAt extends StdStringTaintFunction {
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -338,6 +348,8 @@ private class StdIStreamIn extends DataFlowFunction, TaintFunction {
|
||||
input.isReturnValueDeref() and
|
||||
output.isQualifierObject()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,6 +370,8 @@ private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
|
||||
output.isReturnValueDeref()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from first parameter to second parameter
|
||||
input.isParameterDeref(0) and
|
||||
@@ -403,6 +417,8 @@ private class StdIStreamRead extends DataFlowFunction, TaintFunction {
|
||||
output.isReturnValueDeref()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from qualifier to first parameter
|
||||
input.isQualifierObject() and
|
||||
@@ -442,6 +458,8 @@ private class StdIStreamPutBack extends DataFlowFunction, TaintFunction {
|
||||
output.isReturnValueDeref()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from first parameter (value or pointer) to qualifier
|
||||
input.isParameter(0) and
|
||||
@@ -478,6 +496,8 @@ private class StdIStreamGetLine extends DataFlowFunction, TaintFunction {
|
||||
output.isReturnValueDeref()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from qualifier to first parameter
|
||||
input.isQualifierObject() and
|
||||
@@ -540,6 +560,8 @@ private class StdOStreamOut extends DataFlowFunction, TaintFunction {
|
||||
output.isReturnValueDeref()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from first parameter (value or pointer) to qualifier
|
||||
input.isParameter(0) and
|
||||
@@ -579,6 +601,8 @@ private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
|
||||
output.isReturnValueDeref()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(0) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from second parameter to first parameter
|
||||
input.isParameterDeref(1) and
|
||||
@@ -672,6 +696,8 @@ private class StdStreamFunction extends DataFlowFunction, TaintFunction {
|
||||
output.isReturnValueDeref()
|
||||
}
|
||||
|
||||
override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// reverse flow from returned reference to the qualifier
|
||||
input.isReturnValueDeref() and
|
||||
|
||||
@@ -36,6 +36,8 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio
|
||||
input.isParameter(index) and output.isReturnValue()
|
||||
or
|
||||
input.isParameterDeref(index) and output.isReturnValueDeref()
|
||||
or
|
||||
input.isParameterDeref(index) and output.isParameterDeref(index)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import semmle.code.cpp.Function
|
||||
import FunctionInputsAndOutputs
|
||||
import semmle.code.cpp.models.Models
|
||||
import PartialFlow
|
||||
|
||||
/**
|
||||
* A library function for which a value is or may be copied from a parameter
|
||||
@@ -18,7 +19,7 @@ import semmle.code.cpp.models.Models
|
||||
* Note that this does not include partial copying of values or partial writes
|
||||
* to destinations; that is covered by `TaintModel.qll`.
|
||||
*/
|
||||
abstract class DataFlowFunction extends Function {
|
||||
abstract class DataFlowFunction extends PartialFlowFunction {
|
||||
/**
|
||||
* Holds if data can be copied from the argument, qualifier, or buffer
|
||||
* represented by `input` to the return value or buffer represented by
|
||||
|
||||
31
cpp/ql/lib/semmle/code/cpp/models/interfaces/PartialFlow.qll
Normal file
31
cpp/ql/lib/semmle/code/cpp/models/interfaces/PartialFlow.qll
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Provides an abstract class to override the implicit assumption that a
|
||||
* dataflow/taint-tracking model always fully override the parameters they are
|
||||
* are modeled as writing to. To use this QL library, create a QL class
|
||||
* extending `PartialFlowFunction` with a characteristic predicate that selects
|
||||
* the function or set of functions you are modeling and override the
|
||||
* `isPartialWrite` predicate.
|
||||
*
|
||||
* Note: Since both `DataFlowFunction` and `TaintFunction` extend this class
|
||||
* you don't need to explicitly add this as a base class if your QL class
|
||||
* already extends either `DataFlowFunction` or `TaintFunction`.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.Function
|
||||
import FunctionInputsAndOutputs
|
||||
import semmle.code.cpp.models.Models
|
||||
|
||||
/**
|
||||
* A function that may update part of a `FunctionOutput`.
|
||||
*
|
||||
* For example, the destination argument of `strcat` only updates part of the
|
||||
* argument.
|
||||
*/
|
||||
abstract class PartialFlowFunction extends Function {
|
||||
/**
|
||||
* Holds if the write to output does not overwrite the entire value that was
|
||||
* there before, or does not do so reliably. For example the destination
|
||||
* argument of `strcat` is modified but not overwritten.
|
||||
*/
|
||||
predicate isPartialWrite(FunctionOutput output) { none() }
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
import semmle.code.cpp.Function
|
||||
import FunctionInputsAndOutputs
|
||||
import semmle.code.cpp.models.Models
|
||||
import PartialFlow
|
||||
|
||||
/**
|
||||
* A library function for which a taint-tracking library should propagate taint
|
||||
@@ -23,7 +24,7 @@ import semmle.code.cpp.models.Models
|
||||
* altered (for example copying a string with `strncpy`), this is also considered
|
||||
* data flow.
|
||||
*/
|
||||
abstract class TaintFunction extends Function {
|
||||
abstract class TaintFunction extends PartialFlowFunction {
|
||||
/**
|
||||
* Holds if data passed into the argument, qualifier, or buffer represented by
|
||||
* `input` influences the return value or buffer represented by `output`
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
## 0.9.8
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.9.7
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.9.6
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "non-constant format string" query (`cpp/non-constant-format`) has been converted to a `path-problem` query.
|
||||
* The new C/C++ dataflow and taint-tracking libraries (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now implicitly assume that dataflow and taint modelled via `DataFlowFunction` and `TaintFunction` always fully overwrite their buffers and thus act as flow barriers. As a result, many dataflow and taint-tracking queries now produce fewer false positives. To remove this assumption and go back to the previous behavior for a given model, one can override the new `isPartialWrite` predicate.
|
||||
|
||||
## 0.9.5
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* type `const char*` it is still considered non-constant if the value is not coming from a string
|
||||
* literal. For example, for a parameter with type `const char*` of an exported function that is
|
||||
* used as a format string, there is no way to ensure the originating value was a string literal.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity recommendation
|
||||
* @security-severity 9.3
|
||||
* @precision high
|
||||
@@ -26,6 +26,7 @@ import semmle.code.cpp.ir.dataflow.internal.ModelUtil
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.ir.IR
|
||||
import NonConstFlow::PathGraph
|
||||
|
||||
class UncalledFunction extends Function {
|
||||
UncalledFunction() {
|
||||
@@ -68,7 +69,10 @@ predicate isNonConst(DataFlow::Node node) {
|
||||
// Parameters of uncalled functions that aren't const
|
||||
exists(UncalledFunction f, Parameter p |
|
||||
f.getAParameter() = p and
|
||||
p = node.asParameter()
|
||||
p = node.asParameter() and
|
||||
// Ignore main's argv parameter as it is already considered a `FlowSource`
|
||||
// not ignoring it will result in path redundancies
|
||||
(f.getName() = "main" implies p != f.getParameter(1))
|
||||
)
|
||||
or
|
||||
// Consider as an input any out arg of a function or a function's return where the function is not:
|
||||
@@ -127,11 +131,13 @@ module NonConstFlowConfig implements DataFlow::ConfigSig {
|
||||
|
||||
module NonConstFlow = TaintTracking::Global<NonConstFlowConfig>;
|
||||
|
||||
from FormattingFunctionCall call, Expr formatString, DataFlow::Node sink
|
||||
from
|
||||
FormattingFunctionCall call, Expr formatString, NonConstFlow::PathNode sink,
|
||||
NonConstFlow::PathNode source
|
||||
where
|
||||
isSinkImpl(sink.getNode(), formatString) and
|
||||
call.getArgument(call.getFormatParameterIndex()) = formatString and
|
||||
NonConstFlow::flowTo(sink) and
|
||||
isSinkImpl(sink, formatString)
|
||||
select formatString,
|
||||
"The format string argument to " + call.getTarget().getName() +
|
||||
" should be constant to prevent security issues and other potential errors."
|
||||
NonConstFlow::flowPath(source, sink)
|
||||
select sink.getNode(), source, sink,
|
||||
"The format string argument to $@ has a source which cannot be " +
|
||||
"verified to originate from a string literal.", call, call.getTarget().getName()
|
||||
|
||||
6
cpp/ql/src/change-notes/released/0.9.6.md
Normal file
6
cpp/ql/src/change-notes/released/0.9.6.md
Normal file
@@ -0,0 +1,6 @@
|
||||
## 0.9.6
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "non-constant format string" query (`cpp/non-constant-format`) has been converted to a `path-problem` query.
|
||||
* The new C/C++ dataflow and taint-tracking libraries (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now implicitly assume that dataflow and taint modelled via `DataFlowFunction` and `TaintFunction` always fully overwrite their buffers and thus act as flow barriers. As a result, many dataflow and taint-tracking queries now produce fewer false positives. To remove this assumption and go back to the previous behavior for a given model, one can override the new `isPartialWrite` predicate.
|
||||
3
cpp/ql/src/change-notes/released/0.9.7.md
Normal file
3
cpp/ql/src/change-notes/released/0.9.7.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.9.7
|
||||
|
||||
No user-facing changes.
|
||||
3
cpp/ql/src/change-notes/released/0.9.8.md
Normal file
3
cpp/ql/src/change-notes/released/0.9.8.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.9.8
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.9.5
|
||||
lastReleaseVersion: 0.9.8
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.9.5
|
||||
version: 0.9.8
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -33,11 +33,14 @@ edges
|
||||
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:83:9:83:11 | *arr [p] | provenance | |
|
||||
| test.cpp:79:9:79:11 | *arr [p] | test.cpp:79:14:79:14 | p | provenance | |
|
||||
| test.cpp:83:9:83:11 | *arr [p] | test.cpp:83:14:83:14 | p | provenance | |
|
||||
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:87:28:87:30 | *arr [p] | provenance | |
|
||||
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:89:9:89:11 | *arr [p] | provenance | |
|
||||
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:93:9:93:11 | *arr [p] | provenance | |
|
||||
| test.cpp:89:9:89:11 | *arr [p] | test.cpp:89:14:89:14 | p | provenance | |
|
||||
| test.cpp:93:9:93:11 | *arr [p] | test.cpp:93:14:93:14 | p | provenance | |
|
||||
| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:87:28:87:30 | *arr [p] | provenance | |
|
||||
| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:98:18:98:27 | test6_callee output argument [p] | provenance | |
|
||||
| test.cpp:98:18:98:27 | test6_callee output argument [p] | test.cpp:98:18:98:27 | *call to mk_array_p [p] | provenance | |
|
||||
nodes
|
||||
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
|
||||
| test.cpp:6:9:6:11 | arr | semmle.label | arr |
|
||||
@@ -77,12 +80,15 @@ nodes
|
||||
| test.cpp:83:9:83:11 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:83:14:83:14 | p | semmle.label | p |
|
||||
| test.cpp:87:28:87:30 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:87:28:87:30 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:89:9:89:11 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:89:14:89:14 | p | semmle.label | p |
|
||||
| test.cpp:93:9:93:11 | *arr [p] | semmle.label | *arr [p] |
|
||||
| test.cpp:93:14:93:14 | p | semmle.label | p |
|
||||
| test.cpp:98:18:98:27 | *call to mk_array_p [p] | semmle.label | *call to mk_array_p [p] |
|
||||
| test.cpp:98:18:98:27 | test6_callee output argument [p] | semmle.label | test6_callee output argument [p] |
|
||||
subpaths
|
||||
| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:87:28:87:30 | *arr [p] | test.cpp:87:28:87:30 | *arr [p] | test.cpp:98:18:98:27 | test6_callee output argument [p] |
|
||||
#select
|
||||
| test.cpp:10:9:10:11 | arr | test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr | Off-by one error allocated at $@ bounded by $@. | test.cpp:4:17:4:22 | call to malloc | call to malloc | test.cpp:4:24:4:27 | size | size |
|
||||
| test.cpp:10:9:10:11 | arr | test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr | Off-by one error allocated at $@ bounded by $@. | test.cpp:4:17:4:22 | call to malloc | call to malloc | test.cpp:4:24:4:27 | size | size |
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace std {
|
||||
};
|
||||
|
||||
template<class Container>
|
||||
constexpr back_insert_iterator<Container> back_inserter(Container& x) {
|
||||
constexpr back_insert_iterator<Container> back_inserter(Container& x) { // $ ir-def=*x
|
||||
return back_insert_iterator<Container>(x);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace std {
|
||||
constexpr front_insert_iterator operator++(int);
|
||||
};
|
||||
template<class Container>
|
||||
constexpr front_insert_iterator<Container> front_inserter(Container& x) {
|
||||
constexpr front_insert_iterator<Container> front_inserter(Container& x) { // $ ir-def=*x
|
||||
return front_insert_iterator<Container>(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
| arguments.c | 3 | --edg |
|
||||
| arguments.c | 4 | --disable_system_macros |
|
||||
| arguments.c | 5 | --edg |
|
||||
| arguments.c | 6 | --verbosity |
|
||||
| arguments.c | 6 | --codeql-verbosity |
|
||||
| arguments.c | 7 | --edg |
|
||||
| arguments.c | 8 | 2 |
|
||||
| arguments.c | 9 | --edg |
|
||||
|
||||
@@ -56,7 +56,7 @@ void bg_stackstruct(XY s1, XY s2) {
|
||||
}
|
||||
}
|
||||
|
||||
void bg_structptr(XY *p1, XY *p2) { // $ ast-def=p1 ast-def=p2
|
||||
void bg_structptr(XY *p1, XY *p2) { // $ ast-def=p1 ast-def=p2 ir-def=*p1 ir-def=*p2
|
||||
p1->x = source();
|
||||
if (guarded(p1->x)) {
|
||||
sink(p1->x); // $ SPURIOUS: ast
|
||||
|
||||
@@ -8,7 +8,7 @@ struct twoIntFields {
|
||||
int getFirst() { return m1; }
|
||||
};
|
||||
|
||||
void following_pointers( // $ ast-def=sourceStruct1_ptr
|
||||
void following_pointers( // $ ast-def=sourceStruct1_ptr ir-def=*cleanArray1 ir-def=*sourceArray1 ir-def=*sourceStruct1_ptr
|
||||
int sourceArray1[],
|
||||
int cleanArray1[],
|
||||
twoIntFields sourceStruct1,
|
||||
|
||||
@@ -25,7 +25,7 @@ struct Bottom : Middle {
|
||||
void notSink(int x) override { }
|
||||
};
|
||||
|
||||
void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { // $ ast-def=bottomPtr ast-def=bottomRef
|
||||
void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { // $ ast-def=bottomPtr ast-def=bottomRef ir-def=*bottomPtr ir-def=*bottomRef
|
||||
Top *topPtr = bottomPtr, &topRef = bottomRef;
|
||||
|
||||
sink(topPtr->isSource1()); // $ ir MISSING: ast
|
||||
@@ -65,11 +65,11 @@ Top *allocateBottom() {
|
||||
return new Bottom();
|
||||
}
|
||||
|
||||
void callSinkByPointer(Top *top) { // $ ast-def=top
|
||||
void callSinkByPointer(Top *top) { // $ ast-def=top ir-def=*top
|
||||
top->isSink(source()); // leads to MISSING from ast
|
||||
}
|
||||
|
||||
void callSinkByReference(Top &top) { // $ ast-def=top
|
||||
void callSinkByReference(Top &top) { // $ ast-def=top ir-def=*top
|
||||
top.isSink(source()); // leads to MISSING from ast
|
||||
}
|
||||
|
||||
@@ -81,11 +81,11 @@ void globalVirtualDispatch() {
|
||||
x->isSink(source()); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
Top *identity(Top *top) { // $ ast-def=top
|
||||
Top *identity(Top *top) { // $ ast-def=top ir-def=*top
|
||||
return top;
|
||||
}
|
||||
|
||||
void callIdentityFunctions(Top *top, Bottom *bottom) { // $ ast-def=bottom ast-def=top
|
||||
void callIdentityFunctions(Top *top, Bottom *bottom) { // $ ast-def=bottom ast-def=top ir-def=*bottom ir-def=*top
|
||||
identity(bottom)->isSink(source()); // $ MISSING: ast,ir
|
||||
identity(top)->isSink(source()); // no flow
|
||||
}
|
||||
@@ -120,7 +120,7 @@ namespace virtual_inheritance {
|
||||
struct Bottom : Middle {
|
||||
};
|
||||
|
||||
void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { // $ ast-def=bottomPtr ast-def=bottomRef
|
||||
void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { // $ ast-def=bottomPtr ast-def=bottomRef ir-def=*bottomPtr ir-def=*bottomRef
|
||||
// Because the inheritance from `Top` is virtual, the following casts go
|
||||
// directly from `Bottom` to `Top`, skipping `Middle`. That means we don't
|
||||
// get flow from a `Middle` value to the call qualifier.
|
||||
|
||||
@@ -12,7 +12,7 @@ typedef struct
|
||||
char isTrue;
|
||||
} MyBool;
|
||||
|
||||
void myTest_with_local_flow(MyBool *b, int pos) // $ ast-def=b
|
||||
void myTest_with_local_flow(MyBool *b, int pos) // $ ast-def=b ir-def=*b
|
||||
{
|
||||
MyCoords coords = {0};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ void source_ref(int *toTaint) { // $ ir-def=*toTaint ast-def=toTaint
|
||||
void source_ref(char *toTaint) { // $ ir-def=*toTaint ast-def=toTaint
|
||||
*toTaint = source();
|
||||
}
|
||||
void modify_copy(int* ptr) { // $ ast-def=ptr
|
||||
void modify_copy(int* ptr) { // $ ast-def=ptr ir-def=*ptr
|
||||
int deref = *ptr;
|
||||
int* other = &deref;
|
||||
source_ref(other);
|
||||
@@ -19,7 +19,7 @@ void test_output_copy() {
|
||||
sink(x); // clean
|
||||
}
|
||||
|
||||
void modify(int* ptr) { // $ ast-def=ptr
|
||||
void modify(int* ptr) { // $ ast-def=ptr ir-def=*ptr
|
||||
int* deref = ptr;
|
||||
int* other = &*deref;
|
||||
source_ref(other);
|
||||
@@ -31,7 +31,7 @@ void test_output() {
|
||||
sink(x); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void modify_copy_of_pointer(int* p, unsigned len) { // $ ast-def=p
|
||||
void modify_copy_of_pointer(int* p, unsigned len) { // $ ast-def=p ir-def=*p
|
||||
int* p2 = new int[len];
|
||||
for(unsigned i = 0; i < len; ++i) {
|
||||
p2[i] = p[i];
|
||||
@@ -46,7 +46,7 @@ void test_modify_copy_of_pointer() {
|
||||
sink(x[0]); // $ SPURIOUS: ast // clean
|
||||
}
|
||||
|
||||
void modify_pointer(int* p, unsigned len) { // $ ast-def=p
|
||||
void modify_pointer(int* p, unsigned len) { // $ ast-def=p ir-def=*p
|
||||
int** p2 = &p;
|
||||
for(unsigned i = 0; i < len; ++i) {
|
||||
*p2[i] = p[i];
|
||||
@@ -63,17 +63,17 @@ void test_modify_of_pointer() {
|
||||
|
||||
char* strdup(const char* p);
|
||||
|
||||
void modify_copy_via_strdup(char* p) { // $ ast-def=p
|
||||
void modify_copy_via_strdup(char* p) { // $ ast-def=p ir-def=*p
|
||||
char* p2 = strdup(p);
|
||||
source_ref(p2);
|
||||
}
|
||||
|
||||
void test_modify_copy_via_strdup(char* p) { // $ ast-def=p
|
||||
void test_modify_copy_via_strdup(char* p) { // $ ast-def=p ir-def=*p
|
||||
modify_copy_via_strdup(p);
|
||||
sink(*p); // clean
|
||||
}
|
||||
|
||||
int* deref(int** p) { // $ ast-def=p
|
||||
int* deref(int** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
int* q = *p;
|
||||
return q;
|
||||
}
|
||||
@@ -90,7 +90,7 @@ void addtaint1(int* q) { // $ ast-def=q ir-def=*q
|
||||
*q = source();
|
||||
}
|
||||
|
||||
void addtaint2(int** p) { // $ ast-def=p
|
||||
void addtaint2(int** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
int* q = *p;
|
||||
addtaint1(q);
|
||||
}
|
||||
@@ -106,13 +106,13 @@ using size_t = decltype(sizeof(int));
|
||||
|
||||
void* memcpy(void* dest, const void* src, size_t);
|
||||
|
||||
void modify_copy_via_memcpy(char* p) { // $ ast-def=p
|
||||
void modify_copy_via_memcpy(char* p) { // $ ast-def=p ir-def=*p
|
||||
char* dest;
|
||||
char* p2 = (char*)memcpy(dest, p, 10);
|
||||
source_ref(p2);
|
||||
}
|
||||
|
||||
void test_modify_copy_via_memcpy(char* p) { // $ ast-def=p
|
||||
void test_modify_copy_via_memcpy(char* p) { // $ ast-def=p ir-def=*p
|
||||
modify_copy_via_memcpy(p);
|
||||
sink(*p); // clean
|
||||
}
|
||||
@@ -134,14 +134,14 @@ void source_ref_ref(char** toTaint) { // $ ast-def=toTaint ir-def=*toTaint ir-de
|
||||
// This function copies the value of **p into a new location **p2 and then
|
||||
// taints **p. Thus, **p does not contain tainted data after returning from
|
||||
// this function.
|
||||
void modify_copy_via_strdup_ptr_001(char** p) { // $ ast-def=p
|
||||
void modify_copy_via_strdup_ptr_001(char** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
// **p -> **p2
|
||||
char** p2 = strdup_ptr_001(p);
|
||||
// source -> **p2
|
||||
source_ref_ref(p2);
|
||||
}
|
||||
|
||||
void test_modify_copy_via_strdup_001(char** p) { // $ ast-def=p
|
||||
void test_modify_copy_via_strdup_001(char** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
modify_copy_via_strdup_ptr_001(p);
|
||||
sink(**p); // clean
|
||||
}
|
||||
@@ -149,14 +149,14 @@ void test_modify_copy_via_strdup_001(char** p) { // $ ast-def=p
|
||||
// This function copies the value of *p into a new location *p2 and then
|
||||
// taints **p2. Thus, **p contains tainted data after returning from this
|
||||
// function.
|
||||
void modify_copy_via_strdup_ptr_011(char** p) { // $ ast-def=p
|
||||
void modify_copy_via_strdup_ptr_011(char** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
// **p -> **p2 and *p -> *p2
|
||||
char** p2 = strdup_ptr_011(p);
|
||||
// source -> **p2
|
||||
source_ref_ref(p2);
|
||||
}
|
||||
|
||||
void test_modify_copy_via_strdup_011(char** p) { // $ ast-def=p
|
||||
void test_modify_copy_via_strdup_011(char** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
modify_copy_via_strdup_ptr_011(p);
|
||||
sink(**p); // $ ir MISSING: ast
|
||||
}
|
||||
@@ -171,7 +171,7 @@ void source_ref_2(char** toTaint) { // $ ast-def=toTaint ir-def=*toTaint ir-def=
|
||||
// This function copies the value of p into a new location p2 and then
|
||||
// taints *p2. Thus, *p contains tainted data after returning from this
|
||||
// function.
|
||||
void modify_copy_via_strdup_ptr_111_taint_ind(char** p) { // $ ast-def=p
|
||||
void modify_copy_via_strdup_ptr_111_taint_ind(char** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
// **p -> **p2, *p -> *p2, and p -> p2
|
||||
char** p2 = strdup_ptr_111(p);
|
||||
// source -> *p2
|
||||
@@ -180,7 +180,7 @@ void modify_copy_via_strdup_ptr_111_taint_ind(char** p) { // $ ast-def=p
|
||||
|
||||
void sink(char*);
|
||||
|
||||
void test_modify_copy_via_strdup_111_taint_ind(char** p) { // $ ast-def=p
|
||||
void test_modify_copy_via_strdup_111_taint_ind(char** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
modify_copy_via_strdup_ptr_111_taint_ind(p);
|
||||
sink(*p); // $ ir MISSING: ast
|
||||
}
|
||||
@@ -188,7 +188,7 @@ void test_modify_copy_via_strdup_111_taint_ind(char** p) { // $ ast-def=p
|
||||
// This function copies the value of p into a new location p2 and then
|
||||
// taints **p2. Thus, **p contains tainted data after returning from this
|
||||
// function.
|
||||
void modify_copy_via_strdup_ptr_111_taint_ind_ind(char** p) { // $ ast-def=p
|
||||
void modify_copy_via_strdup_ptr_111_taint_ind_ind(char** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
// **p -> **p2, *p -> *p2, and p -> p2
|
||||
char** p2 = strdup_ptr_111(p);
|
||||
// source -> **p2
|
||||
@@ -197,7 +197,7 @@ void modify_copy_via_strdup_ptr_111_taint_ind_ind(char** p) { // $ ast-def=p
|
||||
|
||||
void sink(char*);
|
||||
|
||||
void test_modify_copy_via_strdup_111_taint_ind_ind(char** p) { // $ ast-def=p
|
||||
void test_modify_copy_via_strdup_111_taint_ind_ind(char** p) { // $ ast-def=p ir-def=*p ir-def=**p
|
||||
modify_copy_via_strdup_ptr_111_taint_ind_ind(p);
|
||||
sink(**p); // $ ir MISSING: ast
|
||||
}
|
||||
@@ -37,7 +37,7 @@ void test_lambdas()
|
||||
};
|
||||
d(t, u);
|
||||
|
||||
auto e = [](int &a, int &b, int &c) { // $ ast-def=a ast-def=b ast-def=c ir-def=*c
|
||||
auto e = [](int &a, int &b, int &c) { // $ ast-def=a ast-def=b ast-def=c ir-def=*c ir-def=*a ir-def=*b
|
||||
sink(a); // $ ast,ir
|
||||
sink(b);
|
||||
c = source();
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace withoutFields {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void assignWrapper(T &lhs, T rhs) { // $ ast-def=lhs ast-def=lhs
|
||||
void assignWrapper(T &lhs, T rhs) { // $ ast-def=lhs ast-def=lhs ir-def=*lhs
|
||||
assign(lhs, rhs);
|
||||
}
|
||||
|
||||
@@ -71,15 +71,15 @@ namespace withFields {
|
||||
int val;
|
||||
};
|
||||
|
||||
void assign(Int &lhs, int rhs) { // $ ast-def=lhs
|
||||
void assign(Int &lhs, int rhs) { // $ ast-def=lhs ir-def=*lhs
|
||||
lhs.val = rhs;
|
||||
}
|
||||
|
||||
void assignWrapper(Int &lhs, int rhs) { // $ ast-def=lhs
|
||||
void assignWrapper(Int &lhs, int rhs) { // $ ast-def=lhs ir-def=*lhs
|
||||
assign(lhs, rhs);
|
||||
}
|
||||
|
||||
void notAssign(Int &lhs, int rhs) { // $ ast-def=lhs
|
||||
void notAssign(Int &lhs, int rhs) { // $ ast-def=lhs ir-def=*lhs
|
||||
lhs.val = rhs;
|
||||
// Field flow ignores that the field is subsequently overwritten, leading
|
||||
// to false flow here.
|
||||
@@ -90,14 +90,14 @@ namespace withFields {
|
||||
}
|
||||
}
|
||||
|
||||
void sourceToParam(Int &out) { // $ ast-def=out
|
||||
void sourceToParam(Int &out) { // $ ast-def=out ir-def=*out
|
||||
out.val = source();
|
||||
if (arbitrary) {
|
||||
out.val = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sourceToParamWrapper(Int &out) { // $ ast-def=out
|
||||
void sourceToParamWrapper(Int &out) { // $ ast-def=out ir-def=*out
|
||||
if (arbitrary) {
|
||||
sourceToParam(out);
|
||||
} else {
|
||||
@@ -105,7 +105,7 @@ namespace withFields {
|
||||
}
|
||||
}
|
||||
|
||||
void notSource(Int &out) { // $ ast-def=out
|
||||
void notSource(Int &out) { // $ ast-def=out ir-def=*out
|
||||
out.val = source();
|
||||
// Field flow ignores that the field is subsequently overwritten, leading
|
||||
// to false flow here.
|
||||
|
||||
@@ -3,12 +3,12 @@ void incr(unsigned char **ps) // $ ast-def=ps ir-def=*ps ir-def=**ps
|
||||
*ps += 1;
|
||||
}
|
||||
|
||||
void callincr(unsigned char *s) // $ ast-def=s
|
||||
void callincr(unsigned char *s) // $ ast-def=s ir-def=*s
|
||||
{
|
||||
incr(&s);
|
||||
}
|
||||
|
||||
void test(unsigned char *s) // $ ast-def=s
|
||||
void test(unsigned char *s) // $ ast-def=s ir-def=*s
|
||||
{
|
||||
callincr(s); // $ flow
|
||||
}
|
||||
@@ -238,8 +238,6 @@ irFlow
|
||||
| test.cpp:382:48:382:54 | source1 | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:394:10:394:12 | tmp |
|
||||
| test.cpp:399:7:399:9 | definition of tmp | test.cpp:401:8:401:10 | tmp |
|
||||
| test.cpp:405:7:405:9 | definition of tmp | test.cpp:408:8:408:10 | tmp |
|
||||
| test.cpp:416:7:416:11 | definition of local | test.cpp:418:8:418:12 | local |
|
||||
| test.cpp:417:16:417:20 | intRefSource output argument | test.cpp:418:8:418:12 | local |
|
||||
| test.cpp:422:7:422:11 | definition of local | test.cpp:424:8:424:12 | local |
|
||||
@@ -266,6 +264,7 @@ irFlow
|
||||
| test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:568:10:568:19 | * ... |
|
||||
| test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:572:10:572:19 | * ... |
|
||||
| test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:578:10:578:19 | * ... |
|
||||
| test.cpp:583:11:583:16 | call to source | test.cpp:590:8:590:8 | x |
|
||||
| test.cpp:594:12:594:26 | *call to indirect_source | test.cpp:597:8:597:13 | * ... |
|
||||
| test.cpp:601:20:601:20 | intPointerSource output argument | test.cpp:603:8:603:9 | * ... |
|
||||
| test.cpp:607:20:607:20 | intPointerSource output argument | test.cpp:609:8:609:9 | * ... |
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace std {
|
||||
template<class T> T&& move(T& t) noexcept; // simplified signature
|
||||
}
|
||||
|
||||
void identityOperations(int* source1) { // $ ast-def=source1
|
||||
void identityOperations(int* source1) { // $ ast-def=source1 ir-def=*source1
|
||||
const int *x1 = std::move(source1);
|
||||
int* x2 = const_cast<int*>(x1);
|
||||
int* x3 = (x2);
|
||||
@@ -398,14 +398,14 @@ void flowThroughMemcpy_blockvar_with_local_flow(int source1, int b) {
|
||||
void cleanedByMemcpy_ssa(int clean1) { // currently modeled with BlockVar, not SSA
|
||||
int tmp;
|
||||
memcpy(&tmp, &clean1, sizeof tmp);
|
||||
sink(tmp); // $ SPURIOUS: ast,ir
|
||||
sink(tmp); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void cleanedByMemcpy_blockvar(int clean1) {
|
||||
int tmp;
|
||||
int *capture = &tmp;
|
||||
memcpy(&tmp, &clean1, sizeof tmp);
|
||||
sink(tmp); // $ SPURIOUS: ast,ir
|
||||
sink(tmp); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void intRefSource(int &ref_source);
|
||||
@@ -484,7 +484,7 @@ struct MyStruct {
|
||||
int* content;
|
||||
};
|
||||
|
||||
void local_field_flow_def_by_ref_steps_with_local_flow(MyStruct * s) { // $ ast-def=s
|
||||
void local_field_flow_def_by_ref_steps_with_local_flow(MyStruct * s) { // $ ast-def=s ir-def=*s
|
||||
writes_to_content(s->content);
|
||||
int* p_content = s->content;
|
||||
sink(*p_content);
|
||||
@@ -521,12 +521,12 @@ void uncertain_definition() {
|
||||
sink(stackArray[0]); // $ ast=519:19 ir SPURIOUS: ast=517:7
|
||||
}
|
||||
|
||||
void set_through_const_pointer(int x, const int **e) // $ ast-def=e ir-def=**e ir-def=*e
|
||||
void set_through_const_pointer(int x, const int **e) // $ ast-def=e ir-def=*e ir-def=**e
|
||||
{
|
||||
*e = &x;
|
||||
}
|
||||
|
||||
void test_set_through_const_pointer(int *e) // $ ast-def=e
|
||||
void test_set_through_const_pointer(int *e) // $ ast-def=e ir-def=*e
|
||||
{
|
||||
set_through_const_pointer(source(), &e);
|
||||
sink(*e); // $ ir MISSING: ast
|
||||
@@ -579,7 +579,7 @@ namespace IndirectFlowThroughGlobals {
|
||||
}
|
||||
}
|
||||
|
||||
void write_to_param(int* x) { // $ ast-def=x
|
||||
void write_to_param(int* x) { // $ ast-def=x ir-def=*x
|
||||
int s = source();
|
||||
x = &s;
|
||||
}
|
||||
@@ -587,7 +587,7 @@ void write_to_param(int* x) { // $ ast-def=x
|
||||
void test_write_to_param() {
|
||||
int x = 0;
|
||||
write_to_param(&x);
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast,ir
|
||||
}
|
||||
|
||||
void test_indirect_flow_to_array() {
|
||||
@@ -609,7 +609,7 @@ void test_def_by_ref_followed_by_uncertain_write_pointer(int* p) { // $ ast-def=
|
||||
sink(*p); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void test_flow_through_void_double_pointer(int *p) // $ ast-def=p
|
||||
void test_flow_through_void_double_pointer(int *p) // $ ast-def=p ir-def=*p
|
||||
{
|
||||
intPointerSource(p);
|
||||
void* q = (void*)&p;
|
||||
@@ -695,11 +695,11 @@ void increment_buf(int** buf) { // $ ast-def=buf ir-def=*buf ir-def=**buf
|
||||
sink(buf); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void call_increment_buf(int** buf) { // $ ast-def=buf
|
||||
void call_increment_buf(int** buf) { // $ ast-def=buf ir-def=*buf ir-def=**buf
|
||||
increment_buf(buf);
|
||||
}
|
||||
|
||||
void test_conflation_regression(int* source) { // $ ast-def=source
|
||||
void test_conflation_regression(int* source) { // $ ast-def=source ir-def=*source
|
||||
int* buf = source;
|
||||
call_increment_buf(&buf);
|
||||
}
|
||||
@@ -709,13 +709,13 @@ void write_to_star_star_p(unsigned char **p) // $ ast-def=p ir-def=**p ir-def=*p
|
||||
**p = 0;
|
||||
}
|
||||
|
||||
void write_to_star_buf(unsigned char *buf) // $ ast-def=buf
|
||||
void write_to_star_buf(unsigned char *buf) // $ ast-def=buf ir-def=*buf
|
||||
{
|
||||
unsigned char *c = buf;
|
||||
write_to_star_star_p(&c);
|
||||
}
|
||||
|
||||
void test_write_to_star_buf(unsigned char *source) // $ ast-def=source
|
||||
void test_write_to_star_buf(unsigned char *source) // $ ast-def=source ir-def=*source
|
||||
{
|
||||
write_to_star_buf(source);
|
||||
sink(*source); // clean
|
||||
@@ -1041,7 +1041,7 @@ namespace test_gettext {
|
||||
|
||||
void* memset(void*, int, size_t);
|
||||
|
||||
void memset_test(char* buf) { // $ ast-def=buf
|
||||
void memset_test(char* buf) { // $ ast-def=buf ir-def=*buf
|
||||
memset(buf, source(), 10);
|
||||
sink(*buf); // $ ir MISSING: ast
|
||||
}
|
||||
@@ -52,13 +52,17 @@ edges
|
||||
| A.cpp:103:14:103:14 | *c [a] | A.cpp:120:12:120:13 | *c1 [a] | provenance | |
|
||||
| A.cpp:107:12:107:13 | *c1 [a] | A.cpp:107:12:107:16 | a | provenance | |
|
||||
| A.cpp:120:12:120:13 | *c1 [a] | A.cpp:120:12:120:16 | a | provenance | |
|
||||
| A.cpp:124:14:124:14 | *b [c] | A.cpp:131:8:131:8 | f7 output argument [c] | provenance | |
|
||||
| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:124:14:124:14 | *b [c] | provenance | |
|
||||
| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:131:8:131:8 | f7 output argument [c] | provenance | |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | provenance | |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | set output argument [c] | provenance | |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:126:12:126:18 | new | provenance | |
|
||||
| A.cpp:131:8:131:8 | f7 output argument [c] | A.cpp:132:10:132:10 | *b [c] | provenance | |
|
||||
| A.cpp:132:10:132:10 | *b [c] | A.cpp:132:10:132:13 | c | provenance | |
|
||||
| A.cpp:140:13:140:13 | *b [c] | A.cpp:151:18:151:18 | D output argument [c] | provenance | |
|
||||
| A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | ... = ... | provenance | |
|
||||
| A.cpp:142:7:142:7 | *b [post update] [c] | A.cpp:140:13:140:13 | *b [c] | provenance | |
|
||||
| A.cpp:142:7:142:7 | *b [post update] [c] | A.cpp:143:7:143:31 | *... = ... [c] | provenance | |
|
||||
| A.cpp:142:7:142:7 | *b [post update] [c] | A.cpp:151:18:151:18 | D output argument [c] | provenance | |
|
||||
| A.cpp:142:7:142:20 | ... = ... | A.cpp:142:7:142:7 | *b [post update] [c] | provenance | |
|
||||
@@ -70,12 +74,20 @@ edges
|
||||
| A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | *this [post update] [b] | provenance | |
|
||||
| A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | ... = ... | provenance | |
|
||||
| A.cpp:150:12:150:18 | new | A.cpp:151:18:151:18 | b | provenance | |
|
||||
| A.cpp:151:12:151:24 | call to D [*b, c] | A.cpp:152:10:152:10 | *d [*b, c] | provenance | |
|
||||
| A.cpp:151:12:151:24 | call to D [*b, c] | A.cpp:153:10:153:10 | *d [*b, c] | provenance | |
|
||||
| A.cpp:151:12:151:24 | call to D [b] | A.cpp:152:10:152:10 | *d [b] | provenance | |
|
||||
| A.cpp:151:18:151:18 | D output argument [c] | A.cpp:154:10:154:10 | *b [c] | provenance | |
|
||||
| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | provenance | |
|
||||
| A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] | provenance | |
|
||||
| A.cpp:152:10:152:10 | *d [*b, c] | A.cpp:152:10:152:13 | *b [c] | provenance | |
|
||||
| A.cpp:152:10:152:10 | *d [*b, c] | A.cpp:152:13:152:13 | *b [c] | provenance | |
|
||||
| A.cpp:152:10:152:10 | *d [b] | A.cpp:152:10:152:13 | b | provenance | |
|
||||
| A.cpp:152:10:152:10 | *d [post update] [*b, c] | A.cpp:153:10:153:10 | *d [*b, c] | provenance | |
|
||||
| A.cpp:152:10:152:13 | *b [c] | A.cpp:152:10:152:13 | sink output argument [c] | provenance | |
|
||||
| A.cpp:152:10:152:13 | *b [c] | A.cpp:173:26:173:26 | *o [c] | provenance | |
|
||||
| A.cpp:152:10:152:13 | sink output argument [c] | A.cpp:152:10:152:10 | *d [post update] [*b, c] | provenance | |
|
||||
| A.cpp:152:13:152:13 | *b [c] | A.cpp:152:10:152:13 | *b [c] | provenance | |
|
||||
| A.cpp:153:10:153:10 | *d [*b, c] | A.cpp:153:13:153:13 | *b [c] | provenance | |
|
||||
| A.cpp:153:13:153:13 | *b [c] | A.cpp:153:10:153:16 | c | provenance | |
|
||||
| A.cpp:154:10:154:10 | *b [c] | A.cpp:154:10:154:13 | c | provenance | |
|
||||
@@ -98,6 +110,7 @@ edges
|
||||
| A.cpp:167:47:167:50 | *next [*next, head] | A.cpp:167:44:167:44 | *l [*next, head] | provenance | |
|
||||
| A.cpp:167:47:167:50 | *next [head] | A.cpp:169:12:169:12 | *l [head] | provenance | |
|
||||
| A.cpp:169:12:169:12 | *l [head] | A.cpp:169:12:169:18 | head | provenance | |
|
||||
| A.cpp:173:26:173:26 | *o [c] | A.cpp:173:26:173:26 | *o [c] | provenance | |
|
||||
| A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... | provenance | |
|
||||
| A.cpp:181:32:181:35 | *next [*next, head] | A.cpp:184:7:184:23 | *... = ... [*next, head] | provenance | |
|
||||
| A.cpp:181:32:181:35 | *next [head] | A.cpp:184:7:184:23 | *... = ... [head] | provenance | |
|
||||
@@ -200,9 +213,13 @@ edges
|
||||
| E.cpp:30:23:30:26 | *data [post update] [*buffer] | E.cpp:30:21:30:21 | *p [post update] [data, *buffer] | provenance | |
|
||||
| E.cpp:32:10:32:10 | *b [*buffer] | E.cpp:32:13:32:18 | *buffer | provenance | |
|
||||
| E.cpp:33:18:33:19 | *& ... [data, *buffer] | E.cpp:19:27:19:27 | *p [data, *buffer] | provenance | |
|
||||
| aliasing.cpp:8:23:8:23 | *s [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | provenance | |
|
||||
| aliasing.cpp:9:3:9:3 | *s [post update] [m1] | aliasing.cpp:8:23:8:23 | *s [m1] | provenance | |
|
||||
| aliasing.cpp:9:3:9:3 | *s [post update] [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | provenance | |
|
||||
| aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:3:9:3 | *s [post update] [m1] | provenance | |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:3:9:22 | ... = ... | provenance | |
|
||||
| aliasing.cpp:12:25:12:25 | *s [m1] | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | provenance | |
|
||||
| aliasing.cpp:13:3:13:3 | *s [post update] [m1] | aliasing.cpp:12:25:12:25 | *s [m1] | provenance | |
|
||||
| aliasing.cpp:13:3:13:3 | *s [post update] [m1] | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | provenance | |
|
||||
| aliasing.cpp:13:3:13:21 | ... = ... | aliasing.cpp:13:3:13:3 | *s [post update] [m1] | provenance | |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:13:3:13:21 | ... = ... | provenance | |
|
||||
@@ -313,6 +330,7 @@ edges
|
||||
| arrays.cpp:50:10:50:17 | *indirect [*ptr, data] | arrays.cpp:50:20:50:22 | *ptr [data] | provenance | |
|
||||
| arrays.cpp:50:20:50:22 | *ptr [data] | arrays.cpp:50:8:50:25 | *access to array [data] | provenance | |
|
||||
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... | provenance | |
|
||||
| by_reference.cpp:12:5:12:5 | *s [post update] [a] | by_reference.cpp:11:39:11:39 | *s [a] | provenance | |
|
||||
| by_reference.cpp:12:5:12:16 | ... = ... | by_reference.cpp:12:5:12:5 | *s [post update] [a] | provenance | |
|
||||
| by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | ... = ... | provenance | |
|
||||
| by_reference.cpp:16:5:16:19 | ... = ... | by_reference.cpp:16:5:16:8 | *this [post update] [a] | provenance | |
|
||||
@@ -356,12 +374,22 @@ edges
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | provenance | |
|
||||
| by_reference.cpp:69:22:69:23 | *& ... [a] | by_reference.cpp:31:46:31:46 | *s [a] | provenance | |
|
||||
| by_reference.cpp:69:22:69:23 | *& ... [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | provenance | |
|
||||
| by_reference.cpp:83:31:83:35 | *inner [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | provenance | |
|
||||
| by_reference.cpp:83:31:83:35 | *inner [a] | by_reference.cpp:103:27:103:35 | taint_inner_a_ptr output argument [a] | provenance | |
|
||||
| by_reference.cpp:83:31:83:35 | *inner [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | provenance | |
|
||||
| by_reference.cpp:83:31:83:35 | *inner [a] | by_reference.cpp:107:29:107:37 | taint_inner_a_ptr output argument [a] | provenance | |
|
||||
| by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:83:31:83:35 | *inner [a] | provenance | |
|
||||
| by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | provenance | |
|
||||
| by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:103:27:103:35 | taint_inner_a_ptr output argument [a] | provenance | |
|
||||
| by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | provenance | |
|
||||
| by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:107:29:107:37 | taint_inner_a_ptr output argument [a] | provenance | |
|
||||
| by_reference.cpp:84:3:84:25 | ... = ... | by_reference.cpp:84:3:84:7 | *inner [post update] [a] | provenance | |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:3:84:25 | ... = ... | provenance | |
|
||||
| by_reference.cpp:87:31:87:35 | *inner [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | provenance | |
|
||||
| by_reference.cpp:87:31:87:35 | *inner [a] | by_reference.cpp:123:21:123:36 | taint_inner_a_ref output argument [a] | provenance | |
|
||||
| by_reference.cpp:87:31:87:35 | *inner [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | provenance | |
|
||||
| by_reference.cpp:87:31:87:35 | *inner [a] | by_reference.cpp:127:21:127:38 | taint_inner_a_ref output argument [a] | provenance | |
|
||||
| by_reference.cpp:88:3:88:7 | *inner [post update] [a] | by_reference.cpp:87:31:87:35 | *inner [a] | provenance | |
|
||||
| by_reference.cpp:88:3:88:7 | *inner [post update] [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | provenance | |
|
||||
| by_reference.cpp:88:3:88:7 | *inner [post update] [a] | by_reference.cpp:123:21:123:36 | taint_inner_a_ref output argument [a] | provenance | |
|
||||
| by_reference.cpp:88:3:88:7 | *inner [post update] [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | provenance | |
|
||||
@@ -614,8 +642,10 @@ edges
|
||||
| qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:44 | ... = ... | provenance | |
|
||||
| qualifiers.cpp:9:30:9:44 | ... = ... | qualifiers.cpp:9:30:9:33 | *this [post update] [a] | provenance | |
|
||||
| qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:64 | ... = ... | provenance | |
|
||||
| qualifiers.cpp:12:49:12:53 | *inner [post update] [a] | qualifiers.cpp:12:27:12:31 | *inner [a] | provenance | |
|
||||
| qualifiers.cpp:12:49:12:64 | ... = ... | qualifiers.cpp:12:49:12:53 | *inner [post update] [a] | provenance | |
|
||||
| qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:65 | ... = ... | provenance | |
|
||||
| qualifiers.cpp:13:51:13:55 | *inner [post update] [a] | qualifiers.cpp:13:29:13:33 | *inner [a] | provenance | |
|
||||
| qualifiers.cpp:13:51:13:65 | ... = ... | qualifiers.cpp:13:51:13:55 | *inner [post update] [a] | provenance | |
|
||||
| qualifiers.cpp:22:5:22:9 | getInner output argument [*inner, a] | qualifiers.cpp:23:10:23:14 | *outer [*inner, a] | provenance | |
|
||||
| qualifiers.cpp:22:5:22:38 | ... = ... | qualifiers.cpp:22:11:22:18 | *call to getInner [post update] [a] | provenance | |
|
||||
@@ -716,6 +746,7 @@ edges
|
||||
| simple.cpp:103:24:103:24 | x | simple.cpp:104:14:104:14 | x | provenance | |
|
||||
| simple.cpp:108:17:108:26 | call to user_input | simple.cpp:109:43:109:43 | x | provenance | |
|
||||
| simple.cpp:109:43:109:43 | x | simple.cpp:103:24:103:24 | x | provenance | |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | *ab [a] | provenance | |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:8:15:9 | *ab [a] | provenance | |
|
||||
| struct_init.c:15:8:15:9 | *ab [a] | struct_init.c:15:12:15:12 | a | provenance | |
|
||||
| struct_init.c:20:13:20:14 | *definition of ab [a] | struct_init.c:22:8:22:9 | *ab [a] | provenance | |
|
||||
@@ -726,6 +757,8 @@ edges
|
||||
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:20:20:29 | call to user_input | provenance | |
|
||||
| struct_init.c:22:8:22:9 | *ab [a] | struct_init.c:22:11:22:11 | a | provenance | |
|
||||
| struct_init.c:24:10:24:12 | *& ... [a] | struct_init.c:14:24:14:25 | *ab [a] | provenance | |
|
||||
| struct_init.c:24:10:24:12 | *& ... [a] | struct_init.c:24:10:24:12 | absink output argument [a] | provenance | |
|
||||
| struct_init.c:24:10:24:12 | absink output argument [a] | struct_init.c:28:5:28:7 | *& ... [a] | provenance | |
|
||||
| struct_init.c:26:16:26:20 | *definition of outer [nestedAB, a] | struct_init.c:31:8:31:12 | *outer [nestedAB, a] | provenance | |
|
||||
| struct_init.c:26:16:26:20 | *definition of outer [nestedAB, a] | struct_init.c:36:11:36:15 | *outer [nestedAB, a] | provenance | |
|
||||
| struct_init.c:26:16:26:20 | *definition of outer [post update] [*pointerAB, a] | struct_init.c:33:8:33:12 | *outer [*pointerAB, a] | provenance | |
|
||||
@@ -805,12 +838,14 @@ nodes
|
||||
| A.cpp:107:12:107:16 | a | semmle.label | a |
|
||||
| A.cpp:120:12:120:13 | *c1 [a] | semmle.label | *c1 [a] |
|
||||
| A.cpp:120:12:120:16 | a | semmle.label | a |
|
||||
| A.cpp:124:14:124:14 | *b [c] | semmle.label | *b [c] |
|
||||
| A.cpp:126:5:126:5 | set output argument [c] | semmle.label | set output argument [c] |
|
||||
| A.cpp:126:12:126:18 | new | semmle.label | new |
|
||||
| A.cpp:126:12:126:18 | new | semmle.label | new |
|
||||
| A.cpp:131:8:131:8 | f7 output argument [c] | semmle.label | f7 output argument [c] |
|
||||
| A.cpp:132:10:132:10 | *b [c] | semmle.label | *b [c] |
|
||||
| A.cpp:132:10:132:13 | c | semmle.label | c |
|
||||
| A.cpp:140:13:140:13 | *b [c] | semmle.label | *b [c] |
|
||||
| A.cpp:140:13:140:13 | b | semmle.label | b |
|
||||
| A.cpp:142:7:142:7 | *b [post update] [c] | semmle.label | *b [post update] [c] |
|
||||
| A.cpp:142:7:142:20 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -827,8 +862,13 @@ nodes
|
||||
| A.cpp:151:12:151:24 | call to D [b] | semmle.label | call to D [b] |
|
||||
| A.cpp:151:18:151:18 | D output argument [c] | semmle.label | D output argument [c] |
|
||||
| A.cpp:151:18:151:18 | b | semmle.label | b |
|
||||
| A.cpp:152:10:152:10 | *d [*b, c] | semmle.label | *d [*b, c] |
|
||||
| A.cpp:152:10:152:10 | *d [b] | semmle.label | *d [b] |
|
||||
| A.cpp:152:10:152:10 | *d [post update] [*b, c] | semmle.label | *d [post update] [*b, c] |
|
||||
| A.cpp:152:10:152:13 | *b [c] | semmle.label | *b [c] |
|
||||
| A.cpp:152:10:152:13 | b | semmle.label | b |
|
||||
| A.cpp:152:10:152:13 | sink output argument [c] | semmle.label | sink output argument [c] |
|
||||
| A.cpp:152:13:152:13 | *b [c] | semmle.label | *b [c] |
|
||||
| A.cpp:153:10:153:10 | *d [*b, c] | semmle.label | *d [*b, c] |
|
||||
| A.cpp:153:10:153:16 | c | semmle.label | c |
|
||||
| A.cpp:153:13:153:13 | *b [c] | semmle.label | *b [c] |
|
||||
@@ -851,6 +891,8 @@ nodes
|
||||
| A.cpp:167:47:167:50 | *next [head] | semmle.label | *next [head] |
|
||||
| A.cpp:169:12:169:12 | *l [head] | semmle.label | *l [head] |
|
||||
| A.cpp:169:12:169:18 | head | semmle.label | head |
|
||||
| A.cpp:173:26:173:26 | *o [c] | semmle.label | *o [c] |
|
||||
| A.cpp:173:26:173:26 | *o [c] | semmle.label | *o [c] |
|
||||
| A.cpp:181:15:181:21 | newHead | semmle.label | newHead |
|
||||
| A.cpp:181:32:181:35 | *next [*next, head] | semmle.label | *next [*next, head] |
|
||||
| A.cpp:181:32:181:35 | *next [head] | semmle.label | *next [head] |
|
||||
@@ -964,9 +1006,11 @@ nodes
|
||||
| E.cpp:32:10:32:10 | *b [*buffer] | semmle.label | *b [*buffer] |
|
||||
| E.cpp:32:13:32:18 | *buffer | semmle.label | *buffer |
|
||||
| E.cpp:33:18:33:19 | *& ... [data, *buffer] | semmle.label | *& ... [data, *buffer] |
|
||||
| aliasing.cpp:8:23:8:23 | *s [m1] | semmle.label | *s [m1] |
|
||||
| aliasing.cpp:9:3:9:3 | *s [post update] [m1] | semmle.label | *s [post update] [m1] |
|
||||
| aliasing.cpp:9:3:9:22 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:12:25:12:25 | *s [m1] | semmle.label | *s [m1] |
|
||||
| aliasing.cpp:13:3:13:3 | *s [post update] [m1] | semmle.label | *s [post update] [m1] |
|
||||
| aliasing.cpp:13:3:13:21 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input | semmle.label | call to user_input |
|
||||
@@ -1084,6 +1128,7 @@ nodes
|
||||
| arrays.cpp:50:10:50:17 | *indirect [*ptr, data] | semmle.label | *indirect [*ptr, data] |
|
||||
| arrays.cpp:50:20:50:22 | *ptr [data] | semmle.label | *ptr [data] |
|
||||
| arrays.cpp:50:27:50:30 | data | semmle.label | data |
|
||||
| by_reference.cpp:11:39:11:39 | *s [a] | semmle.label | *s [a] |
|
||||
| by_reference.cpp:11:48:11:52 | value | semmle.label | value |
|
||||
| by_reference.cpp:12:5:12:5 | *s [post update] [a] | semmle.label | *s [post update] [a] |
|
||||
| by_reference.cpp:12:5:12:16 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -1128,9 +1173,11 @@ nodes
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
|
||||
| by_reference.cpp:69:22:69:23 | *& ... [a] | semmle.label | *& ... [a] |
|
||||
| by_reference.cpp:83:31:83:35 | *inner [a] | semmle.label | *inner [a] |
|
||||
| by_reference.cpp:84:3:84:7 | *inner [post update] [a] | semmle.label | *inner [post update] [a] |
|
||||
| by_reference.cpp:84:3:84:25 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:87:31:87:35 | *inner [a] | semmle.label | *inner [a] |
|
||||
| by_reference.cpp:88:3:88:7 | *inner [post update] [a] | semmle.label | *inner [post update] [a] |
|
||||
| by_reference.cpp:88:3:88:24 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
|
||||
@@ -1393,9 +1440,11 @@ nodes
|
||||
| qualifiers.cpp:9:21:9:25 | value | semmle.label | value |
|
||||
| qualifiers.cpp:9:30:9:33 | *this [post update] [a] | semmle.label | *this [post update] [a] |
|
||||
| qualifiers.cpp:9:30:9:44 | ... = ... | semmle.label | ... = ... |
|
||||
| qualifiers.cpp:12:27:12:31 | *inner [a] | semmle.label | *inner [a] |
|
||||
| qualifiers.cpp:12:40:12:44 | value | semmle.label | value |
|
||||
| qualifiers.cpp:12:49:12:53 | *inner [post update] [a] | semmle.label | *inner [post update] [a] |
|
||||
| qualifiers.cpp:12:49:12:64 | ... = ... | semmle.label | ... = ... |
|
||||
| qualifiers.cpp:13:29:13:33 | *inner [a] | semmle.label | *inner [a] |
|
||||
| qualifiers.cpp:13:42:13:46 | value | semmle.label | value |
|
||||
| qualifiers.cpp:13:51:13:55 | *inner [post update] [a] | semmle.label | *inner [post update] [a] |
|
||||
| qualifiers.cpp:13:51:13:65 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -1507,6 +1556,7 @@ nodes
|
||||
| simple.cpp:108:17:108:26 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:109:43:109:43 | x | semmle.label | x |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
|
||||
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
|
||||
| struct_init.c:15:8:15:9 | *ab [a] | semmle.label | *ab [a] |
|
||||
| struct_init.c:15:12:15:12 | a | semmle.label | a |
|
||||
| struct_init.c:20:13:20:14 | *definition of ab [a] | semmle.label | *definition of ab [a] |
|
||||
@@ -1516,6 +1566,7 @@ nodes
|
||||
| struct_init.c:22:8:22:9 | *ab [a] | semmle.label | *ab [a] |
|
||||
| struct_init.c:22:11:22:11 | a | semmle.label | a |
|
||||
| struct_init.c:24:10:24:12 | *& ... [a] | semmle.label | *& ... [a] |
|
||||
| struct_init.c:24:10:24:12 | absink output argument [a] | semmle.label | absink output argument [a] |
|
||||
| struct_init.c:26:16:26:20 | *definition of outer [nestedAB, a] | semmle.label | *definition of outer [nestedAB, a] |
|
||||
| struct_init.c:26:16:26:20 | *definition of outer [post update] [*pointerAB, a] | semmle.label | *definition of outer [post update] [*pointerAB, a] |
|
||||
| struct_init.c:26:16:26:20 | *definition of outer [post update] [nestedAB, a] | semmle.label | *definition of outer [post update] [nestedAB, a] |
|
||||
@@ -1552,6 +1603,7 @@ subpaths
|
||||
| A.cpp:90:15:90:15 | c | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | *this [post update] [c] | A.cpp:90:7:90:8 | set output argument [c] |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | *this [post update] [c] | A.cpp:126:5:126:5 | set output argument [c] |
|
||||
| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:10 | *this [post update] [b] | A.cpp:151:12:151:24 | call to D [b] |
|
||||
| A.cpp:152:10:152:13 | *b [c] | A.cpp:173:26:173:26 | *o [c] | A.cpp:173:26:173:26 | *o [c] | A.cpp:152:10:152:13 | sink output argument [c] |
|
||||
| A.cpp:160:29:160:29 | b | A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:10 | *this [post update] [head] | A.cpp:160:18:160:60 | call to MyList [head] |
|
||||
| A.cpp:161:38:161:39 | *l1 [head] | A.cpp:181:32:181:35 | *next [head] | A.cpp:184:7:184:10 | *this [post update] [*next, head] | A.cpp:161:18:161:40 | call to MyList [*next, head] |
|
||||
| A.cpp:162:38:162:39 | *l2 [*next, head] | A.cpp:181:32:181:35 | *next [*next, head] | A.cpp:184:7:184:10 | *this [post update] [*next, *next, head] | A.cpp:162:18:162:40 | call to MyList [*next, *next, head] |
|
||||
@@ -1564,6 +1616,7 @@ subpaths
|
||||
| D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | *this [post update] [elem] | D.cpp:37:8:37:10 | setElem output argument [elem] |
|
||||
| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | *this [post update] [elem] | D.cpp:51:8:51:14 | setElem output argument [elem] |
|
||||
| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:8 | *this [post update] [a] | by_reference.cpp:20:5:20:8 | setDirectly output argument [a] |
|
||||
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:11:39:11:39 | *s [a] | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] |
|
||||
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | *s [post update] [a] | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] |
|
||||
| by_reference.cpp:40:12:40:15 | *this [a] | by_reference.cpp:35:9:35:19 | *this [a] | by_reference.cpp:35:9:35:19 | *getDirectly | by_reference.cpp:40:18:40:28 | call to getDirectly |
|
||||
| by_reference.cpp:44:26:44:29 | *this [a] | by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:31:16:31:28 | *nonMemberGetA | by_reference.cpp:44:12:44:24 | call to nonMemberGetA |
|
||||
@@ -1573,6 +1626,7 @@ subpaths
|
||||
| by_reference.cpp:57:8:57:8 | *s [a] | by_reference.cpp:39:9:39:21 | *this [a] | by_reference.cpp:39:9:39:21 | *getIndirectly | by_reference.cpp:57:10:57:22 | call to getIndirectly |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] |
|
||||
| by_reference.cpp:63:8:63:8 | *s [a] | by_reference.cpp:43:9:43:27 | *this [a] | by_reference.cpp:43:9:43:27 | *getThroughNonMember | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:11:39:11:39 | *s [a] | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | *s [post update] [a] | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] |
|
||||
| by_reference.cpp:69:22:69:23 | *& ... [a] | by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:31:16:31:28 | *nonMemberGetA | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
|
||||
| complex.cpp:42:16:42:16 | *f [a_] | complex.cpp:9:7:9:7 | *this [a_] | complex.cpp:9:7:9:7 | *a | complex.cpp:42:18:42:18 | call to a |
|
||||
@@ -1588,7 +1642,9 @@ subpaths
|
||||
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:5:23:7 | *this [post update] [a_] | constructors.cpp:36:9:36:9 | call to Foo [a_] |
|
||||
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:5:23:7 | *this [post update] [b_] | constructors.cpp:36:9:36:9 | call to Foo [b_] |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:33 | *this [post update] [a] | qualifiers.cpp:27:11:27:18 | setA output argument [a] |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:27:12:31 | *inner [a] | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:53 | *inner [post update] [a] | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:29:13:33 | *inner [a] | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:55 | *inner [post update] [a] | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] |
|
||||
| simple.cpp:28:10:28:10 | *f [a_] | simple.cpp:18:9:18:9 | *this [a_] | simple.cpp:18:9:18:9 | *a | simple.cpp:28:12:28:12 | call to a |
|
||||
| simple.cpp:29:10:29:10 | *f [b_] | simple.cpp:19:9:19:9 | *this [b_] | simple.cpp:19:9:19:9 | *b | simple.cpp:29:12:29:12 | call to b |
|
||||
@@ -1597,6 +1653,7 @@ subpaths
|
||||
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:25 | *this [post update] [a_] | simple.cpp:41:5:41:5 | setA output argument [a_] |
|
||||
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:25 | *this [post update] [b_] | simple.cpp:42:5:42:5 | setB output argument [b_] |
|
||||
| simple.cpp:84:14:84:20 | *this [f2, f1] | simple.cpp:78:9:78:15 | *this [f2, f1] | simple.cpp:78:9:78:15 | *getf2f1 | simple.cpp:84:14:84:20 | call to getf2f1 |
|
||||
| struct_init.c:24:10:24:12 | *& ... [a] | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:24:10:24:12 | absink output argument [a] |
|
||||
#select
|
||||
| A.cpp:43:10:43:12 | *& ... | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | *& ... | *& ... flows from $@ | A.cpp:41:15:41:21 | new | new |
|
||||
| A.cpp:49:10:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:10:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new |
|
||||
|
||||
@@ -6490,6 +6490,7 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future (
|
||||
| taint.cpp:607:10:607:16 | call to _strinc | taint.cpp:609:8:609:12 | dest1 | |
|
||||
| taint.cpp:607:18:607:23 | source | taint.cpp:607:10:607:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:607:26:607:31 | locale | taint.cpp:607:10:607:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:607:26:607:31 | locale | taint.cpp:607:26:607:31 | ref arg locale | TAINT |
|
||||
| taint.cpp:607:26:607:31 | ref arg locale | taint.cpp:606:82:606:87 | locale | |
|
||||
| taint.cpp:607:26:607:31 | ref arg locale | taint.cpp:611:25:611:30 | locale | |
|
||||
| taint.cpp:608:7:608:11 | ref arg dest1 | taint.cpp:606:52:606:56 | dest1 | |
|
||||
@@ -6501,6 +6502,7 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future (
|
||||
| taint.cpp:611:10:611:16 | call to _strinc | taint.cpp:613:8:613:12 | dest2 | |
|
||||
| taint.cpp:611:18:611:22 | clean | taint.cpp:611:10:611:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:611:25:611:30 | locale | taint.cpp:611:10:611:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:611:25:611:30 | locale | taint.cpp:611:25:611:30 | ref arg locale | TAINT |
|
||||
| taint.cpp:611:25:611:30 | ref arg locale | taint.cpp:606:82:606:87 | locale | |
|
||||
| taint.cpp:612:7:612:11 | ref arg dest2 | taint.cpp:606:65:606:69 | dest2 | |
|
||||
| taint.cpp:612:7:612:11 | ref arg dest2 | taint.cpp:613:8:613:12 | dest2 | |
|
||||
@@ -6657,6 +6659,23 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future (
|
||||
| taint.cpp:745:27:745:32 | buffer | taint.cpp:745:19:745:25 | call to realloc | TAINT |
|
||||
| taint.cpp:746:9:746:15 | * ... | taint.cpp:746:8:746:15 | * ... | TAINT |
|
||||
| taint.cpp:746:10:746:15 | buffer | taint.cpp:746:9:746:15 | * ... | TAINT |
|
||||
| taint.cpp:751:31:751:34 | path | taint.cpp:751:31:751:34 | path | |
|
||||
| taint.cpp:751:31:751:34 | path | taint.cpp:752:10:752:13 | path | |
|
||||
| taint.cpp:751:31:751:34 | path | taint.cpp:753:10:753:13 | path | |
|
||||
| taint.cpp:751:43:751:46 | data | taint.cpp:751:43:751:46 | data | |
|
||||
| taint.cpp:751:43:751:46 | data | taint.cpp:753:22:753:25 | data | |
|
||||
| taint.cpp:752:10:752:13 | ref arg path | taint.cpp:751:31:751:34 | path | |
|
||||
| taint.cpp:752:10:752:13 | ref arg path | taint.cpp:753:10:753:13 | path | |
|
||||
| taint.cpp:752:16:752:19 | %s | taint.cpp:752:10:752:13 | ref arg path | TAINT |
|
||||
| taint.cpp:752:22:752:26 | abc | taint.cpp:752:10:752:13 | ref arg path | TAINT |
|
||||
| taint.cpp:753:10:753:13 | ref arg path | taint.cpp:751:31:751:34 | path | |
|
||||
| taint.cpp:753:16:753:19 | %s | taint.cpp:753:10:753:13 | ref arg path | TAINT |
|
||||
| taint.cpp:753:22:753:25 | data | taint.cpp:753:10:753:13 | ref arg path | TAINT |
|
||||
| taint.cpp:753:22:753:25 | ref arg data | taint.cpp:751:43:751:46 | data | |
|
||||
| taint.cpp:757:7:757:10 | path | taint.cpp:758:21:758:24 | path | |
|
||||
| taint.cpp:757:7:757:10 | path | taint.cpp:759:8:759:11 | path | |
|
||||
| taint.cpp:758:21:758:24 | ref arg path | taint.cpp:759:8:759:11 | path | |
|
||||
| taint.cpp:759:8:759:11 | path | taint.cpp:759:7:759:11 | * ... | |
|
||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
|
||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
|
||||
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |
|
||||
|
||||
@@ -71,11 +71,11 @@ void test_pair()
|
||||
sink(i.second); // $ MISSING: ast,ir
|
||||
sink(i); // $ ast,ir
|
||||
sink(j.first);
|
||||
sink(j.second); // $ SPURIOUS: ast,ir
|
||||
sink(j); // $ SPURIOUS: ast,ir
|
||||
sink(j.second); // $ SPURIOUS: ast
|
||||
sink(j); // $ SPURIOUS: ast
|
||||
sink(k.first);
|
||||
sink(k.second); // $ SPURIOUS: ast,ir
|
||||
sink(k); // $ SPURIOUS: ast,ir
|
||||
sink(k.second); // $ SPURIOUS: ast
|
||||
sink(k); // $ SPURIOUS: ast
|
||||
sink(l.first);
|
||||
sink(l.second); // $ MISSING: ast,ir
|
||||
sink(l); // $ ast,ir
|
||||
@@ -196,10 +196,10 @@ void test_map()
|
||||
sink(m18); // $ ast,ir
|
||||
m15.swap(m16);
|
||||
m17.swap(m18);
|
||||
sink(m15); // $ SPURIOUS: ast,ir
|
||||
sink(m15); // $ SPURIOUS: ast
|
||||
sink(m16); // $ ast,ir
|
||||
sink(m17); // $ ast,ir
|
||||
sink(m18); // $ SPURIOUS: ast,ir
|
||||
sink(m18); // $ SPURIOUS: ast
|
||||
|
||||
// merge
|
||||
std::map<char *, char *> m19, m20, m21, m22;
|
||||
@@ -345,10 +345,10 @@ void test_unordered_map()
|
||||
sink(m18); // $ ast,ir
|
||||
m15.swap(m16);
|
||||
m17.swap(m18);
|
||||
sink(m15); // $ SPURIOUS: ast,ir
|
||||
sink(m15); // $ SPURIOUS: ast
|
||||
sink(m16); // $ ast,ir
|
||||
sink(m17); // $ ast,ir
|
||||
sink(m18); // $ SPURIOUS: ast,ir
|
||||
sink(m18); // $ SPURIOUS: ast
|
||||
|
||||
// merge
|
||||
std::unordered_map<char *, char *> m19, m20, m21, m22;
|
||||
|
||||
@@ -81,10 +81,10 @@ void test_set()
|
||||
sink(s15); // $ ast,ir
|
||||
s12.swap(s13);
|
||||
s14.swap(s15);
|
||||
sink(s12); // $ SPURIOUS: ast,ir
|
||||
sink(s12); // $ SPURIOUS: ast
|
||||
sink(s13); // $ ast,ir
|
||||
sink(s14); // $ ast,ir
|
||||
sink(s15); // $ SPURIOUS: ast,ir
|
||||
sink(s15); // $ SPURIOUS: ast
|
||||
|
||||
// merge
|
||||
std::set<char *> s16, s17, s18, s19;
|
||||
@@ -193,10 +193,10 @@ void test_unordered_set()
|
||||
sink(s15); // $ ast,ir
|
||||
s12.swap(s13);
|
||||
s14.swap(s15);
|
||||
sink(s12); // $ SPURIOUS: ast,ir
|
||||
sink(s12); // $ SPURIOUS: ast
|
||||
sink(s13); // $ ast,ir
|
||||
sink(s14); // $ ast,ir
|
||||
sink(s15); // $ SPURIOUS: ast,ir
|
||||
sink(s15); // $ SPURIOUS: ast
|
||||
|
||||
// merge
|
||||
std::unordered_set<char *> s16, s17, s18, s19;
|
||||
|
||||
@@ -203,7 +203,7 @@ void test_string_assign() {
|
||||
sink(s5); // $ ast,ir
|
||||
|
||||
sink(s6.assign(s1));
|
||||
sink(s6); // $ SPURIOUS: ast,ir
|
||||
sink(s6); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void test_string_insert() {
|
||||
@@ -280,9 +280,9 @@ void test_string_swap() {
|
||||
s4.swap(s3);
|
||||
|
||||
sink(s1); // $ ast,ir
|
||||
sink(s2); // $ SPURIOUS: ast,ir
|
||||
sink(s2); // $ SPURIOUS: ast
|
||||
sink(s3); // $ ast,ir
|
||||
sink(s4); // $ SPURIOUS: ast,ir
|
||||
sink(s4); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void test_string_clear() {
|
||||
@@ -495,7 +495,7 @@ void test_string_iterator_methods()
|
||||
sink(h); // $ ast,ir
|
||||
|
||||
sink(s6.assign(s5.cbegin(), s5.cend()));
|
||||
sink(s6); // $ SPURIOUS: ast,ir
|
||||
sink(s6); // $ SPURIOUS: ast
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ void test_stringstream_string(int amount)
|
||||
ss7.str(source());
|
||||
ss7.str("abc"); // (overwrites)
|
||||
sink(ss6); // $ ast,ir
|
||||
sink(ss7); // $ SPURIOUS: ast,ir
|
||||
sink(ss7); // $ SPURIOUS: ast
|
||||
|
||||
sink(ss8.put('a'));
|
||||
sink(ss9.put(ns_char::source())); // $ ast,ir
|
||||
@@ -118,9 +118,9 @@ void test_stringstream_swap()
|
||||
ss4.swap(ss3);
|
||||
|
||||
sink(ss1); // $ ast,ir
|
||||
sink(ss2); // $ SPURIOUS: ast,ir
|
||||
sink(ss2); // $ SPURIOUS: ast
|
||||
sink(ss3); // $ ast,ir
|
||||
sink(ss4); // $ SPURIOUS: ast,ir
|
||||
sink(ss4); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void test_stringstream_in()
|
||||
@@ -217,7 +217,7 @@ void test_getline()
|
||||
sink(ss1.getline(b3, 1000));
|
||||
sink(b1);
|
||||
sink(b2); // $ ast,ir
|
||||
sink(b3); // $ SPURIOUS: ast,ir
|
||||
sink(b3); // $ SPURIOUS: ast
|
||||
|
||||
sink(ss1.getline(b4, 1000, ' '));
|
||||
sink(ss2.getline(b5, 1000, ' ')); // $ ast,ir
|
||||
@@ -225,7 +225,7 @@ void test_getline()
|
||||
sink(ss1.getline(b6, 1000, ' '));
|
||||
sink(b4);
|
||||
sink(b5); // $ ast,ir
|
||||
sink(b6); // $ SPURIOUS: ast,ir
|
||||
sink(b6); // $ SPURIOUS: ast
|
||||
|
||||
sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast,ir
|
||||
sink(b7); // $ ast,ir
|
||||
@@ -237,7 +237,7 @@ void test_getline()
|
||||
sink(getline(ss1, s3));
|
||||
sink(s1);
|
||||
sink(s2); // $ ast,ir
|
||||
sink(s3); // $ SPURIOUS: ast,ir
|
||||
sink(s3); // $ SPURIOUS: ast
|
||||
|
||||
sink(getline(ss1, s4, ' '));
|
||||
sink(getline(ss2, s5, ' ')); // $ ast,ir
|
||||
@@ -245,7 +245,7 @@ void test_getline()
|
||||
sink(getline(ss1, s6, ' '));
|
||||
sink(s4);
|
||||
sink(s5); // $ ast,ir
|
||||
sink(s6); // $ SPURIOUS: ast,ir
|
||||
sink(s6); // $ SPURIOUS: ast
|
||||
|
||||
sink(getline(getline(ss2, s7), s8)); // $ ast,ir
|
||||
sink(s7); // $ ast,ir
|
||||
|
||||
@@ -212,7 +212,7 @@ void test_swap() {
|
||||
|
||||
std::swap(x, y);
|
||||
|
||||
sink(x); // $ SPURIOUS: ast,ir
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
sink(y); // $ ast,ir
|
||||
}
|
||||
|
||||
@@ -744,4 +744,17 @@ void test_realloc_2_indirections(int **buffer) {
|
||||
**buffer = source();
|
||||
buffer = (int**)realloc(buffer, 16);
|
||||
sink(**buffer); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
int sprintf(char *, const char *, ...);
|
||||
|
||||
void call_sprintf_twice(char* path, char* data) {
|
||||
sprintf(path, "%s", "abc");
|
||||
sprintf(path, "%s", data);
|
||||
}
|
||||
|
||||
void test_call_sprintf() {
|
||||
char path[10];
|
||||
call_sprintf_twice(path, indirect_source());
|
||||
sink(*path); // $ ast,ir
|
||||
}
|
||||
@@ -114,10 +114,10 @@ void test_vector_swap() {
|
||||
v1.swap(v2);
|
||||
v3.swap(v4);
|
||||
|
||||
sink(v1); // $ SPURIOUS: ast,ir
|
||||
sink(v1); // $ SPURIOUS: ast
|
||||
sink(v2); // $ ast,ir
|
||||
sink(v3); // $ ast,ir
|
||||
sink(v4); // $ SPURIOUS: ast,ir
|
||||
sink(v4); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void test_vector_clear() {
|
||||
@@ -138,7 +138,7 @@ void test_vector_clear() {
|
||||
|
||||
sink(v1); // $ SPURIOUS: ast,ir
|
||||
sink(v2); // $ ast,ir
|
||||
sink(v3); // $ ast,ir
|
||||
sink(v3); // $ SPURIOUS: ast
|
||||
sink(v4);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -605,7 +605,7 @@ struct String {
|
||||
String& operator=(String&&);
|
||||
|
||||
const char* c_str() const;
|
||||
|
||||
char pop_back();
|
||||
private:
|
||||
const char* p;
|
||||
};
|
||||
@@ -2164,6 +2164,171 @@ void initialization_with_destructor(bool b, char c) {
|
||||
if (y == 1)
|
||||
return;
|
||||
}
|
||||
|
||||
for(vector<ClassWithDestructor> ys(x); ClassWithDestructor y : ys) {
|
||||
ClassWithDestructor z1;
|
||||
ClassWithDestructor z2;
|
||||
}
|
||||
}
|
||||
|
||||
void static_variable_with_destructor_1() {
|
||||
ClassWithDestructor a;
|
||||
static ClassWithDestructor b;
|
||||
}
|
||||
|
||||
void static_variable_with_destructor_2() {
|
||||
static ClassWithDestructor a;
|
||||
ClassWithDestructor b;
|
||||
}
|
||||
|
||||
void static_variable_with_destructor_3() {
|
||||
ClassWithDestructor a;
|
||||
ClassWithDestructor b;
|
||||
static ClassWithDestructor c;
|
||||
}
|
||||
|
||||
static ClassWithDestructor global_class_with_destructor;
|
||||
|
||||
namespace vacuous_destructor_call {
|
||||
template<typename T>
|
||||
T& get(T& t) { return t; }
|
||||
|
||||
template<typename T>
|
||||
void call_destructor(T& t) {
|
||||
get(t).~T();
|
||||
}
|
||||
|
||||
void non_vacuous_destructor_call() {
|
||||
ClassWithDestructor c;
|
||||
call_destructor(c);
|
||||
}
|
||||
|
||||
void vacuous_destructor_call() {
|
||||
int i;
|
||||
call_destructor(i);
|
||||
}
|
||||
}
|
||||
|
||||
void TryCatchDestructors(bool b) {
|
||||
try {
|
||||
String s;
|
||||
if (b) {
|
||||
throw "string literal";
|
||||
}
|
||||
String s2;
|
||||
}
|
||||
catch (const char* s) {
|
||||
throw String(s);
|
||||
}
|
||||
catch (const String& e) {
|
||||
}
|
||||
catch (...) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void IfDestructors(bool b) {
|
||||
String s1;
|
||||
if(b) {
|
||||
String s2;
|
||||
} else {
|
||||
String s3;
|
||||
}
|
||||
String s4;
|
||||
}
|
||||
|
||||
void ForDestructors() {
|
||||
char c = 'a';
|
||||
for(String s("hello"); c != 0; c = s.pop_back()) {
|
||||
String s2;
|
||||
}
|
||||
|
||||
for(String s : vector<String>(String("hello"))) {
|
||||
String s2;
|
||||
}
|
||||
|
||||
for(String s("hello"), s2("world"); c != 0; c = s.pop_back()) {
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void IfDestructors2(bool b) {
|
||||
if(String s = String("hello"); b) {
|
||||
int x = 0;
|
||||
} else {
|
||||
int y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class Bool {
|
||||
public:
|
||||
Bool(bool b_);
|
||||
operator bool();
|
||||
~Bool();
|
||||
};
|
||||
|
||||
void IfDestructors3(bool b) {
|
||||
if(Bool B = Bool(b)) {
|
||||
String s1;
|
||||
} else {
|
||||
String s2;
|
||||
}
|
||||
}
|
||||
|
||||
void WhileLoopDestructors(bool b) {
|
||||
{
|
||||
String s;
|
||||
while(b) {
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
while (Bool B = Bool(b)) {
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoidFunc() {}
|
||||
|
||||
void IfReturnDestructors(bool b) {
|
||||
String s;
|
||||
if(b) {
|
||||
return;
|
||||
}
|
||||
if(b) {
|
||||
return VoidFunc();
|
||||
}
|
||||
s;
|
||||
}
|
||||
|
||||
int IfReturnDestructors3(bool b) {
|
||||
String s;
|
||||
if(b) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VoidReturnDestructors() {
|
||||
String s;
|
||||
return VoidFunc();
|
||||
}
|
||||
|
||||
namespace return_routine_type {
|
||||
struct HasVoidToIntFunc
|
||||
{
|
||||
void VoidToInt(int);
|
||||
};
|
||||
|
||||
typedef void (HasVoidToIntFunc::*VoidToIntMemberFunc)(int);
|
||||
|
||||
static VoidToIntMemberFunc GetVoidToIntFunc()
|
||||
{
|
||||
return &HasVoidToIntFunc::VoidToInt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++20 --clang
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
| copy.cpp:13:9:13:9 | operator= | protected_cc::Sub2& protected_cc::Sub2::operator=(protected_cc::Sub2 const&) | | |
|
||||
| copy.cpp:13:9:13:9 | operator= | protected_cc::Sub2& protected_cc::Sub2::operator=(protected_cc::Sub2&&) | | |
|
||||
| copy.cpp:17:9:17:9 | HasMember | void protected_cc::HasMember::HasMember() | deleted | |
|
||||
| copy.cpp:17:9:17:9 | HasMember | void protected_cc::HasMember::HasMember(protected_cc::HasMember const&) | | |
|
||||
| copy.cpp:17:9:17:9 | HasMember | void protected_cc::HasMember::HasMember(protected_cc::HasMember&&) | | |
|
||||
| copy.cpp:17:9:17:9 | HasMember | void protected_cc::HasMember::HasMember(protected_cc::HasMember const&) | deleted | |
|
||||
| copy.cpp:17:9:17:9 | operator= | protected_cc::HasMember& protected_cc::HasMember::operator=(protected_cc::HasMember const&) | | |
|
||||
| copy.cpp:17:9:17:9 | operator= | protected_cc::HasMember& protected_cc::HasMember::operator=(protected_cc::HasMember&&) | | |
|
||||
| copy.cpp:25:5:25:5 | C | void deleted_cc::C::C(deleted_cc::C const&) | deleted | |
|
||||
|
||||
@@ -186,7 +186,6 @@
|
||||
| Variable | specifiers2pp.cpp:16:13:16:22 | privateInt | privateInt | private |
|
||||
| Variable | specifiers2pp.cpp:17:21:17:30 | mutableInt | mutableInt | private |
|
||||
| Variable | specifiers2pp.cpp:20:13:20:24 | protectedInt | protectedInt | protected |
|
||||
| Variable | specifiers2pp.cpp:52:25:52:27 | vci | vci | static |
|
||||
| VariableDeclarationEntry | specifiers2.c:5:12:5:12 | declaration of i | i | extern |
|
||||
| VariableDeclarationEntry | specifiers2.c:6:12:6:12 | declaration of i | i | extern |
|
||||
| VariableDeclarationEntry | specifiers2.c:8:12:8:12 | declaration of j | j | extern |
|
||||
|
||||
@@ -7,9 +7,9 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
|
||||
@@ -8,11 +8,11 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||
| VacuousDestructorCall.cpp:3:3:3:3 | VariableAddress: x | Instruction 'VariableAddress: x' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||
| VacuousDestructorCall.cpp:4:3:4:3 | Load: y | Instruction 'Load: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| statements.cpp:26:3:26:3 | IndirectMayWriteSideEffect: inner | Instruction 'IndirectMayWriteSideEffect: inner' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| statements.cpp:28:1:28:1 | IndirectMayWriteSideEffect: before | Instruction 'IndirectMayWriteSideEffect: before' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
| stmt_expr.cpp:29:11:32:11 | CopyValue: (statement expression) | Instruction 'CopyValue: (statement expression)' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
| stmt_in_type.cpp:5:53:5:53 | Constant: 1 | Instruction 'Constant: 1' has no successors in function '$@'. | stmt_in_type.cpp:2:6:2:12 | void cpp_fun() | void cpp_fun() |
|
||||
@@ -30,7 +30,6 @@ multipleIRTypes
|
||||
lostReachability
|
||||
backEdgeCountMismatch
|
||||
useNotDominatedByDefinition
|
||||
| VacuousDestructorCall.cpp:2:29:2:29 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||
| ms_try_except.cpp:9:19:9:19 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
|
||||
| ms_try_except.cpp:9:19:9:19 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
|
||||
| ms_try_except.cpp:19:17:19:21 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
|
||||
|
||||
@@ -7,9 +7,9 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user