mirror of
https://github.com/github/codeql.git
synced 2026-05-18 13:17:08 +02:00
Compare commits
445 Commits
tausbn/pyt
...
sitedocs/2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea39eba881 | ||
|
|
9c51514bd9 | ||
|
|
04436208ab | ||
|
|
5749fdbc46 | ||
|
|
ff2d78d2c8 | ||
|
|
f571ebdaf4 | ||
|
|
e6e6a4e9c8 | ||
|
|
adbcbefaa9 | ||
|
|
4ac8dd72a7 | ||
|
|
73c4fe08fa | ||
|
|
00c228540e | ||
|
|
35a8e7cbf0 | ||
|
|
42acd9c22c | ||
|
|
6485dcc0fc | ||
|
|
a09eb9f4c5 | ||
|
|
7fe378e831 | ||
|
|
3fdc7e95df | ||
|
|
8187b00562 | ||
|
|
d300736c7e | ||
|
|
58f2777532 | ||
|
|
589a34241c | ||
|
|
820c14577a | ||
|
|
e7852f520f | ||
|
|
5440dbf70d | ||
|
|
43df6a2c07 | ||
|
|
66130d208e | ||
|
|
dbd33d1cf0 | ||
|
|
9b5cfc9026 | ||
|
|
3601773856 | ||
|
|
9ee2314ef6 | ||
|
|
7c35309732 | ||
|
|
245cd5c0b5 | ||
|
|
ac4601cb8f | ||
|
|
a9bab18804 | ||
|
|
36a775502f | ||
|
|
7c46e9fcf4 | ||
|
|
33eb69164c | ||
|
|
6d8d106d91 | ||
|
|
546b0a9a89 | ||
|
|
fc5b9e2796 | ||
|
|
2896bfbd9f | ||
|
|
7f950d8e0d | ||
|
|
7dd175d938 | ||
|
|
feb1ca29cc | ||
|
|
e4f680d476 | ||
|
|
a548316747 | ||
|
|
2321eecb9e | ||
|
|
e74606eba3 | ||
|
|
79c5ad93b0 | ||
|
|
f2e467d8ea | ||
|
|
5b48bc4a3e | ||
|
|
48fcec82d6 | ||
|
|
608a3f907c | ||
|
|
1f64f5f8c9 | ||
|
|
f8c805de6b | ||
|
|
ec6e17360d | ||
|
|
a3f6bfe1df | ||
|
|
51afe12ae1 | ||
|
|
b0eb0e1f1e | ||
|
|
85782ff1d4 | ||
|
|
1fa151db7c | ||
|
|
76564edc93 | ||
|
|
92b086d36f | ||
|
|
c9474050c8 | ||
|
|
ea38bf5ebc | ||
|
|
138ce42cf6 | ||
|
|
7d74125508 | ||
|
|
5202792163 | ||
|
|
b71b43a2fb | ||
|
|
4b0689b6ba | ||
|
|
6dec323cfc | ||
|
|
4dd8f6e618 | ||
|
|
81b04863b2 | ||
|
|
22b168beee | ||
|
|
67612e60b5 | ||
|
|
7bbc18f114 | ||
|
|
c7295a09cd | ||
|
|
f3a381f10d | ||
|
|
dae20ca50c | ||
|
|
6d5fd3c9de | ||
|
|
73040bd30f | ||
|
|
990dec67d0 | ||
|
|
43ee62ad64 | ||
|
|
eda345a5b8 | ||
|
|
e3380aa545 | ||
|
|
7f6c84dda8 | ||
|
|
35b93063f9 | ||
|
|
16375b0fe7 | ||
|
|
37677142b9 | ||
|
|
58a1353ddc | ||
|
|
1638183d18 | ||
|
|
6178acc070 | ||
|
|
81ce8dc02d | ||
|
|
92447dc743 | ||
|
|
7ba25b23a5 | ||
|
|
eb5cb2a7bf | ||
|
|
215808d7e9 | ||
|
|
cdf3d47031 | ||
|
|
c606ab09a5 | ||
|
|
d7dc73e18b | ||
|
|
f0a5183a3f | ||
|
|
4c9876b008 | ||
|
|
cf162aa412 | ||
|
|
84797b9091 | ||
|
|
cc754858c6 | ||
|
|
a60afef923 | ||
|
|
e58b6e86b2 | ||
|
|
0edfafeb06 | ||
|
|
a87df5459f | ||
|
|
527041348e | ||
|
|
e065390185 | ||
|
|
27ba51cf9d | ||
|
|
94a941115f | ||
|
|
ca55b92281 | ||
|
|
0ebe045cd8 | ||
|
|
c4f2bbda2a | ||
|
|
34308eee8d | ||
|
|
4e5a6d770a | ||
|
|
f1115af146 | ||
|
|
f4c2e65614 | ||
|
|
a54a73c9a2 | ||
|
|
caa45058ae | ||
|
|
55e6255e05 | ||
|
|
316273c7f3 | ||
|
|
66d2a8499d | ||
|
|
02bab4c15a | ||
|
|
0dbe8c3d8a | ||
|
|
d13ea0b6c9 | ||
|
|
6972f9b31d | ||
|
|
350dab4621 | ||
|
|
6ba6b12b9f | ||
|
|
b71074f9c4 | ||
|
|
fbbd57b34f | ||
|
|
f400228037 | ||
|
|
dcc6f83d3b | ||
|
|
7027b7fe82 | ||
|
|
b4fdd4e222 | ||
|
|
e78e71c875 | ||
|
|
edd383afc1 | ||
|
|
a264ea23c6 | ||
|
|
2b99b83857 | ||
|
|
8e43c5c683 | ||
|
|
4dde1fb117 | ||
|
|
bd7b2c4cc6 | ||
|
|
d5c34264ad | ||
|
|
5be75e91fc | ||
|
|
a78e04eb34 | ||
|
|
05aaf2bb67 | ||
|
|
84f3771cdd | ||
|
|
28e1e3a13a | ||
|
|
6e09dcc16a | ||
|
|
22e6c676c3 | ||
|
|
b7d2e54bbd | ||
|
|
00ab1a3129 | ||
|
|
a92e394a7c | ||
|
|
7286f56718 | ||
|
|
331f308997 | ||
|
|
97275157e6 | ||
|
|
e124b07611 | ||
|
|
dcc2b2c50d | ||
|
|
c0974934bc | ||
|
|
39a802fb98 | ||
|
|
00e77a3ddb | ||
|
|
569bb991d4 | ||
|
|
6a1bb9bfb0 | ||
|
|
357638baa8 | ||
|
|
0bf0c069c6 | ||
|
|
a9ce2e10ad | ||
|
|
fc12537699 | ||
|
|
ab288d0d4c | ||
|
|
e5de4f2d67 | ||
|
|
73fe20f33b | ||
|
|
1f3a3492ae | ||
|
|
910725939f | ||
|
|
9bad1e60db | ||
|
|
9b5bf519a1 | ||
|
|
279605b486 | ||
|
|
acf2f761a6 | ||
|
|
1a13a0e4c9 | ||
|
|
52b273ae23 | ||
|
|
8055c5d9e3 | ||
|
|
020eb4aed7 | ||
|
|
040a288bb3 | ||
|
|
37212737fb | ||
|
|
ac484e5a04 | ||
|
|
a8ae2e2525 | ||
|
|
50ad45944c | ||
|
|
5def2887e7 | ||
|
|
52a36ce41c | ||
|
|
4dd23d4767 | ||
|
|
726e0928ed | ||
|
|
83cef78200 | ||
|
|
0e9a7c84d1 | ||
|
|
ff82eb95f5 | ||
|
|
6563414370 | ||
|
|
fbf6727809 | ||
|
|
16cb6c2044 | ||
|
|
85a45b0155 | ||
|
|
0c93641b54 | ||
|
|
ce1d0d2375 | ||
|
|
31687afd5d | ||
|
|
4ab7acedb6 | ||
|
|
038afc4008 | ||
|
|
037c76d840 | ||
|
|
11142df4d0 | ||
|
|
7a96b11a0a | ||
|
|
19ac9e089a | ||
|
|
c7efde3b7a | ||
|
|
72e6853792 | ||
|
|
9c2322dd82 | ||
|
|
7072ab9364 | ||
|
|
114c17ad57 | ||
|
|
040395485e | ||
|
|
bf22c6dae0 | ||
|
|
f5d014baa5 | ||
|
|
59b14f6a69 | ||
|
|
45e1be875c | ||
|
|
4dc605354c | ||
|
|
1ba3efb111 | ||
|
|
e84a509976 | ||
|
|
c3671c7625 | ||
|
|
be3c1ed0be | ||
|
|
c95abd47ce | ||
|
|
cb1c68260e | ||
|
|
c663809cc7 | ||
|
|
0e24ed14da | ||
|
|
0bb6a64e81 | ||
|
|
0a8dfbafe4 | ||
|
|
5a1c0f60e6 | ||
|
|
4adc373dfe | ||
|
|
4b1626c83a | ||
|
|
3418ec8a81 | ||
|
|
bda8a804ec | ||
|
|
65b30c1dff | ||
|
|
d99a763ef7 | ||
|
|
a08b292099 | ||
|
|
5399d88d15 | ||
|
|
eeda4355f1 | ||
|
|
e43c368222 | ||
|
|
30b7fadbb8 | ||
|
|
6e63df9e32 | ||
|
|
0e1c45e84b | ||
|
|
df64e0bc5f | ||
|
|
f89fedcbaf | ||
|
|
a693c6d9b4 | ||
|
|
10f6329b3e | ||
|
|
f907fd21ad | ||
|
|
0e95f41900 | ||
|
|
ac4ad0cbc0 | ||
|
|
24572848f3 | ||
|
|
07fc84de8c | ||
|
|
bb97df1d71 | ||
|
|
1fece75f15 | ||
|
|
bbf3fa7506 | ||
|
|
d182eae868 | ||
|
|
a499919239 | ||
|
|
f834768720 | ||
|
|
9d2dc7a3cc | ||
|
|
88e3bc6865 | ||
|
|
445b82b4e1 | ||
|
|
70465b22c7 | ||
|
|
98289b52d6 | ||
|
|
8151f3024d | ||
|
|
13e3a5158e | ||
|
|
b0a13fb661 | ||
|
|
6a0adff1dc | ||
|
|
eeaa2bcc55 | ||
|
|
f384afbaf6 | ||
|
|
3ad83cc098 | ||
|
|
7cd84c8f0a | ||
|
|
6b310bb825 | ||
|
|
2a70437a12 | ||
|
|
4b9340816c | ||
|
|
9ab3837cdc | ||
|
|
f7b8e8af41 | ||
|
|
1cfac50749 | ||
|
|
bfea40fca0 | ||
|
|
1abd81ec34 | ||
|
|
f43e929d1a | ||
|
|
573763a4b3 | ||
|
|
f1392712ee | ||
|
|
5125973f9b | ||
|
|
1927530517 | ||
|
|
376c6ea09a | ||
|
|
7b85bb4c95 | ||
|
|
4367b7813c | ||
|
|
d1c0294551 | ||
|
|
5e401abccb | ||
|
|
2f1d4b923e | ||
|
|
4c769f2b09 | ||
|
|
3307457deb | ||
|
|
13b0a9a842 | ||
|
|
905420143b | ||
|
|
008585eeba | ||
|
|
8886092cd0 | ||
|
|
4d28c0d2a9 | ||
|
|
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 | ||
|
|
580e68d5de | ||
|
|
45bb4a0ee5 | ||
|
|
a47c702171 | ||
|
|
65ac94320e | ||
|
|
073f65d586 | ||
|
|
3c79faf37a | ||
|
|
2fe10942da | ||
|
|
3fcb0ee228 | ||
|
|
b2edf6cf3e | ||
|
|
a1c384c57b | ||
|
|
0efb00724d | ||
|
|
22cb9ed063 | ||
|
|
79edc5c261 | ||
|
|
c90fcd19cc | ||
|
|
8d8126f849 | ||
|
|
a72bd7efcc | ||
|
|
87b1028aab | ||
|
|
ac465b9234 | ||
|
|
8a7c3c19fe | ||
|
|
ec5a8b49c8 | ||
|
|
ac3cb7f6c4 | ||
|
|
a17c704f46 | ||
|
|
d899267acb | ||
|
|
5f6de79c09 | ||
|
|
a09505afc2 | ||
|
|
5148054612 | ||
|
|
221e281f73 | ||
|
|
0ea27c6e9b | ||
|
|
da275b374f | ||
|
|
a47ffc6833 | ||
|
|
bb2083d10a | ||
|
|
bc81201c2e | ||
|
|
7121282b27 | ||
|
|
572777f11b | ||
|
|
cf8f2a38c3 | ||
|
|
a6b092d8c1 | ||
|
|
4d97c42ee5 | ||
|
|
501f617eaa | ||
|
|
34fb1c4a9f | ||
|
|
59195cccdd | ||
|
|
bb5017121f | ||
|
|
737f3e8899 | ||
|
|
0813199c7f | ||
|
|
a925c23d14 | ||
|
|
6bd3c8c07b | ||
|
|
6378c5e22f | ||
|
|
63123f3984 | ||
|
|
ba4f8612eb | ||
|
|
ad1284853b | ||
|
|
eb25d0df66 | ||
|
|
85636ccab7 | ||
|
|
2cb0afee73 | ||
|
|
1aa4494dbc | ||
|
|
fabde6e0ff | ||
|
|
75e01d3648 | ||
|
|
b8c800608e | ||
|
|
7af4b8de7b | ||
|
|
e421c49440 | ||
|
|
bd1ee9b937 | ||
|
|
1fc18bee5d | ||
|
|
a1a49bdddf | ||
|
|
761aede2df | ||
|
|
ac5e9c75e1 | ||
|
|
7d60f03131 | ||
|
|
8e5be13466 | ||
|
|
46616d6b42 | ||
|
|
c630300374 | ||
|
|
d63b33bb08 | ||
|
|
14d1e08051 | ||
|
|
b8f6877aba | ||
|
|
13577f71d6 | ||
|
|
21f477a674 | ||
|
|
d4b2ca5cee | ||
|
|
31cae204f6 | ||
|
|
00d1b11b0b | ||
|
|
d99c0a2382 | ||
|
|
9245e1c2a4 | ||
|
|
2961b79fb9 | ||
|
|
2e7529cc70 | ||
|
|
e1d5c9d45b | ||
|
|
5a3a8d781a | ||
|
|
08f78a2df4 | ||
|
|
0f540f4c25 | ||
|
|
f6f99fb459 | ||
|
|
c76d0d364d | ||
|
|
f79bd2a071 | ||
|
|
7ce825c5ea | ||
|
|
ab7e797fff | ||
|
|
26f1091d5f | ||
|
|
56d0254d2b | ||
|
|
4ee54738fa | ||
|
|
260c111932 | ||
|
|
1b598c8683 | ||
|
|
f1918fb4e0 | ||
|
|
09fa2a7d50 | ||
|
|
94e9848d61 | ||
|
|
fbfc959f82 |
@@ -88,123 +88,46 @@
|
||||
"IR Instruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll"
|
||||
],
|
||||
"IR IRBlock": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll"
|
||||
],
|
||||
"IR IRVariable": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRVariable.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll"
|
||||
],
|
||||
"IR IRFunction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRFunction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRFunction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRFunction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRFunction.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll"
|
||||
],
|
||||
"IR Operand": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/Operand.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll"
|
||||
],
|
||||
"IR IRType": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/IRType.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/IRType.qll"
|
||||
],
|
||||
"IR IRConfiguration": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/IRConfiguration.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/IRConfiguration.qll"
|
||||
],
|
||||
"IR UseSoundEscapeAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/UseSoundEscapeAnalysis.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/UseSoundEscapeAnalysis.qll"
|
||||
],
|
||||
"IR IRFunctionBase": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/IRFunctionBase.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/IRFunctionBase.qll"
|
||||
],
|
||||
"IR Operand Tag": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/OperandTag.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/OperandTag.qll"
|
||||
],
|
||||
"IR TInstruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll"
|
||||
],
|
||||
"IR TIRVariable": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/TIRVariable.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll"
|
||||
],
|
||||
"IR IR": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IR.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll"
|
||||
],
|
||||
"IR IRConsistency": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRConsistency.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRConsistency.qll"
|
||||
],
|
||||
"IR PrintIR": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/PrintIR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/PrintIR.qll"
|
||||
],
|
||||
"IR IntegerConstant": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerConstant.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerConstant.qll"
|
||||
],
|
||||
"IR IntegerInteval": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerInterval.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerInterval.qll"
|
||||
],
|
||||
"IR IntegerPartial": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerPartial.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerPartial.qll"
|
||||
],
|
||||
"IR Overlap": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/Overlap.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/Overlap.qll"
|
||||
],
|
||||
"IR EdgeKind": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/EdgeKind.qll"
|
||||
],
|
||||
"IR MemoryAccessKind": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/MemoryAccessKind.qll"
|
||||
],
|
||||
"IR TempVariableTag": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/TempVariableTag.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/TempVariableTag.qll"
|
||||
],
|
||||
"IR Opcode": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/Opcode.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll"
|
||||
],
|
||||
"IR SSAConsistency": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll"
|
||||
],
|
||||
"C++ IR InstructionImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll",
|
||||
@@ -252,8 +175,7 @@
|
||||
],
|
||||
"SSA AliasAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll"
|
||||
],
|
||||
"SSA PrintAliasAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintAliasAnalysis.qll",
|
||||
@@ -268,44 +190,28 @@
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingImports.qll"
|
||||
],
|
||||
"IR SSA SimpleSSA": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll"
|
||||
],
|
||||
"IR AliasConfiguration (unaliased_ssa)": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasConfiguration.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasConfiguration.qll"
|
||||
],
|
||||
"IR SSA SSAConstruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll"
|
||||
],
|
||||
"IR SSA PrintSSA": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintSSA.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll"
|
||||
],
|
||||
"IR ValueNumberInternal": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll"
|
||||
],
|
||||
"C++ IR ValueNumber": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/ValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll"
|
||||
],
|
||||
"C++ IR PrintValueNumbering": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/PrintValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/PrintValueNumbering.qll"
|
||||
],
|
||||
"C++ IR ConstantAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/constant/ConstantAnalysis.qll",
|
||||
@@ -333,38 +239,6 @@
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/PrintDominance.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/PrintDominance.qll"
|
||||
],
|
||||
"C# IR InstructionImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/InstructionImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/InstructionImports.qll"
|
||||
],
|
||||
"C# IR IRImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRImports.qll"
|
||||
],
|
||||
"C# IR IRBlockImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRBlockImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll"
|
||||
],
|
||||
"C# IR IRFunctionImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRFunctionImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll"
|
||||
],
|
||||
"C# IR IRVariableImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRVariableImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll"
|
||||
],
|
||||
"C# IR OperandImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/OperandImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/OperandImports.qll"
|
||||
],
|
||||
"C# IR PrintIRImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/PrintIRImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintIRImports.qll"
|
||||
],
|
||||
"C# IR ValueNumberingImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll"
|
||||
],
|
||||
"C# ControlFlowReachability": [
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/ControlFlowReachability.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ControlFlowReachability.qll"
|
||||
@@ -498,4 +372,4 @@
|
||||
"python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml",
|
||||
"python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,12 @@ 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
|
||||
|
||||
private module SourceVariables {
|
||||
cached
|
||||
private newtype TSourceVariable =
|
||||
TMkSourceVariable(SsaInternals0::SourceVariable base, int ind) {
|
||||
TMkSourceVariable(BaseSourceVariable base, int ind) {
|
||||
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||
}
|
||||
|
||||
@@ -30,7 +29,7 @@ private module SourceVariables {
|
||||
}
|
||||
|
||||
class SourceVariable extends TSourceVariable {
|
||||
SsaInternals0::SourceVariable base;
|
||||
BaseSourceVariable base;
|
||||
int ind;
|
||||
|
||||
SourceVariable() { this = TMkSourceVariable(base, ind) }
|
||||
@@ -42,7 +41,7 @@ private module SourceVariables {
|
||||
* Gets the base source variable (i.e., the variable without any
|
||||
* indirections) of this source variable.
|
||||
*/
|
||||
SsaInternals0::SourceVariable getBaseVariable() { result = base }
|
||||
BaseSourceVariable getBaseVariable() { result = base }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = repeatStars(this.getIndirection()) + base.toString() }
|
||||
@@ -104,17 +103,9 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
|
||||
|
||||
cached
|
||||
private newtype TDefOrUseImpl =
|
||||
TDefAddressImpl(BaseIRVariable v) or
|
||||
TDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) {
|
||||
isDef(_, _, address, base, _, indirectionIndex) and
|
||||
(
|
||||
// We only include the definition if the SSA pruning stage
|
||||
// concluded that the definition is live after the write.
|
||||
any(SsaInternals0::Def def).getAddressOperand() = address
|
||||
or
|
||||
// Since the pruning stage doesn't know about global variables we can't use the above check to
|
||||
// rule out dead assignments to globals.
|
||||
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
|
||||
)
|
||||
isDef(_, _, address, base, _, indirectionIndex)
|
||||
} or
|
||||
TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) {
|
||||
isUse(_, operand, base, _, indirectionIndex) and
|
||||
@@ -133,8 +124,7 @@ private newtype TDefOrUseImpl =
|
||||
TIteratorDef(
|
||||
Operand iteratorDerefAddress, BaseSourceVariableInstruction container, int indirectionIndex
|
||||
) {
|
||||
isIteratorDef(container, iteratorDerefAddress, _, _, indirectionIndex) and
|
||||
any(SsaInternals0::Def def | def.isIteratorDef()).getAddressOperand() = iteratorDerefAddress
|
||||
isIteratorDef(container, iteratorDerefAddress, _, _, indirectionIndex)
|
||||
} or
|
||||
TIteratorUse(
|
||||
Operand iteratorAddress, BaseSourceVariableInstruction container, int indirectionIndex
|
||||
@@ -267,24 +257,64 @@ private predicate sourceVariableHasBaseAndIndex(SourceVariable v, BaseSourceVari
|
||||
}
|
||||
|
||||
abstract class DefImpl extends DefOrUseImpl {
|
||||
Operand address;
|
||||
int ind;
|
||||
|
||||
bindingset[ind]
|
||||
DefImpl() { any() }
|
||||
|
||||
abstract int getIndirection();
|
||||
|
||||
abstract Node0Impl getValue();
|
||||
|
||||
abstract predicate isCertain();
|
||||
|
||||
Operand getAddressOperand() { result = address }
|
||||
|
||||
override int getIndirectionIndex() { result = ind }
|
||||
|
||||
override string toString() { result = "Def of " + this.getSourceVariable() }
|
||||
|
||||
abstract int getIndirection();
|
||||
|
||||
abstract predicate isCertain();
|
||||
|
||||
abstract Node0Impl getValue();
|
||||
}
|
||||
|
||||
/** An initial definition of an `IRVariable`'s address. */
|
||||
private class DefAddressImpl extends DefImpl, TDefAddressImpl {
|
||||
BaseIRVariable v;
|
||||
|
||||
DefAddressImpl() {
|
||||
this = TDefAddressImpl(v) and
|
||||
ind = 0
|
||||
}
|
||||
|
||||
final override int getIndirection() { result = 0 }
|
||||
|
||||
final override predicate isCertain() { any() }
|
||||
|
||||
final override Node0Impl getValue() { none() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
block = v.getIRVariable().getEnclosingIRFunction().getEntryBlock() and
|
||||
index = 0
|
||||
}
|
||||
|
||||
override Cpp::Location getLocation() { result = v.getIRVariable().getLocation() }
|
||||
|
||||
final override SourceVariable getSourceVariable() {
|
||||
result.getBaseVariable() = v and
|
||||
result.getIndirection() = 0
|
||||
}
|
||||
|
||||
final override BaseSourceVariableInstruction getBase() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An SSA definition that has an associated `Operand` representing the address
|
||||
* that is being written to.
|
||||
*/
|
||||
abstract private class OperandBasedDef extends DefImpl {
|
||||
Operand address;
|
||||
|
||||
bindingset[ind]
|
||||
OperandBasedDef() { any() }
|
||||
|
||||
Operand getAddressOperand() { result = address }
|
||||
|
||||
override Cpp::Location getLocation() { result = this.getAddressOperand().getUse().getLocation() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
@@ -292,7 +322,7 @@ abstract class DefImpl extends DefOrUseImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private class DirectDef extends DefImpl, TDefImpl {
|
||||
private class DirectDef extends OperandBasedDef, TDefImpl {
|
||||
BaseSourceVariableInstruction base;
|
||||
|
||||
DirectDef() { this = TDefImpl(base, address, ind) }
|
||||
@@ -306,7 +336,7 @@ private class DirectDef extends DefImpl, TDefImpl {
|
||||
override predicate isCertain() { isDef(true, _, address, base, _, ind) }
|
||||
}
|
||||
|
||||
private class IteratorDef extends DefImpl, TIteratorDef {
|
||||
private class IteratorDef extends OperandBasedDef, TIteratorDef {
|
||||
BaseSourceVariableInstruction container;
|
||||
|
||||
IteratorDef() { this = TIteratorDef(address, container, ind) }
|
||||
@@ -984,17 +1014,6 @@ predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a write at index `i` in basic block `bb` to variable `v` that's
|
||||
* subsequently read (as determined by the SSA pruning stage).
|
||||
*/
|
||||
private predicate variableWriteCand(IRBlock bb, int i, SourceVariable v) {
|
||||
exists(SsaInternals0::Def def, SsaInternals0::SourceVariable v0 |
|
||||
def.asDefOrUse().hasIndexInBlock(bb, i, v0) and
|
||||
v0 = v.getBaseVariable()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate sourceVariableIsGlobal(
|
||||
SourceVariable sv, GlobalLikeVariable global, IRFunction func, int indirectionIndex
|
||||
) {
|
||||
@@ -1018,16 +1037,14 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
DataFlowImplCommon::forceCachingInSameStage() and
|
||||
(
|
||||
variableWriteCand(bb, i, v) or
|
||||
sourceVariableIsGlobal(v, _, _, _)
|
||||
) and
|
||||
exists(DefImpl def | def.hasIndexInBlock(bb, i, v) |
|
||||
if def.isCertain() then certain = true else certain = false
|
||||
)
|
||||
or
|
||||
exists(GlobalDefImpl global |
|
||||
global.hasIndexInBlock(bb, i, v) and
|
||||
certain = true
|
||||
exists(DefImpl def | def.hasIndexInBlock(bb, i, v) |
|
||||
if def.isCertain() then certain = true else certain = false
|
||||
)
|
||||
or
|
||||
exists(GlobalDefImpl global |
|
||||
global.hasIndexInBlock(bb, i, v) and
|
||||
certain = true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1202,7 +1219,7 @@ class UseOrPhi extends SsaDefOrUse {
|
||||
class Def extends DefOrUse {
|
||||
override DefImpl defOrUse;
|
||||
|
||||
Operand getAddressOperand() { result = defOrUse.getAddressOperand() }
|
||||
Operand getAddressOperand() { result = defOrUse.(OperandBasedDef).getAddressOperand() }
|
||||
|
||||
Instruction getAddress() { result = this.getAddressOperand().getDef() }
|
||||
|
||||
|
||||
@@ -1,347 +0,0 @@
|
||||
/**
|
||||
* This module defines an initial SSA pruning stage that doesn't take
|
||||
* indirections into account.
|
||||
*/
|
||||
|
||||
private import codeql.ssa.Ssa as SsaImplCommon
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.internal.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.ir.implementation.raw.internal.SideEffects as SideEffects
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import semmle.code.cpp.ir.dataflow.internal.SsaInternalsCommon
|
||||
|
||||
private module SourceVariables {
|
||||
class SourceVariable extends BaseSourceVariable {
|
||||
/**
|
||||
* Gets the base source variable of this `SourceVariable`.
|
||||
*/
|
||||
BaseSourceVariable getBaseVariable() { result = this }
|
||||
}
|
||||
}
|
||||
|
||||
import SourceVariables
|
||||
|
||||
private newtype TDefOrUseImpl =
|
||||
TDefImpl(Operand address) { isDef(_, _, address, _, _, _) } or
|
||||
TUseImpl(Operand operand) {
|
||||
isUse(_, operand, _, _, _) and
|
||||
not isDef(true, _, operand, _, _, _)
|
||||
} or
|
||||
TIteratorDef(BaseSourceVariableInstruction container, Operand iteratorAddress) {
|
||||
isIteratorDef(container, iteratorAddress, _, _, _)
|
||||
} or
|
||||
TIteratorUse(BaseSourceVariableInstruction container, Operand iteratorAddress) {
|
||||
isIteratorUse(container, iteratorAddress, _, _)
|
||||
} or
|
||||
TFinalParameterUse(Parameter p) {
|
||||
any(Indirection indirection).getType() = p.getUnspecifiedType()
|
||||
}
|
||||
|
||||
abstract private class DefOrUseImpl extends TDefOrUseImpl {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the block of this definition or use. */
|
||||
final IRBlock getBlock() { this.hasIndexInBlock(result, _) }
|
||||
|
||||
/** Holds if this definition or use has index `index` in block `block`. */
|
||||
abstract predicate hasIndexInBlock(IRBlock block, int index);
|
||||
|
||||
final predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) {
|
||||
this.hasIndexInBlock(block, index) and
|
||||
sv = this.getSourceVariable()
|
||||
}
|
||||
|
||||
/** Gets the location of this element. */
|
||||
abstract Cpp::Location getLocation();
|
||||
|
||||
abstract BaseSourceVariableInstruction getBase();
|
||||
|
||||
final BaseSourceVariable getBaseSourceVariable() {
|
||||
result = this.getBase().getBaseSourceVariable()
|
||||
}
|
||||
|
||||
/** Gets the variable that is defined or used. */
|
||||
final SourceVariable getSourceVariable() {
|
||||
result.getBaseVariable() = this.getBaseSourceVariable()
|
||||
}
|
||||
|
||||
abstract predicate isCertain();
|
||||
}
|
||||
|
||||
abstract class DefImpl extends DefOrUseImpl {
|
||||
Operand address;
|
||||
|
||||
Operand getAddressOperand() { result = address }
|
||||
|
||||
abstract Node0Impl getValue();
|
||||
|
||||
override string toString() { result = address.toString() }
|
||||
|
||||
override Cpp::Location getLocation() { result = this.getAddressOperand().getLocation() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
this.getAddressOperand().getUse() = block.getInstruction(index)
|
||||
}
|
||||
}
|
||||
|
||||
private class DirectDef extends DefImpl, TDefImpl {
|
||||
DirectDef() { this = TDefImpl(address) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { isDef(_, _, address, result, _, _) }
|
||||
|
||||
override Node0Impl getValue() { isDef(_, result, address, _, _, _) }
|
||||
|
||||
override predicate isCertain() { isDef(true, _, address, _, _, _) }
|
||||
}
|
||||
|
||||
private class IteratorDef extends DefImpl, TIteratorDef {
|
||||
BaseSourceVariableInstruction container;
|
||||
|
||||
IteratorDef() { this = TIteratorDef(container, address) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { result = container }
|
||||
|
||||
override Node0Impl getValue() { isIteratorDef(_, address, result, _, _) }
|
||||
|
||||
override predicate isCertain() { none() }
|
||||
}
|
||||
|
||||
abstract class UseImpl extends DefOrUseImpl { }
|
||||
|
||||
abstract private class OperandBasedUse extends UseImpl {
|
||||
Operand operand;
|
||||
|
||||
override string toString() { result = operand.toString() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
// Ideally, this would just be implemented as:
|
||||
// ```
|
||||
// operand.getUse() = block.getInstruction(index)
|
||||
// ```
|
||||
// but because the IR generated for a snippet such as
|
||||
// ```
|
||||
// int x = *p++;
|
||||
// ```
|
||||
// looks like
|
||||
// ```
|
||||
// r1(glval<int>) = VariableAddress[x] :
|
||||
// r2(glval<int *>) = VariableAddress[p] :
|
||||
// r3(int *) = Load[p] : &:r2, m1
|
||||
// r4(int) = Constant[1] :
|
||||
// r5(int *) = PointerAdd[4] : r3, r4
|
||||
// m3(int *) = Store[p] : &:r2, r5
|
||||
// r6(int *) = CopyValue : r3
|
||||
// r7(int) = Load[?] : &:r6, ~m2
|
||||
// m2(int) = Store[x] : &:r1, r7
|
||||
// ```
|
||||
// we need to ensure that the `r3` operand of the `CopyValue` instruction isn't seen as a fresh use
|
||||
// of `p` that happens after the increment. So if the base instruction of this use comes from a
|
||||
// post-fix crement operation we set the index of the SSA use that wraps the `r3` operand at the
|
||||
// `CopyValue` instruction to be the same index as the `r3` operand at the `PointerAdd` instruction.
|
||||
// This ensures that the SSA library doesn't create flow from the `PointerAdd` to `r6`.
|
||||
exists(BaseSourceVariableInstruction base | base = this.getBase() |
|
||||
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
|
||||
then
|
||||
exists(Operand op |
|
||||
op =
|
||||
min(Operand cand, int i |
|
||||
isUse(_, cand, base, _, _) and
|
||||
block.getInstruction(i) = cand.getUse()
|
||||
|
|
||||
cand order by i
|
||||
) and
|
||||
block.getInstruction(index) = op.getUse()
|
||||
)
|
||||
else operand.getUse() = block.getInstruction(index)
|
||||
)
|
||||
}
|
||||
|
||||
final override Cpp::Location getLocation() { result = operand.getLocation() }
|
||||
}
|
||||
|
||||
private class DirectUse extends OperandBasedUse, TUseImpl {
|
||||
DirectUse() { this = TUseImpl(operand) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, _) }
|
||||
|
||||
override predicate isCertain() { isUse(true, operand, _, _, _) }
|
||||
}
|
||||
|
||||
private class IteratorUse extends OperandBasedUse, TIteratorUse {
|
||||
BaseSourceVariableInstruction container;
|
||||
|
||||
IteratorUse() { this = TIteratorUse(container, operand) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { result = container }
|
||||
|
||||
override predicate isCertain() { none() }
|
||||
}
|
||||
|
||||
private class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
||||
Parameter p;
|
||||
|
||||
FinalParameterUse() { this = TFinalParameterUse(p) }
|
||||
|
||||
override string toString() { result = p.toString() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
// Ideally, this should always be a `ReturnInstruction`, but if
|
||||
// someone forgets to write a `return` statement in a function
|
||||
// with a non-void return type we generate an `UnreachedInstruction`.
|
||||
// In this case we still want to generate flow out of such functions
|
||||
// if they write to a parameter. So we pick the index of the
|
||||
// `UnreachedInstruction` as the index of this use.
|
||||
// Note that a function may have both a `ReturnInstruction` and an
|
||||
// `UnreachedInstruction`. If that's the case this predicate will
|
||||
// return multiple results. I don't think this is detrimental to
|
||||
// performance, however.
|
||||
exists(Instruction return |
|
||||
return instanceof ReturnInstruction or
|
||||
return instanceof UnreachedInstruction
|
||||
|
|
||||
block.getInstruction(index) = return and
|
||||
return.getEnclosingFunction() = p.getFunction()
|
||||
)
|
||||
}
|
||||
|
||||
final override Cpp::Location getLocation() {
|
||||
// Parameters can have multiple locations. When there's a unique location we use
|
||||
// that one, but if multiple locations exist we default to an unknown location.
|
||||
result = unique( | | p.getLocation())
|
||||
or
|
||||
not exists(unique( | | p.getLocation())) and
|
||||
result instanceof UnknownDefaultLocation
|
||||
}
|
||||
|
||||
override BaseSourceVariableInstruction getBase() {
|
||||
exists(InitializeParameterInstruction init |
|
||||
init.getParameter() = p and
|
||||
// This is always a `VariableAddressInstruction`
|
||||
result = init.getAnOperand().getDef()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isCertain() { any() }
|
||||
}
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
import InputSigCommon
|
||||
import SourceVariables
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th write in block `bb` writes to the variable `v`.
|
||||
* `certain` is `true` if the write is guaranteed to overwrite the entire variable.
|
||||
*/
|
||||
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
DataFlowImplCommon::forceCachingInSameStage() and
|
||||
exists(DefImpl def | def.hasIndexInBlock(bb, i, v) |
|
||||
if def.isCertain() then certain = true else certain = false
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th read in block `bb` reads to the variable `v`.
|
||||
* `certain` is `true` if the read is guaranteed.
|
||||
*/
|
||||
predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(UseImpl use | use.hasIndexInBlock(bb, i, v) |
|
||||
if use.isCertain() then certain = true else certain = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TSsaDefOrUse =
|
||||
TDefOrUse(DefOrUseImpl defOrUse) {
|
||||
defOrUse instanceof UseImpl
|
||||
or
|
||||
// If `defOrUse` is a definition we only include it if the
|
||||
// SSA library concludes that it's live after the write.
|
||||
exists(DefinitionExt def, SourceVariable sv, IRBlock bb, int i |
|
||||
def.definesAt(sv, bb, i, _) and
|
||||
defOrUse.(DefImpl).hasIndexInBlock(bb, i, sv)
|
||||
)
|
||||
} or
|
||||
TPhi(PhiNode phi)
|
||||
|
||||
abstract private class SsaDefOrUse extends TSsaDefOrUse {
|
||||
string toString() { result = "SsaDefOrUse" }
|
||||
|
||||
DefOrUseImpl asDefOrUse() { none() }
|
||||
|
||||
PhiNode asPhi() { none() }
|
||||
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
class DefOrUse extends TDefOrUse, SsaDefOrUse {
|
||||
DefOrUseImpl defOrUse;
|
||||
|
||||
DefOrUse() { this = TDefOrUse(defOrUse) }
|
||||
|
||||
final override DefOrUseImpl asDefOrUse() { result = defOrUse }
|
||||
|
||||
final override Location getLocation() { result = defOrUse.getLocation() }
|
||||
|
||||
final SourceVariable getSourceVariable() { result = defOrUse.getSourceVariable() }
|
||||
}
|
||||
|
||||
class Phi extends TPhi, SsaDefOrUse {
|
||||
PhiNode phi;
|
||||
|
||||
Phi() { this = TPhi(phi) }
|
||||
|
||||
final override PhiNode asPhi() { result = phi }
|
||||
|
||||
final override Location getLocation() { result = phi.getBasicBlock().getLocation() }
|
||||
}
|
||||
|
||||
class UseOrPhi extends SsaDefOrUse {
|
||||
UseOrPhi() {
|
||||
this.asDefOrUse() instanceof UseImpl
|
||||
or
|
||||
this instanceof Phi
|
||||
}
|
||||
|
||||
final override Location getLocation() {
|
||||
result = this.asDefOrUse().getLocation() or result = this.(Phi).getLocation()
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = this.asDefOrUse().toString()
|
||||
or
|
||||
this instanceof Phi and
|
||||
result = "Phi"
|
||||
}
|
||||
}
|
||||
|
||||
class Def extends DefOrUse {
|
||||
override DefImpl defOrUse;
|
||||
|
||||
Operand getAddressOperand() { result = defOrUse.getAddressOperand() }
|
||||
|
||||
Instruction getAddress() { result = this.getAddressOperand().getDef() }
|
||||
|
||||
Node0Impl getValue() { result = defOrUse.getValue() }
|
||||
|
||||
override string toString() { result = this.asDefOrUse().toString() }
|
||||
|
||||
BaseSourceVariableInstruction getBase() { result = defOrUse.getBase() }
|
||||
|
||||
predicate isIteratorDef() { defOrUse instanceof IteratorDef }
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
|
||||
class PhiNode extends SsaImpl::DefinitionExt {
|
||||
PhiNode() {
|
||||
this instanceof SsaImpl::PhiNode or
|
||||
this instanceof SsaImpl::PhiReadNode
|
||||
}
|
||||
}
|
||||
|
||||
class DefinitionExt = SsaImpl::DefinitionExt;
|
||||
@@ -96,6 +96,9 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
exists(BuiltInVarArgsStart vaStartExpr |
|
||||
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
|
||||
)
|
||||
or
|
||||
// suppress destructors of temporary variables until proper support is added for them.
|
||||
exists(Expr parent | parent.getAnImplicitDestructorCall() = expr)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -744,9 +747,13 @@ newtype TTranslatedElement =
|
||||
// The declaration/initialization part of a `ConditionDeclExpr`
|
||||
TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or
|
||||
// The side effects of a `Call`
|
||||
TTranslatedCallSideEffects(CallOrAllocationExpr expr) { not ignoreSideEffects(expr) } or
|
||||
TTranslatedCallSideEffects(CallOrAllocationExpr expr) {
|
||||
not ignoreExpr(expr) and
|
||||
not ignoreSideEffects(expr)
|
||||
} or
|
||||
// The non-argument-specific side effect of a `Call`
|
||||
TTranslatedCallSideEffect(Expr expr, SideEffectOpcode opcode) {
|
||||
not ignoreExpr(expr) and
|
||||
not ignoreSideEffects(expr) and
|
||||
opcode = getCallSideEffectOpcode(expr)
|
||||
} or
|
||||
@@ -764,6 +771,7 @@ newtype TTranslatedElement =
|
||||
// Constructor calls lack a qualifier (`this`) expression, so we need to handle the side effects
|
||||
// on `*this` without an `Expr`.
|
||||
TTranslatedStructorQualifierSideEffect(Call call, SideEffectOpcode opcode) {
|
||||
not ignoreExpr(call) and
|
||||
not ignoreSideEffects(call) and
|
||||
call instanceof ConstructorCall and
|
||||
opcode = getASideEffectOpcode(call, -1)
|
||||
|
||||
@@ -97,19 +97,6 @@ abstract class TranslatedExpr extends TranslatedElement {
|
||||
)
|
||||
}
|
||||
|
||||
final override predicate hasAnImplicitDestructorCall() {
|
||||
exists(expr.getAnImplicitDestructorCall())
|
||||
}
|
||||
|
||||
final override int getFirstDestructorCallIndex() {
|
||||
not this.handlesDestructorsExplicitly() and
|
||||
(
|
||||
result = max(int childId | exists(this.getChildInternal(childId))) + 1
|
||||
or
|
||||
not exists(this.getChildInternal(_)) and result = 0
|
||||
)
|
||||
}
|
||||
|
||||
final override Locatable getAst() { result = expr }
|
||||
|
||||
final override Declaration getFunction() { result = getEnclosingDeclaration(expr) }
|
||||
|
||||
@@ -166,6 +166,8 @@ postWithInFlow
|
||||
| test.cpp:932:5:932:19 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:932:6:932:19 | global_pointer [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1045:9:1045:11 | ref arg buf | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1051:5:1051:11 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1052:9:1052:9 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
| example.c:15:37:15:37 | **b | example.c:15:37:15:37 | **b |
|
||||
| example.c:15:37:15:37 | **b | example.c:15:37:15:37 | **b |
|
||||
| example.c:15:37:15:37 | **b | example.c:15:37:15:37 | *b |
|
||||
| example.c:15:37:15:37 | **b | example.c:19:6:19:6 | *b |
|
||||
| example.c:15:37:15:37 | *b | example.c:15:37:15:37 | **b |
|
||||
| example.c:15:37:15:37 | *b | example.c:15:37:15:37 | *b |
|
||||
| example.c:15:37:15:37 | *b | example.c:15:37:15:37 | *b |
|
||||
| example.c:15:37:15:37 | *b | example.c:15:37:15:37 | b |
|
||||
| example.c:15:37:15:37 | *b | example.c:19:6:19:6 | b |
|
||||
| example.c:15:37:15:37 | b | example.c:15:37:15:37 | *b |
|
||||
| example.c:15:37:15:37 | b | example.c:15:37:15:37 | b |
|
||||
| example.c:15:37:15:37 | b | example.c:15:37:15:37 | b |
|
||||
| example.c:15:37:15:37 | b | example.c:19:6:19:6 | b |
|
||||
| example.c:15:44:15:46 | pos | example.c:24:24:24:26 | pos |
|
||||
| example.c:17:11:17:16 | *definition of coords | example.c:17:11:17:16 | *definition of coords |
|
||||
| example.c:17:11:17:16 | *definition of coords | example.c:17:11:17:16 | *definition of coords |
|
||||
| example.c:17:11:17:16 | *definition of coords | example.c:17:11:17:16 | *definition of coords |
|
||||
| example.c:17:11:17:16 | *definition of coords | example.c:17:11:17:16 | *definition of coords |
|
||||
| example.c:17:11:17:16 | *definition of coords | example.c:24:13:24:18 | *coords |
|
||||
| example.c:17:11:17:16 | *definition of coords [post update] | example.c:17:11:17:16 | *definition of coords |
|
||||
| example.c:17:11:17:16 | *definition of coords [post update] | example.c:24:13:24:18 | *coords |
|
||||
| example.c:17:11:17:16 | definition of coords | example.c:17:11:17:16 | *definition of coords |
|
||||
| example.c:17:11:17:16 | definition of coords | example.c:17:11:17:16 | definition of coords |
|
||||
| example.c:17:11:17:16 | definition of coords | example.c:17:11:17:16 | definition of coords |
|
||||
| example.c:17:11:17:16 | definition of coords | example.c:17:11:17:16 | definition of coords |
|
||||
| example.c:17:11:17:16 | definition of coords | example.c:17:11:17:16 | definition of coords |
|
||||
| example.c:17:11:17:16 | definition of coords | example.c:24:13:24:18 | coords |
|
||||
| example.c:17:11:17:16 | definition of coords [post update] | example.c:17:11:17:16 | definition of coords |
|
||||
| example.c:17:11:17:16 | definition of coords [post update] | example.c:24:13:24:18 | coords |
|
||||
| example.c:17:19:17:22 | {...} | example.c:17:19:17:22 | {...} |
|
||||
| example.c:17:21:17:21 | 0 | example.c:17:21:17:21 | 0 |
|
||||
| example.c:19:6:19:6 | *b | example.c:15:37:15:37 | *b |
|
||||
| example.c:19:6:19:6 | *b [post update] | example.c:15:37:15:37 | *b |
|
||||
| example.c:19:6:19:6 | *b [post update] | example.c:19:6:19:6 | *b |
|
||||
| example.c:19:6:19:6 | b [post update] | example.c:19:6:19:6 | b |
|
||||
| example.c:24:2:24:7 | *coords | example.c:26:18:26:24 | *& ... |
|
||||
| example.c:24:2:24:7 | *coords [post update] | example.c:26:18:26:24 | *& ... |
|
||||
| example.c:24:2:24:7 | coords | example.c:26:18:26:24 | & ... |
|
||||
| example.c:24:2:24:7 | coords [post update] | example.c:26:18:26:24 | & ... |
|
||||
| example.c:24:13:24:18 | *coords | example.c:24:2:24:7 | *coords |
|
||||
| example.c:24:13:24:18 | *coords [post update] | example.c:24:2:24:7 | *coords |
|
||||
| example.c:24:13:24:18 | coords | example.c:24:2:24:7 | coords |
|
||||
| example.c:24:13:24:18 | coords [post update] | example.c:24:2:24:7 | coords |
|
||||
| example.c:24:13:24:30 | ... = ... | example.c:24:2:24:30 | ... = ... |
|
||||
| example.c:24:20:24:20 | *y | example.c:24:20:24:20 | *y |
|
||||
| example.c:24:20:24:20 | y | example.c:24:20:24:20 | y |
|
||||
| example.c:24:20:24:20 | y | example.c:24:20:24:20 | y |
|
||||
| example.c:24:24:24:26 | pos | example.c:28:14:28:25 | & ... |
|
||||
| example.c:24:24:24:26 | pos | example.c:28:14:28:25 | *& ... |
|
||||
| example.c:24:24:24:30 | ... + ... | example.c:24:13:24:30 | ... = ... |
|
||||
| example.c:26:13:26:16 | call to getX | example.c:26:2:26:25 | ... = ... |
|
||||
| example.c:26:18:26:24 | & ... | example.c:26:2:26:7 | coords |
|
||||
| example.c:26:18:26:24 | *& ... | example.c:26:2:26:7 | *coords |
|
||||
| example.c:26:18:26:24 | getX output argument | example.c:26:2:26:7 | *coords |
|
||||
| example.c:26:18:26:24 | pointer to getX output argument | example.c:26:2:26:7 | coords |
|
||||
| example.c:26:19:26:24 | *coords | example.c:26:18:26:24 | *& ... |
|
||||
| example.c:26:19:26:24 | coords | example.c:26:18:26:24 | & ... |
|
||||
| example.c:28:22:28:25 | & ... | example.c:28:14:28:25 | & ... |
|
||||
| example.c:28:22:28:25 | *& ... | example.c:28:14:28:25 | *& ... |
|
||||
| example.c:28:23:28:25 | *pos | example.c:28:22:28:25 | *& ... |
|
||||
| example.c:28:23:28:25 | pos | example.c:28:22:28:25 | & ... |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:6:12:6:17 | call to source |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:7:8:7:9 | t1 |
|
||||
| test.cpp:7:8:7:9 | t1 | test.cpp:8:8:8:9 | t1 |
|
||||
| test.cpp:7:8:7:9 | t1 | test.cpp:8:8:8:9 | t1 |
|
||||
| test.cpp:8:3:8:9 | ... = ... | test.cpp:10:8:10:9 | t2 |
|
||||
| test.cpp:8:8:8:9 | t1 | test.cpp:8:3:8:9 | ... = ... |
|
||||
| test.cpp:8:8:8:9 | t1 | test.cpp:9:8:9:9 | t1 |
|
||||
| test.cpp:8:8:8:9 | t1 | test.cpp:9:8:9:9 | t1 |
|
||||
| test.cpp:9:8:9:9 | t1 | test.cpp:11:7:11:8 | t1 |
|
||||
| test.cpp:9:8:9:9 | t1 | test.cpp:11:7:11:8 | t1 |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:13:10:13:11 | t2 |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:15:3:15:6 | Phi |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:15:3:15:6 | Phi |
|
||||
| test.cpp:11:7:11:8 | t1 | test.cpp:21:8:21:9 | t1 |
|
||||
| test.cpp:12:5:12:10 | ... = ... | test.cpp:13:10:13:11 | t2 |
|
||||
| test.cpp:12:10:12:10 | 0 | test.cpp:12:5:12:10 | ... = ... |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:15:3:15:6 | Phi |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:15:3:15:6 | Phi |
|
||||
| test.cpp:15:3:15:6 | Phi | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:15:3:15:6 | Phi | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:15:8:15:9 | t2 | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:15:8:15:9 | t2 | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:17:3:17:8 | ... = ... | test.cpp:21:8:21:9 | t1 |
|
||||
| test.cpp:17:8:17:8 | 0 | test.cpp:17:3:17:8 | ... = ... |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | 0 |
|
||||
| test.cpp:23:15:23:16 | 0 | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:23:19:23:19 | Phi | test.cpp:23:19:23:19 | i |
|
||||
| test.cpp:23:19:23:19 | Phi | test.cpp:23:19:23:19 | i |
|
||||
| test.cpp:23:19:23:19 | Phi | test.cpp:23:23:23:24 | t1 |
|
||||
| test.cpp:23:19:23:19 | Phi | test.cpp:23:23:23:24 | t1 |
|
||||
| test.cpp:23:19:23:19 | Phi | test.cpp:24:10:24:11 | t2 |
|
||||
| test.cpp:23:19:23:19 | Phi | test.cpp:24:10:24:11 | t2 |
|
||||
| test.cpp:23:19:23:19 | i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:19:23:19 | i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:23:23:24 | t1 | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:23:23:23:24 | t1 | test.cpp:26:8:26:9 | t1 |
|
||||
| test.cpp:23:23:23:24 | t1 | test.cpp:26:8:26:9 | t1 |
|
||||
| test.cpp:23:27:23:27 | *i | test.cpp:23:27:23:27 | *i |
|
||||
| test.cpp:23:27:23:27 | *i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:27:23:27 | i | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:27:23:29 | ... ++ | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:23:27:23:29 | ... ++ | test.cpp:23:27:23:29 | ... ++ |
|
||||
| test.cpp:24:5:24:11 | ... = ... | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:23:19:23:19 | Phi |
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:24:5:24:11 | ... = ... |
|
||||
| test.cpp:382:48:382:54 | source1 | test.cpp:384:16:384:23 | *& ... |
|
||||
| test.cpp:383:12:383:13 | 0 | test.cpp:383:12:383:13 | 0 |
|
||||
| test.cpp:383:12:383:13 | 0 | test.cpp:384:10:384:13 | *& ... |
|
||||
| test.cpp:384:10:384:13 | & ... | test.cpp:384:3:384:8 | call to memcpy |
|
||||
| test.cpp:384:10:384:13 | & ... | test.cpp:384:10:384:13 | & ... |
|
||||
| test.cpp:384:10:384:13 | & ... | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:384:10:384:13 | *& ... | test.cpp:384:10:384:13 | *& ... |
|
||||
| test.cpp:384:10:384:13 | memcpy output argument | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:384:10:384:13 | pointer to memcpy output argument | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:384:11:384:13 | *tmp | test.cpp:384:10:384:13 | *& ... |
|
||||
| test.cpp:384:11:384:13 | tmp | test.cpp:384:10:384:13 | & ... |
|
||||
| test.cpp:384:16:384:23 | & ... | test.cpp:384:16:384:23 | & ... |
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:3:384:8 | **call to memcpy |
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:3:384:8 | *call to memcpy |
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:10:384:13 | memcpy output argument |
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:16:384:23 | *& ... |
|
||||
| test.cpp:384:16:384:23 | **(const void *)... | test.cpp:384:3:384:8 | **call to memcpy |
|
||||
| test.cpp:384:16:384:23 | **(const void *)... | test.cpp:384:10:384:13 | memcpy output argument |
|
||||
| test.cpp:384:17:384:23 | *source1 | test.cpp:384:16:384:23 | *& ... |
|
||||
| test.cpp:384:17:384:23 | source1 | test.cpp:384:16:384:23 | & ... |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:391:16:391:23 | *& ... |
|
||||
| test.cpp:388:66:388:66 | b | test.cpp:393:7:393:7 | b |
|
||||
| test.cpp:389:12:389:13 | 0 | test.cpp:389:12:389:13 | 0 |
|
||||
| test.cpp:389:12:389:13 | 0 | test.cpp:390:18:390:21 | *& ... |
|
||||
| test.cpp:390:18:390:21 | & ... | test.cpp:390:18:390:21 | & ... |
|
||||
| test.cpp:390:18:390:21 | & ... | test.cpp:391:10:391:13 | & ... |
|
||||
| test.cpp:390:18:390:21 | *& ... | test.cpp:390:18:390:21 | *& ... |
|
||||
| test.cpp:390:18:390:21 | *& ... | test.cpp:391:10:391:13 | *& ... |
|
||||
| test.cpp:390:19:390:21 | *tmp | test.cpp:390:18:390:21 | *& ... |
|
||||
| test.cpp:390:19:390:21 | tmp | test.cpp:390:18:390:21 | & ... |
|
||||
| test.cpp:391:10:391:13 | & ... | test.cpp:391:3:391:8 | call to memcpy |
|
||||
| test.cpp:391:10:391:13 | & ... | test.cpp:391:10:391:13 | & ... |
|
||||
| test.cpp:391:10:391:13 | & ... | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:391:10:391:13 | *& ... | test.cpp:391:10:391:13 | *& ... |
|
||||
| test.cpp:391:10:391:13 | memcpy output argument | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:391:10:391:13 | pointer to memcpy output argument | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:391:11:391:13 | *tmp | test.cpp:391:10:391:13 | *& ... |
|
||||
| test.cpp:391:11:391:13 | tmp | test.cpp:391:10:391:13 | & ... |
|
||||
| test.cpp:391:16:391:23 | & ... | test.cpp:391:16:391:23 | & ... |
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:3:391:8 | **call to memcpy |
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:3:391:8 | *call to memcpy |
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:10:391:13 | memcpy output argument |
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:16:391:23 | *& ... |
|
||||
| test.cpp:391:16:391:23 | **(const void *)... | test.cpp:391:3:391:8 | **call to memcpy |
|
||||
| test.cpp:391:16:391:23 | **(const void *)... | test.cpp:391:10:391:13 | memcpy output argument |
|
||||
| test.cpp:391:17:391:23 | *source1 | test.cpp:391:16:391:23 | *& ... |
|
||||
| test.cpp:391:17:391:23 | source1 | test.cpp:391:16:391:23 | & ... |
|
||||
| test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp |
|
||||
| test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp |
|
||||
| test.cpp:487:67:487:67 | **s | test.cpp:487:67:487:67 | **s |
|
||||
| test.cpp:487:67:487:67 | **s | test.cpp:487:67:487:67 | **s |
|
||||
| test.cpp:487:67:487:67 | **s | test.cpp:487:67:487:67 | *s |
|
||||
| test.cpp:487:67:487:67 | **s | test.cpp:488:21:488:21 | *s |
|
||||
| test.cpp:487:67:487:67 | *s | test.cpp:487:67:487:67 | **s |
|
||||
| test.cpp:487:67:487:67 | *s | test.cpp:487:67:487:67 | *s |
|
||||
| test.cpp:487:67:487:67 | *s | test.cpp:487:67:487:67 | *s |
|
||||
| test.cpp:487:67:487:67 | *s | test.cpp:487:67:487:67 | s |
|
||||
| test.cpp:487:67:487:67 | *s | test.cpp:488:21:488:21 | s |
|
||||
| test.cpp:487:67:487:67 | s | test.cpp:487:67:487:67 | *s |
|
||||
| test.cpp:487:67:487:67 | s | test.cpp:487:67:487:67 | s |
|
||||
| test.cpp:487:67:487:67 | s | test.cpp:487:67:487:67 | s |
|
||||
| test.cpp:487:67:487:67 | s | test.cpp:488:21:488:21 | s |
|
||||
| test.cpp:488:21:488:21 | *s | test.cpp:489:20:489:20 | *s |
|
||||
| test.cpp:488:21:488:21 | *s [post update] | test.cpp:489:20:489:20 | *s |
|
||||
| test.cpp:488:21:488:21 | s | test.cpp:489:20:489:20 | s |
|
||||
| test.cpp:488:21:488:21 | s | test.cpp:489:20:489:20 | s |
|
||||
| test.cpp:488:21:488:21 | s [post update] | test.cpp:489:20:489:20 | s |
|
||||
| test.cpp:488:24:488:30 | *content | test.cpp:488:21:488:30 | *content |
|
||||
| test.cpp:488:24:488:30 | content | test.cpp:488:21:488:30 | content |
|
||||
| test.cpp:489:20:489:20 | *s | test.cpp:487:67:487:67 | *s |
|
||||
| test.cpp:489:20:489:20 | *s [post update] | test.cpp:487:67:487:67 | *s |
|
||||
| test.cpp:489:20:489:20 | *s [post update] | test.cpp:489:20:489:20 | *s |
|
||||
| test.cpp:489:20:489:20 | s [post update] | test.cpp:489:20:489:20 | s |
|
||||
| test.cpp:489:23:489:29 | *content | test.cpp:489:23:489:29 | *content |
|
||||
| test.cpp:489:23:489:29 | *content | test.cpp:490:8:490:17 | * ... |
|
||||
| test.cpp:489:23:489:29 | content | test.cpp:489:23:489:29 | content |
|
||||
| test.cpp:489:23:489:29 | content | test.cpp:490:9:490:17 | p_content |
|
||||
| test.cpp:1050:12:1050:12 | definition of a | test.cpp:1051:3:1051:3 | *a |
|
||||
| test.cpp:1051:3:1051:3 | *a | test.cpp:1052:8:1052:9 | *& ... |
|
||||
| test.cpp:1051:3:1051:3 | *a [post update] | test.cpp:1052:8:1052:9 | *& ... |
|
||||
| test.cpp:1051:3:1051:3 | a | test.cpp:1052:8:1052:9 | & ... |
|
||||
| test.cpp:1051:3:1051:3 | a [post update] | test.cpp:1052:8:1052:9 | & ... |
|
||||
| test.cpp:1051:15:1051:21 | 0 | test.cpp:1051:3:1051:21 | ... = ... |
|
||||
| test.cpp:1051:15:1051:21 | *0 | test.cpp:1051:3:1051:21 | *... = ... |
|
||||
| test.cpp:1052:9:1052:9 | *a | test.cpp:1052:8:1052:9 | *& ... |
|
||||
| test.cpp:1052:9:1052:9 | a | test.cpp:1052:8:1052:9 | & ... |
|
||||
@@ -0,0 +1,8 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::Node nodeFrom, DataFlow::Node nodeTo
|
||||
where
|
||||
DataFlow::localFlowStep(nodeFrom, nodeTo) and
|
||||
nodeFrom.getFunction().getName().matches("%\\_with\\_local\\_flow")
|
||||
select nodeFrom, nodeTo
|
||||
@@ -81,3 +81,10 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (local
|
||||
| test.cpp:488:21:488:21 | s [post update] | test.cpp:489:20:489:20 | s |
|
||||
| test.cpp:488:24:488:30 | ref arg content | test.cpp:489:23:489:29 | content |
|
||||
| test.cpp:489:23:489:29 | content | test.cpp:490:9:490:17 | p_content |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1051:3:1051:3 | a |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1052:9:1052:9 | a |
|
||||
| test.cpp:1051:3:1051:3 | a [post update] | test.cpp:1052:9:1052:9 | a |
|
||||
| test.cpp:1051:3:1051:21 | ... = ... | test.cpp:1051:5:1051:11 | content [post update] |
|
||||
| test.cpp:1051:15:1051:21 | 0 | test.cpp:1051:3:1051:21 | ... = ... |
|
||||
| test.cpp:1052:8:1052:9 | ref arg & ... | test.cpp:1052:9:1052:9 | a [inner post update] |
|
||||
| test.cpp:1052:9:1052:9 | a | test.cpp:1052:8:1052:9 | & ... |
|
||||
|
||||
@@ -123,6 +123,7 @@ astFlow
|
||||
| test.cpp:842:11:842:16 | call to source | test.cpp:844:8:844:8 | y |
|
||||
| test.cpp:846:13:846:27 | call to indirect_source | test.cpp:848:23:848:25 | rpx |
|
||||
| test.cpp:860:54:860:59 | call to source | test.cpp:861:10:861:37 | static_local_pointer_dynamic |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1052:8:1052:9 | & ... |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
| true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x |
|
||||
|
||||
@@ -1044,4 +1044,10 @@ void* memset(void*, int, size_t);
|
||||
void memset_test(char* buf) { // $ ast-def=buf ir-def=*buf
|
||||
memset(buf, source(), 10);
|
||||
sink(*buf); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void flow_out_of_address_with_local_flow() {
|
||||
MyStruct a;
|
||||
a.content = nullptr;
|
||||
sink(&a); // $ SPURIOUS: ast
|
||||
}
|
||||
@@ -54,3 +54,5 @@
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:797:20:797:20 | a |
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:797:31:797:31 | a |
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:798:17:798:17 | a |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1051:3:1051:3 | a |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1052:9:1052:9 | a |
|
||||
|
||||
@@ -12779,7 +12779,7 @@ ir.cpp:
|
||||
# 2215| r2215_1(glval<bool>) = VariableAddress[b] :
|
||||
# 2215| r2215_2(bool) = Load[b] : &:r2215_1, ~m?
|
||||
# 2215| v2215_3(void) = ConditionalBranch : r2215_2
|
||||
#-----| False -> Block 5
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 3
|
||||
|
||||
# 2212| Block 1
|
||||
@@ -12796,44 +12796,35 @@ ir.cpp:
|
||||
# 2216| r2216_3(char *) = Convert : r2216_2
|
||||
# 2216| mu2216_4(char *) = Store[#throw2216:7] : &:r2216_1, r2216_3
|
||||
# 2216| v2216_5(void) = ThrowValue : &:r2216_1, ~m?
|
||||
#-----| Exception -> Block 6
|
||||
#-----| Exception -> Block 5
|
||||
|
||||
# 2219| Block 4
|
||||
# 2219| r2219_1(glval<String>) = VariableAddress[s] :
|
||||
# 2218| Block 4
|
||||
# 2218| r2218_1(glval<String>) = VariableAddress[s2] :
|
||||
# 2218| mu2218_2(String) = Uninitialized[s2] : &:r2218_1
|
||||
# 2218| r2218_3(glval<unknown>) = FunctionAddress[String] :
|
||||
# 2218| v2218_4(void) = Call[String] : func:r2218_3, this:r2218_1
|
||||
# 2218| mu2218_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2218| mu2218_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2218_1
|
||||
# 2219| r2219_1(glval<String>) = VariableAddress[s2] :
|
||||
# 2219| r2219_2(glval<unknown>) = FunctionAddress[~String] :
|
||||
# 2219| v2219_3(void) = Call[~String] : func:r2219_2, this:r2219_1
|
||||
# 2219| mu2219_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2219| v2219_5(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, ~m?
|
||||
# 2219| mu2219_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1
|
||||
#-----| Goto -> Block 5
|
||||
# 2219| r2219_7(glval<String>) = VariableAddress[s] :
|
||||
# 2219| r2219_8(glval<unknown>) = FunctionAddress[~String] :
|
||||
# 2219| v2219_9(void) = Call[~String] : func:r2219_8, this:r2219_7
|
||||
# 2219| mu2219_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2219| v2219_11(void) = ^IndirectReadSideEffect[-1] : &:r2219_7, ~m?
|
||||
# 2219| mu2219_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2219_7
|
||||
#-----| Goto -> Block 10
|
||||
|
||||
# 2218| Block 5
|
||||
# 2218| r2218_1(glval<String>) = VariableAddress[s2] :
|
||||
# 2218| mu2218_2(String) = Uninitialized[s2] : &:r2218_1
|
||||
# 2218| r2218_3(glval<unknown>) = FunctionAddress[String] :
|
||||
# 2218| v2218_4(void) = Call[String] : func:r2218_3, this:r2218_1
|
||||
# 2218| mu2218_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2218| mu2218_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2218_1
|
||||
# 2219| r2219_7(glval<String>) = VariableAddress[s2] :
|
||||
# 2219| r2219_8(glval<unknown>) = FunctionAddress[~String] :
|
||||
# 2219| v2219_9(void) = Call[~String] : func:r2219_8, this:r2219_7
|
||||
# 2219| mu2219_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2219| v2219_11(void) = ^IndirectReadSideEffect[-1] : &:r2219_7, ~m?
|
||||
# 2219| mu2219_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2219_7
|
||||
# 2219| r2219_13(glval<String>) = VariableAddress[s] :
|
||||
# 2219| r2219_14(glval<unknown>) = FunctionAddress[~String] :
|
||||
# 2219| v2219_15(void) = Call[~String] : func:r2219_14, this:r2219_13
|
||||
# 2219| mu2219_16(unknown) = ^CallSideEffect : ~m?
|
||||
# 2219| v2219_17(void) = ^IndirectReadSideEffect[-1] : &:r2219_13, ~m?
|
||||
# 2219| mu2219_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2219_13
|
||||
#-----| Goto -> Block 11
|
||||
# 2220| Block 5
|
||||
# 2220| v2220_1(void) = CatchByType[const char *] :
|
||||
#-----| Exception -> Block 7
|
||||
#-----| Goto -> Block 6
|
||||
|
||||
# 2220| Block 6
|
||||
# 2220| v2220_1(void) = CatchByType[const char *] :
|
||||
#-----| Exception -> Block 8
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 2220| Block 7
|
||||
# 2220| r2220_2(glval<char *>) = VariableAddress[s] :
|
||||
# 2220| mu2220_3(char *) = InitializeParameter[s] : &:r2220_2
|
||||
# 2220| r2220_4(char *) = Load[s] : &:r2220_2, ~m?
|
||||
@@ -12850,25 +12841,25 @@ ir.cpp:
|
||||
# 2221| v2221_10(void) = ThrowValue : &:r2221_1, ~m?
|
||||
#-----| Exception -> Block 2
|
||||
|
||||
# 2223| Block 8
|
||||
# 2223| Block 7
|
||||
# 2223| v2223_1(void) = CatchByType[const String &] :
|
||||
#-----| Exception -> Block 10
|
||||
#-----| Goto -> Block 9
|
||||
#-----| Exception -> Block 9
|
||||
#-----| Goto -> Block 8
|
||||
|
||||
# 2223| Block 9
|
||||
# 2223| Block 8
|
||||
# 2223| r2223_2(glval<String &>) = VariableAddress[e] :
|
||||
# 2223| mu2223_3(String &) = InitializeParameter[e] : &:r2223_2
|
||||
# 2223| r2223_4(String &) = Load[e] : &:r2223_2, ~m?
|
||||
# 2223| mu2223_5(unknown) = InitializeIndirection[e] : &:r2223_4
|
||||
# 2223| v2223_6(void) = NoOp :
|
||||
#-----| Goto -> Block 11
|
||||
#-----| Goto -> Block 10
|
||||
|
||||
# 2225| Block 10
|
||||
# 2225| Block 9
|
||||
# 2225| v2225_1(void) = CatchAny :
|
||||
# 2226| v2226_1(void) = ReThrow :
|
||||
#-----| Exception -> Block 2
|
||||
|
||||
# 2228| Block 11
|
||||
# 2228| Block 10
|
||||
# 2228| v2228_1(void) = NoOp :
|
||||
# 2212| v2212_9(void) = ReturnVoid :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
@@ -9,7 +9,6 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| 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
|
||||
|
||||
@@ -10,9 +10,6 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| 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() |
|
||||
|
||||
@@ -9,7 +9,6 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| 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
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
| test2.cpp:7:32:7:33 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:6:40:6:72 | sslv23 | sslv23 | test2.cpp:7:32:7:33 | call to context | no_sslv3 has not been set |
|
||||
| test2.cpp:7:32:7:33 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:6:40:6:72 | sslv23 | sslv23 | test2.cpp:7:32:7:33 | call to context | no_tlsv1 has not been set |
|
||||
| test2.cpp:7:32:7:33 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:6:40:6:72 | sslv23 | sslv23 | test2.cpp:7:32:7:33 | call to context | no_tlsv1_1 has not been set |
|
||||
| test2.cpp:15:32:15:33 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:14:40:14:72 | sslv23 | sslv23 | test2.cpp:15:32:15:33 | call to context | no_sslv3 has not been set |
|
||||
| test2.cpp:15:32:15:33 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:14:40:14:72 | sslv23 | sslv23 | test2.cpp:15:32:15:33 | call to context | no_tlsv1 has not been set |
|
||||
| test2.cpp:15:32:15:33 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:14:40:14:72 | sslv23 | sslv23 | test2.cpp:15:32:15:33 | call to context | no_tlsv1_1 has not been set |
|
||||
| test2.cpp:23:32:23:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:23:32:23:64 | sslv23 | sslv23 | test2.cpp:23:32:23:65 | call to context | no_sslv3 has not been set |
|
||||
| test2.cpp:23:32:23:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:23:32:23:64 | sslv23 | sslv23 | test2.cpp:23:32:23:65 | call to context | no_tlsv1 has not been set |
|
||||
| test2.cpp:23:32:23:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:23:32:23:64 | sslv23 | sslv23 | test2.cpp:23:32:23:65 | call to context | no_tlsv1_1 has not been set |
|
||||
@@ -19,22 +14,11 @@
|
||||
| test2.cpp:52:32:52:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_sslv3 has not been set |
|
||||
| test2.cpp:52:32:52:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_tlsv1 has not been set |
|
||||
| test2.cpp:52:32:52:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_tlsv1_1 has not been set |
|
||||
| test3.cpp:7:32:7:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test3.cpp:7:32:7:61 | tls | tls | test3.cpp:7:32:7:62 | call to context | no_tlsv1 has not been set |
|
||||
| test3.cpp:7:32:7:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test3.cpp:7:32:7:61 | tls | tls | test3.cpp:7:32:7:62 | call to context | no_tlsv1_1 has not been set |
|
||||
| test3.cpp:15:32:15:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test3.cpp:15:32:15:61 | tls | tls | test3.cpp:15:32:15:62 | call to context | no_tlsv1 has not been set |
|
||||
| test3.cpp:15:32:15:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test3.cpp:15:32:15:61 | tls | tls | test3.cpp:15:32:15:62 | call to context | no_tlsv1_1 has not been set |
|
||||
| test.cpp:11:32:11:69 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:11:32:11:68 | tls_client | tls_client | test.cpp:11:32:11:69 | call to context | no_tlsv1 has not been set |
|
||||
| test.cpp:11:32:11:69 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:11:32:11:68 | tls_client | tls_client | test.cpp:11:32:11:69 | call to context | no_tlsv1_1 has not been set |
|
||||
| test.cpp:17:32:17:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:17:32:17:64 | sslv23 | sslv23 | test.cpp:17:32:17:65 | call to context | no_sslv3 has not been set |
|
||||
| test.cpp:17:32:17:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:17:32:17:64 | sslv23 | sslv23 | test.cpp:17:32:17:65 | call to context | no_tlsv1 has not been set |
|
||||
| test.cpp:17:32:17:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:17:32:17:64 | sslv23 | sslv23 | test.cpp:17:32:17:65 | call to context | no_tlsv1_1 has not been set |
|
||||
| test.cpp:25:32:25:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:25:32:25:64 | sslv23 | sslv23 | test.cpp:25:32:25:65 | call to context | no_sslv3 has not been set |
|
||||
| test.cpp:25:32:25:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:25:32:25:64 | sslv23 | sslv23 | test.cpp:25:32:25:65 | call to context | no_tlsv1 has not been set |
|
||||
| test.cpp:25:32:25:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:25:32:25:64 | sslv23 | sslv23 | test.cpp:25:32:25:65 | call to context | no_tlsv1_1 has not been set |
|
||||
| test.cpp:31:32:31:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_sslv3 has not been set |
|
||||
| test.cpp:31:32:31:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_tlsv1 has not been set |
|
||||
| test.cpp:31:32:31:65 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_tlsv1_1 has not been set |
|
||||
| test.cpp:36:32:36:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:36:32:36:61 | tls | tls | test.cpp:36:32:36:62 | call to context | no_tlsv1 has not been set |
|
||||
| test.cpp:36:32:36:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:36:32:36:61 | tls | tls | test.cpp:36:32:36:62 | call to context | no_tlsv1_1 has not been set |
|
||||
| test.cpp:41:32:41:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:41:32:41:61 | tls | tls | test.cpp:41:32:41:62 | call to context | no_tlsv1 has not been set |
|
||||
| test.cpp:41:32:41:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:41:32:41:61 | tls | tls | test.cpp:41:32:41:62 | call to context | no_tlsv1_1 has not been set |
|
||||
| test.cpp:41:32:41:62 | call to context | This usage of 'boost::asio::ssl::context::context' with protocol $@ is not configured correctly: The option $@. | test.cpp:41:32:41:61 | tls | tls | test.cpp:43:6:43:16 | call to set_options | no_tlsv1_2 was set |
|
||||
|
||||
@@ -8,13 +8,13 @@ void SetOptionsNoOldTls(boost::asio::ssl::context& ctx)
|
||||
|
||||
void TestProperConfiguration_inter_CorrectUsage01()
|
||||
{
|
||||
boost::asio::ssl::context ctx(boost::asio::ssl::context::tls_client); // GOOD [FALSE POSITIVE]
|
||||
boost::asio::ssl::context ctx(boost::asio::ssl::context::tls_client); // GOOD
|
||||
SetOptionsNoOldTls(ctx);
|
||||
}
|
||||
|
||||
void TestProperConfiguration_inter_CorrectUsage02()
|
||||
{
|
||||
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); // GOOD [FALSE POSITIVE]
|
||||
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); // GOOD
|
||||
ctx.set_options(boost::asio::ssl::context::no_tlsv1 |
|
||||
boost::asio::ssl::context::no_tlsv1_1 |
|
||||
boost::asio::ssl::context::no_sslv3);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
void good1()
|
||||
{
|
||||
// GOOD [FALSE POSITIVE]
|
||||
// GOOD
|
||||
boost::asio::ssl::context::method m = boost::asio::ssl::context::sslv23;
|
||||
boost::asio::ssl::context ctx(m);
|
||||
ctx.set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1 | boost::asio::ssl::context::no_sslv3);
|
||||
|
||||
@@ -13,7 +13,7 @@ void useTLS_bad()
|
||||
void useTLS_good()
|
||||
{
|
||||
boost::asio::ssl::context ctx(boost::asio::ssl::context::tls);
|
||||
ctx.set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1); // GOOD [FALSE POSITIVE]
|
||||
ctx.set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1); // GOOD
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:log-injection,sink:sql-injection,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value
|
||||
Amazon.Lambda.APIGatewayEvents,,6,,,,,,,,,,,,,,,6,,
|
||||
Amazon.Lambda.Core,10,,,,,,,,,,,10,,,,,,,
|
||||
Dapper,55,,,,,,,,,,,,55,,,,,,
|
||||
ILCompiler,,,81,,,,,,,,,,,,,,,81,
|
||||
ILLink.RoslynAnalyzer,,,63,,,,,,,,,,,,,,,63,
|
||||
ILLink.Shared,,,32,,,,,,,,,,,,,,,29,3
|
||||
ILLink.Tasks,,,5,,,,,,,,,,,,,,,5,
|
||||
Internal.IL,,,69,,,,,,,,,,,,,,,67,2
|
||||
Internal.Pgo,,,9,,,,,,,,,,,,,,,8,1
|
||||
Internal.TypeSystem,,,367,,,,,,,,,,,,,,,331,36
|
||||
JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,,7,
|
||||
Microsoft.Android.Build,,,14,,,,,,,,,,,,,,,14,
|
||||
Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,7,
|
||||
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,
|
||||
Microsoft.CSharp,,,24,,,,,,,,,,,,,,,24,
|
||||
Microsoft.Diagnostics.Tools.Pgo,,,13,,,,,,,,,,,,,,,13,
|
||||
Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,,6,,,,,,12
|
||||
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.Caching.Memory,,,38,,,,,,,,,,,,,,,37,1
|
||||
Microsoft.Extensions.Configuration,,,83,,,,,,,,,,,,,,,80,3
|
||||
Microsoft.Extensions.DependencyInjection,,,120,,,,,,,,,,,,,,,120,
|
||||
Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,,,,12,
|
||||
Microsoft.Extensions.Diagnostics.Metrics,,,13,,,,,,,,,,,,,,,13,
|
||||
Microsoft.Extensions.FileProviders,,,15,,,,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.FileSystemGlobbing,,,16,,,,,,,,,,,,,,,14,2
|
||||
Microsoft.Extensions.Hosting,,,23,,,,,,,,,,,,,,,22,1
|
||||
Microsoft.Extensions.Http,,,10,,,,,,,,,,,,,,,10,
|
||||
Microsoft.Extensions.Logging,,,60,,,,,,,,,,,,,,,59,1
|
||||
Microsoft.Extensions.Options,,,8,,,,,,,,,,,,,,,8,
|
||||
Microsoft.Extensions.Primitives,,,64,,,,,,,,,,,,,,,64,
|
||||
Microsoft.Interop,,,78,,,,,,,,,,,,,,,78,
|
||||
Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,,1,
|
||||
Microsoft.NET.WebAssembly.Webcil,,,7,,,,,,,,,,,,,,,7,
|
||||
Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,,5,5
|
||||
Microsoft.WebAssembly.Build.Tasks,,,3,,,,,,,,,,,,,,,3,
|
||||
Microsoft.Win32.SafeHandles,,,4,,,,,,,,,,,,,,,4,
|
||||
Mono.Linker,,,163,,,,,,,,,,,,,,,163,
|
||||
MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,
|
||||
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,73,18
|
||||
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,7,
|
||||
SourceGenerators,,,4,,,,,,,,,,,,,,,4,
|
||||
System,67,25,11862,,8,8,9,,,4,5,,33,1,17,3,4,9896,1966
|
||||
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,
|
||||
package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:log-injection,sink:sql-injection,source:commandargs,source:environment,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value
|
||||
Amazon.Lambda.APIGatewayEvents,,6,,,,,,,,,,,,,,,,,6,,
|
||||
Amazon.Lambda.Core,10,,,,,,,,,,,10,,,,,,,,,
|
||||
Dapper,55,,,,,,,,,,,,55,,,,,,,,
|
||||
ILCompiler,,,81,,,,,,,,,,,,,,,,,81,
|
||||
ILLink.RoslynAnalyzer,,,63,,,,,,,,,,,,,,,,,63,
|
||||
ILLink.Shared,,,32,,,,,,,,,,,,,,,,,29,3
|
||||
ILLink.Tasks,,,5,,,,,,,,,,,,,,,,,5,
|
||||
Internal.IL,,,69,,,,,,,,,,,,,,,,,67,2
|
||||
Internal.Pgo,,,9,,,,,,,,,,,,,,,,,8,1
|
||||
Internal.TypeSystem,,,367,,,,,,,,,,,,,,,,,331,36
|
||||
JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,,,,7,
|
||||
Microsoft.Android.Build,,,14,,,,,,,,,,,,,,,,,14,
|
||||
Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,,,7,
|
||||
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,,,
|
||||
Microsoft.CSharp,,,24,,,,,,,,,,,,,,,,,24,
|
||||
Microsoft.Diagnostics.Tools.Pgo,,,13,,,,,,,,,,,,,,,,,13,
|
||||
Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,,6,,,,,,,,12
|
||||
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.Caching.Memory,,,38,,,,,,,,,,,,,,,,,37,1
|
||||
Microsoft.Extensions.Configuration,,2,89,,,,,,,,,,,,2,,,,,86,3
|
||||
Microsoft.Extensions.DependencyInjection,,,120,,,,,,,,,,,,,,,,,120,
|
||||
Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,,,,,,12,
|
||||
Microsoft.Extensions.Diagnostics.Metrics,,,13,,,,,,,,,,,,,,,,,13,
|
||||
Microsoft.Extensions.FileProviders,,,15,,,,,,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.FileSystemGlobbing,,,16,,,,,,,,,,,,,,,,,14,2
|
||||
Microsoft.Extensions.Hosting,,,23,,,,,,,,,,,,,,,,,22,1
|
||||
Microsoft.Extensions.Http,,,10,,,,,,,,,,,,,,,,,10,
|
||||
Microsoft.Extensions.Logging,,,60,,,,,,,,,,,,,,,,,59,1
|
||||
Microsoft.Extensions.Options,,,8,,,,,,,,,,,,,,,,,8,
|
||||
Microsoft.Extensions.Primitives,,,64,,,,,,,,,,,,,,,,,64,
|
||||
Microsoft.Interop,,,78,,,,,,,,,,,,,,,,,78,
|
||||
Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,,,,1,
|
||||
Microsoft.NET.WebAssembly.Webcil,,,7,,,,,,,,,,,,,,,,,7,
|
||||
Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,,,,5,5
|
||||
Microsoft.WebAssembly.Build.Tasks,,,3,,,,,,,,,,,,,,,,,3,
|
||||
Microsoft.Win32.SafeHandles,,,4,,,,,,,,,,,,,,,,,4,
|
||||
Mono.Linker,,,163,,,,,,,,,,,,,,,,,163,
|
||||
MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,,,
|
||||
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,73,18
|
||||
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,7,
|
||||
SourceGenerators,,,4,,,,,,,,,,,,,,,,,4,
|
||||
System,67,30,11864,,8,8,9,,,4,5,,33,2,3,1,17,3,4,9898,1966
|
||||
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -8,7 +8,7 @@ C# framework & library support
|
||||
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
|
||||
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
|
||||
System,"``System.*``, ``System``",25,11862,67,9
|
||||
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32.SafeHandles``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",6,1541,148,
|
||||
Totals,,31,13410,409,9
|
||||
System,"``System.*``, ``System``",30,11864,67,9
|
||||
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32.SafeHandles``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",8,1547,148,
|
||||
Totals,,38,13418,409,9
|
||||
|
||||
|
||||
@@ -814,6 +814,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private IEnumerable<string> RestoreSolutions(IEnumerable<string> solutions, out IEnumerable<string> assets)
|
||||
{
|
||||
var successCount = 0;
|
||||
var nugetSourceFailures = 0;
|
||||
var assetFiles = new List<string>();
|
||||
var projects = solutions.SelectMany(solution =>
|
||||
{
|
||||
@@ -823,11 +824,16 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
if (res.HasNugetPackageSourceError)
|
||||
{
|
||||
nugetSourceFailures++;
|
||||
}
|
||||
assetFiles.AddRange(res.AssetsFilePaths);
|
||||
return res.RestoredProjects;
|
||||
}).ToList();
|
||||
assets = assetFiles;
|
||||
CompilationInfos.Add(("Successfully restored solution files", successCount.ToString()));
|
||||
CompilationInfos.Add(("Failed solution restore with package source error", nugetSourceFailures.ToString()));
|
||||
CompilationInfos.Add(("Restored projects through solution files", projects.Count.ToString()));
|
||||
return projects;
|
||||
}
|
||||
@@ -841,6 +847,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private void RestoreProjects(IEnumerable<string> projects, out IEnumerable<string> assets)
|
||||
{
|
||||
var successCount = 0;
|
||||
var nugetSourceFailures = 0;
|
||||
var assetFiles = new List<string>();
|
||||
var sync = new object();
|
||||
Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = threads }, project =>
|
||||
@@ -853,11 +860,16 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
if (res.HasNugetPackageSourceError)
|
||||
{
|
||||
nugetSourceFailures++;
|
||||
}
|
||||
assetFiles.AddRange(res.AssetsFilePaths);
|
||||
}
|
||||
});
|
||||
assets = assetFiles;
|
||||
CompilationInfos.Add(("Successfully restored project files", successCount.ToString()));
|
||||
CompilationInfos.Add(("Failed project restore with package source error", nugetSourceFailures.ToString()));
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"^(.+)\.(\d+\.\d+\.\d+(-(.+))?)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||
|
||||
@@ -131,11 +131,16 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
try
|
||||
{
|
||||
var o = JObject.Parse(File.ReadAllText(path));
|
||||
versions.Add((string)o?["sdk"]?["version"]!);
|
||||
var v = (string?)o?["sdk"]?["version"];
|
||||
if (v is not null)
|
||||
{
|
||||
versions.Add(v);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// not a valid `global.json` file
|
||||
logger.LogInfo($"Couldn't find .NET SDK version in '{path}'.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,10 +60,9 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
try
|
||||
{
|
||||
FileUtils.TryDelete(output.FullName);
|
||||
if (shouldCleanUpContainingFolder)
|
||||
{
|
||||
output.Directory?.Delete(true);
|
||||
FileUtils.TryDelete(output.FullName);
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -105,12 +104,19 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
|
||||
public void Analysed(int item, int total, string source, string output, TimeSpan time, AnalysisAction action)
|
||||
{
|
||||
logger.Log(Severity.Info, "[{0}/{1}] {2} ({3})", item, total, source,
|
||||
action == AnalysisAction.Extracted
|
||||
? time.ToString()
|
||||
: action == AnalysisAction.Excluded
|
||||
? "excluded"
|
||||
: "up to date");
|
||||
var extra = action switch
|
||||
{
|
||||
AnalysisAction.Extracted => time.ToString(),
|
||||
AnalysisAction.Excluded => "excluded",
|
||||
AnalysisAction.UpToDate => "up to date",
|
||||
_ => "unknown action"
|
||||
};
|
||||
logger.LogInfo($"[{item}/{total}] {source} ({extra})");
|
||||
}
|
||||
|
||||
public void Started(int item, int total, string source)
|
||||
{
|
||||
logger.LogInfo($"[{item}/{total}] {source} (processing started)");
|
||||
}
|
||||
|
||||
public void MissingType(string type)
|
||||
|
||||
@@ -9,19 +9,20 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private readonly string assemblyPath;
|
||||
private readonly IAssemblySymbol assembly;
|
||||
private readonly bool isOutputAssembly;
|
||||
|
||||
private Assembly(Context cx, Microsoft.CodeAnalysis.Location? init)
|
||||
: base(cx, init)
|
||||
{
|
||||
if (init is null)
|
||||
isOutputAssembly = init is null;
|
||||
if (isOutputAssembly)
|
||||
{
|
||||
// This is the output assembly
|
||||
assemblyPath = cx.Extractor.OutputPath;
|
||||
assembly = cx.Compilation.Assembly;
|
||||
}
|
||||
else
|
||||
{
|
||||
assembly = init.MetadataModule!.ContainingAssembly;
|
||||
assembly = init!.MetadataModule!.ContainingAssembly;
|
||||
var identity = assembly.Identity;
|
||||
var idString = identity.Name + " " + identity.Version;
|
||||
assemblyPath = cx.Extractor.GetAssemblyFile(idString);
|
||||
@@ -32,8 +33,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
if (assemblyPath is not null)
|
||||
{
|
||||
trapFile.assemblies(this, File.Create(Context, assemblyPath), assembly.ToString() ?? "",
|
||||
assembly.Identity.Name, assembly.Identity.Version.ToString());
|
||||
var isBuildlessOutputAssembly = isOutputAssembly && Context.Extractor.Mode.HasFlag(ExtractorMode.Standalone);
|
||||
var identifier = isBuildlessOutputAssembly
|
||||
? ""
|
||||
: assembly.ToString() ?? "";
|
||||
var name = isBuildlessOutputAssembly ? "" : assembly.Identity.Name;
|
||||
var version = isBuildlessOutputAssembly ? "" : assembly.Identity.Version.ToString();
|
||||
trapFile.assemblies(this, File.Create(Context, assemblyPath), identifier, name, version);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,8 +74,16 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(assembly.ToString());
|
||||
if (!(assemblyPath is null))
|
||||
if (isOutputAssembly && Context.Extractor.Mode.HasFlag(ExtractorMode.Standalone))
|
||||
{
|
||||
trapFile.Write("buildlessOutputAssembly");
|
||||
}
|
||||
else
|
||||
{
|
||||
trapFile.Write(assembly.ToString());
|
||||
}
|
||||
|
||||
if (assemblyPath is not null)
|
||||
{
|
||||
trapFile.Write("#file:///");
|
||||
trapFile.Write(assemblyPath.Replace("\\", "/"));
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
@@ -23,8 +24,6 @@ namespace Semmle.Extraction.CSharp
|
||||
private protected Entities.Compilation? compilationEntity;
|
||||
private IDisposable? compilationTrapFile;
|
||||
|
||||
private readonly object progressMutex = new object();
|
||||
|
||||
// The bulk of the extraction work, potentially executed in parallel.
|
||||
protected readonly List<Action> extractionTasks = new List<Action>();
|
||||
private int taskCount = 0;
|
||||
@@ -131,6 +130,9 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
var skipExtraction = options.Cache && File.Exists(trapWriter.TrapFile);
|
||||
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, assemblyPath);
|
||||
|
||||
if (!skipExtraction)
|
||||
{
|
||||
/* Note on parallel builds:
|
||||
@@ -167,7 +169,7 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
ReportProgress(assemblyPath, trapWriter.TrapFile, stopwatch.Elapsed, skipExtraction ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
ReportProgressTaskDone(currentTaskId, assemblyPath, trapWriter.TrapFile, stopwatch.Elapsed, skipExtraction ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
@@ -177,11 +179,13 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
private void DoExtractCIL(PortableExecutableReference r)
|
||||
{
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, r.FilePath);
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
CIL.Analyser.ExtractCIL(r.FilePath!, Logger, options, out var trapFile, out var extracted);
|
||||
stopwatch.Stop();
|
||||
ReportProgress(r.FilePath, trapFile, stopwatch.Elapsed, extracted ? AnalysisAction.Extracted : AnalysisAction.UpToDate);
|
||||
ReportProgressTaskDone(currentTaskId, r.FilePath, trapFile, stopwatch.Elapsed, extracted ? AnalysisAction.Extracted : AnalysisAction.UpToDate);
|
||||
}
|
||||
|
||||
private void DoExtractTree(SyntaxTree tree)
|
||||
@@ -201,6 +205,9 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
upToDate = options.Fast && FileIsUpToDate(sourcePath, trapWriter.TrapFile);
|
||||
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, sourcePath);
|
||||
|
||||
if (!upToDate)
|
||||
{
|
||||
var cx = new Context(extractor, compilation.Clone(), trapWriter, new SourceScope(tree), addAssemblyTrapPrefix);
|
||||
@@ -221,7 +228,7 @@ namespace Semmle.Extraction.CSharp
|
||||
cx.PopulateAll();
|
||||
}
|
||||
|
||||
ReportProgress(sourcePath, trapPath, stopwatch.Elapsed, upToDate ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
ReportProgressTaskDone(currentTaskId, sourcePath, trapPath, stopwatch.Elapsed, upToDate ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
@@ -234,6 +241,11 @@ namespace Semmle.Extraction.CSharp
|
||||
try
|
||||
{
|
||||
var assemblyPath = extractor.OutputPath;
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, assemblyPath);
|
||||
|
||||
var transformedAssemblyPath = PathTransformer.Transform(assemblyPath);
|
||||
var assembly = compilation.Assembly;
|
||||
var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
|
||||
@@ -243,6 +255,8 @@ namespace Semmle.Extraction.CSharp
|
||||
compilationEntity = Entities.Compilation.Create(cx);
|
||||
|
||||
extractor.CompilationInfos.ForEach(ci => trapWriter.Writer.compilation_info(compilationEntity, ci.key, ci.value));
|
||||
|
||||
ReportProgressTaskDone(currentTaskId, assemblyPath, trapWriter.TrapFile, stopwatch.Elapsed, AnalysisAction.Extracted);
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
@@ -279,10 +293,19 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
private void ReportProgress(string src, string output, TimeSpan time, AnalysisAction action)
|
||||
private int IncrementTaskCount()
|
||||
{
|
||||
lock (progressMutex)
|
||||
progressMonitor.Analysed(++taskCount, extractionTasks.Count, src, output, time, action);
|
||||
return Interlocked.Increment(ref taskCount);
|
||||
}
|
||||
|
||||
private void ReportProgressTaskStarted(int currentCount, string src)
|
||||
{
|
||||
progressMonitor.Started(currentCount, extractionTasks.Count, src);
|
||||
}
|
||||
|
||||
private void ReportProgressTaskDone(int currentCount, string src, string output, TimeSpan time, AnalysisAction action)
|
||||
{
|
||||
progressMonitor.Analysed(currentCount, extractionTasks.Count, src, output, time, action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -47,6 +47,8 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
public void Started(int item, int total, string source) { }
|
||||
|
||||
public void MissingNamespace(string @namespace) { }
|
||||
|
||||
public void MissingSummary(int types, int namespaces) { }
|
||||
|
||||
@@ -19,6 +19,11 @@ namespace Semmle.Extraction.CSharp
|
||||
/// <param name="action">What action was taken for the file.</param>
|
||||
void Analysed(int item, int total, string source, string output, TimeSpan time, AnalysisAction action);
|
||||
|
||||
/// <summary>
|
||||
/// Callback that processing of a particular item has been started.
|
||||
/// </summary>
|
||||
void Started(int item, int total, string source);
|
||||
|
||||
/// <summary>
|
||||
/// A "using namespace" directive was seen but the given
|
||||
/// namespace could not be found.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import csharp
|
||||
import cil
|
||||
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific
|
||||
private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific
|
||||
@@ -31,11 +30,6 @@ private module Input implements InputSig<CsharpDataFlow> {
|
||||
n instanceof FlowInsensitiveFieldNode
|
||||
}
|
||||
|
||||
predicate missingLocationExclude(Node n) {
|
||||
// Some CIL methods are missing locations
|
||||
n.asParameter() instanceof CIL::Parameter
|
||||
}
|
||||
|
||||
predicate postWithInFlowExclude(Node n) {
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
@@ -48,8 +42,6 @@ private module Input implements InputSig<CsharpDataFlow> {
|
||||
not exists(LocalFlow::getAPostUpdateNodeForArg(n.getControlFlowNode()))
|
||||
or
|
||||
n instanceof ParamsArgumentNode
|
||||
or
|
||||
n.asExpr() instanceof CIL::Expr
|
||||
}
|
||||
|
||||
predicate postHasUniquePreExclude(PostUpdateNode n) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
Console.WriteLine(args[0]);
|
||||
Console.WriteLine($"<arguments>{string.Join(",", args)}</arguments>");
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
from create_database_utils import *
|
||||
from diagnostics_test_utils import *
|
||||
|
||||
run_codeql_database_create(['dotnet build'], db=None, lang="csharp")
|
||||
check_diagnostics()
|
||||
def check_build_out(msg, s):
|
||||
if "[build-stdout] " + msg not in s:
|
||||
raise Exception("The C# tracer did not interpret the dotnet path-to-application command correctly.")
|
||||
|
||||
run_codeql_database_create(['dotnet build'], test_db="test1-db", lang="csharp")
|
||||
check_diagnostics(test_db="test1-db")
|
||||
|
||||
# This test checks that we don't inject any flags when running the application using `dotnet`
|
||||
my_dir = "my_program"
|
||||
my_abs_path = os.path.abspath(f"{my_dir}/dotnet_build.dll")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test1-db', 'dotnet build -o my_program', f'dotnet {my_abs_path} build is not a subcommand'], "test2-db", "csharp")
|
||||
check_build_out("<arguments>build,is,not,a,subcommand</arguments>", s)
|
||||
check_diagnostics(test_db="test2-db")
|
||||
|
||||
@@ -1,65 +1,57 @@
|
||||
from create_database_utils import *
|
||||
from diagnostics_test_utils import *
|
||||
|
||||
def run_codeql_database_create_stdout(args, dbname):
|
||||
stdout = open(dbname + "file.txt", 'w+')
|
||||
run_codeql_database_create(args, test_db=dbname, db=None, stdout=stdout, lang="csharp")
|
||||
stdout.seek(0)
|
||||
s = stdout.read()
|
||||
stdout.close()
|
||||
return s
|
||||
|
||||
def check_build_out(msg, s):
|
||||
if "[build-stdout] " + msg not in s:
|
||||
raise Exception("The C# extractor did not interpret the 'dotnet run' command correctly")
|
||||
raise Exception("The C# tracer did not interpret the 'dotnet run' command correctly")
|
||||
|
||||
# no arguments
|
||||
s = run_codeql_database_create_stdout(['dotnet run'], "test-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet run'], "test-db", "csharp")
|
||||
check_build_out("Default reply", s)
|
||||
check_diagnostics()
|
||||
|
||||
# no arguments, but `--`
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test-db', 'dotnet run --'], "test2-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test-db', 'dotnet run --'], "test2-db", "csharp")
|
||||
check_build_out("Default reply", s)
|
||||
check_diagnostics(test_db="test2-db")
|
||||
|
||||
# one argument, no `--`
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test2-db', 'dotnet run hello'], "test3-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test2-db', 'dotnet run hello'], "test3-db", "csharp")
|
||||
check_build_out("Default reply", s)
|
||||
check_diagnostics(test_db="test3-db")
|
||||
|
||||
# one argument, but `--`
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test3-db', 'dotnet run -- hello'], "test4-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test3-db', 'dotnet run -- hello'], "test4-db", "csharp")
|
||||
check_build_out("Default reply", s)
|
||||
check_diagnostics(test_db="test4-db")
|
||||
|
||||
# two arguments, no `--`
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test4-db', 'dotnet run hello world'], "test5-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test4-db', 'dotnet run hello world'], "test5-db", "csharp")
|
||||
check_build_out("hello, world", s)
|
||||
check_diagnostics(test_db="test5-db")
|
||||
|
||||
# two arguments, and `--`
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test5-db', 'dotnet run -- hello world'], "test6-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test5-db', 'dotnet run -- hello world'], "test6-db", "csharp")
|
||||
check_build_out("hello, world", s)
|
||||
check_diagnostics(test_db="test6-db")
|
||||
|
||||
# shared compilation enabled; tracer should override by changing the command
|
||||
# to `dotnet run -p:UseSharedCompilation=true -p:UseSharedCompilation=false -- hello world`
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test6-db', 'dotnet run -p:UseSharedCompilation=true -- hello world'], "test7-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test6-db', 'dotnet run -p:UseSharedCompilation=true -- hello world'], "test7-db", "csharp")
|
||||
check_build_out("hello, world", s)
|
||||
check_diagnostics(test_db="test7-db")
|
||||
|
||||
# option passed into `dotnet run`
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test7-db', 'dotnet build', 'dotnet run --no-build hello world'], "test8-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test7-db', 'dotnet build', 'dotnet run --no-build hello world'], "test8-db", "csharp")
|
||||
check_build_out("hello, world", s)
|
||||
check_diagnostics(test_db="test8-db")
|
||||
|
||||
# two arguments, no '--' (first argument quoted)
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test8-db', 'dotnet run "hello world part1" part2'], "test9-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test8-db', 'dotnet run "hello world part1" part2'], "test9-db", "csharp")
|
||||
check_build_out("hello world part1, part2", s)
|
||||
check_diagnostics(test_db="test9-db")
|
||||
|
||||
# two arguments, no '--' (second argument quoted) and using dotnet to execute dotnet
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test9-db', 'dotnet dotnet run part1 "hello world part2"'], "test10-db")
|
||||
s = run_codeql_database_create_stdout(['dotnet clean', 'rm -rf test9-db', 'dotnet dotnet run part1 "hello world part2"'], "test10-db", "csharp")
|
||||
check_build_out("part1, hello world part2", s)
|
||||
check_diagnostics(test_db="test10-db")
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
| Failed project restore with package source error | 1.0 |
|
||||
| Failed solution restore with package source error | 0.0 |
|
||||
| Fallback nuget restore | 1.0 |
|
||||
| Project files on filesystem | 1.0 |
|
||||
| Resolved assembly conflicts | 7.0 |
|
||||
| Restored .NET framework variants | 0.0 |
|
||||
| Restored projects through solution files | 0.0 |
|
||||
| Solution files on filesystem | 1.0 |
|
||||
| Source files generated | 0.0 |
|
||||
| Source files on filesystem | 1.0 |
|
||||
| Successfully ran fallback nuget restore | 1.0 |
|
||||
| Successfully restored project files | 0.0 |
|
||||
| Successfully restored solution files | 1.0 |
|
||||
| Unresolved references | 0.0 |
|
||||
| UseWPF set | 0.0 |
|
||||
| UseWindowsForms set | 0.0 |
|
||||
| WebView extraction enabled | 1.0 |
|
||||
@@ -0,0 +1,14 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.commons.Diagnostics
|
||||
|
||||
query predicate compilationInfo(string key, float value) {
|
||||
key != "Resolved references" and
|
||||
exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) |
|
||||
key = infoKey and
|
||||
value = infoValue.toFloat()
|
||||
or
|
||||
not exists(infoValue.toFloat()) and
|
||||
key = infoKey + ": " + infoValue and
|
||||
value = 1
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* The QL library C# classes no longer extend their corresponding `DotNet` classes. Furthermore, CIL related data flow functionality has been deleted and all `DotNet` and `CIL` related classes have been deprecated. This effectively means that it no longer has any effect to enable CIL extraction.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The models for `System.IO.TextReader` have been modified to better model the flow of tainted text from a `TextReader`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The .NET standard libraries APIs for accessing command line arguments and environment variables have been modeled using the `commandargs` and `environment` threat models.
|
||||
* The `cs/assembly-path-injection` query has been modified so that it's sources rely on `ThreatModelFlowSource`. In order to restore results from command line arguments, you should enable the `commandargs` threat model.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The models for `System.Net.Http.HttpRequestMessage` have been modified to better model the flow of tainted URIs.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Support for C# 12 / .NET8.
|
||||
@@ -2,4 +2,4 @@
|
||||
* The default QL library for modeling .NET definitions for both C# and CIL code.
|
||||
*/
|
||||
|
||||
import semmle.code.dotnet.DotNet as DotNet
|
||||
deprecated import semmle.code.dotnet.DotNet as DotNet
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["Microsoft.Extensions.Configuration", "EnvironmentVariablesExtensions", False, "AddEnvironmentVariables", "", "", "Argument[0]", "environment", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "EnvironmentVariablesExtensions", False, "AddEnvironmentVariables", "", "", "ReturnValue", "environment", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["Microsoft.Extensions.Configuration", "IConfiguration", True, "get_Item", "(System.String)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "IConfigurationBuilder", True, "Build", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "CommandLineConfigurationExtensions", False, "AddCommandLine", "", "", "Argument[1]", "Argument[0]", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "CommandLineConfigurationExtensions", False, "AddCommandLine", "(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.String[],System.Collections.Generic.IDictionary<System.String,System.String>)", "", "Argument[2]", "Argument[0]", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "CommandLineConfigurationExtensions", False, "AddCommandLine", "", "", "Argument[1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "CommandLineConfigurationExtensions", False, "AddCommandLine", "(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.String[],System.Collections.Generic.IDictionary<System.String,System.String>)", "", "Argument[2]", "ReturnValue", "taint", "manual"]
|
||||
@@ -89,14 +89,16 @@ extensions:
|
||||
- ["System.IO", "StreamReader", False, "StreamReader", "(System.String,System.Text.Encoding,System.Boolean,System.Int32)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["System.IO", "StringReader", False, "StringReader", "(System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "(System.Span<System.Char>)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadAsync", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadAsync", "(System.Memory<System.Char>,System.Threading.CancellationToken)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlock", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlock", "(System.Span<System.Char>)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlockAsync", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlockAsync", "(System.Memory<System.Char>,System.Threading.CancellationToken)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "(System.Span<System.Char>)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadAsync", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
# Post-update nodes for `Memory<T>` are currently unsupported. This model is provided for completeness
|
||||
- ["System.IO", "TextReader", True, "ReadAsync", "(System.Memory<System.Char>,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlock", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlock", "(System.Span<System.Char>)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlockAsync", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
# Post-update nodes for `Memory<T>` are currently unsupported. This model is provided for completeness
|
||||
- ["System.IO", "TextReader", True, "ReadBlockAsync", "(System.Memory<System.Char>,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadLine", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadLineAsync", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadToEnd", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
|
||||
@@ -8,6 +8,8 @@ extensions:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Net.Http", "HttpRequestMessage", False, "HttpRequestMessage", "(System.Net.Http.HttpMethod,System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["System.Net.Http", "HttpRequestMessage", False, "HttpRequestMessage", "(System.Net.Http.HttpMethod,System.String)", "", "Argument[1]", "Argument[this]", "taint", "manual"]
|
||||
- ["System.Net.Http", "HttpRequestOptions", False, "Add", "(System.Collections.Generic.KeyValuePair<System.String,System.Object>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]", "value", "manual"]
|
||||
- ["System.Net.Http", "HttpRequestOptions", False, "Add", "(System.Collections.Generic.KeyValuePair<System.String,System.Object>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"]
|
||||
- ["System.Net.Http", "MultipartContent", False, "Add", "(System.Net.Http.HttpContent)", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
|
||||
|
||||
@@ -6,6 +6,11 @@ extensions:
|
||||
- ["System", "Console", False, "Read", "", "", "ReturnValue", "local", "manual"]
|
||||
- ["System", "Console", False, "ReadKey", "", "", "ReturnValue", "local", "manual"]
|
||||
- ["System", "Console", False, "ReadLine", "", "", "ReturnValue", "local", "manual"]
|
||||
- ["System", "Environment", False, "ExpandEnvironmentVariables", "(System.String)", "", "ReturnValue", "environment", "manual"]
|
||||
- ["System", "Environment", False, "GetCommandLineArgs", "()", "", "ReturnValue", "commandargs", "manual"]
|
||||
- ["System", "Environment", False, "get_CommandLine", "()", "", "ReturnValue", "commandargs", "manual"]
|
||||
- ["System", "Environment", False, "GetEnvironmentVariable", "", "", "ReturnValue", "environment", "manual"]
|
||||
- ["System", "Environment", False, "GetEnvironmentVariables", "", "", "ReturnValue", "environment", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
private import CIL
|
||||
|
||||
/** An instruction that accesses a variable. */
|
||||
class Access extends Instruction, @cil_access {
|
||||
deprecated class Access extends Instruction, @cil_access {
|
||||
/** Gets the declaration referenced by this instruction. */
|
||||
Variable getTarget() { cil_access(this, result) }
|
||||
}
|
||||
@@ -16,59 +16,59 @@ class Access extends Instruction, @cil_access {
|
||||
* An instruction that accesses a variable.
|
||||
* This class is provided for consistency with the C# data model.
|
||||
*/
|
||||
class VariableAccess extends Access, @cil_access { }
|
||||
deprecated class VariableAccess extends Access, @cil_access { }
|
||||
|
||||
/** An instruction that reads a variable. */
|
||||
class ReadAccess extends VariableAccess, Expr, @cil_read_access {
|
||||
deprecated class ReadAccess extends VariableAccess, Expr, @cil_read_access {
|
||||
override Type getType() { result = this.getTarget().getType() }
|
||||
}
|
||||
|
||||
/** An instruction yielding an address. */
|
||||
class ReadRef extends Expr, @cil_read_ref { }
|
||||
deprecated class ReadRef extends Expr, @cil_read_ref { }
|
||||
|
||||
/** An instruction that reads the address of a variable. */
|
||||
class ReadRefAccess extends ReadAccess, ReadRef { }
|
||||
deprecated class ReadRefAccess extends ReadAccess, ReadRef { }
|
||||
|
||||
/** An instruction that writes a variable. */
|
||||
class WriteAccess extends VariableAccess, @cil_write_access {
|
||||
deprecated class WriteAccess extends VariableAccess, @cil_write_access {
|
||||
/** Gets the expression whose value is used in this variable write. */
|
||||
Expr getExpr() { none() }
|
||||
}
|
||||
|
||||
/** An instruction that accesses a parameter. */
|
||||
class ParameterAccess extends StackVariableAccess, @cil_arg_access {
|
||||
deprecated class ParameterAccess extends StackVariableAccess, @cil_arg_access {
|
||||
override MethodParameter getTarget() { result = StackVariableAccess.super.getTarget() }
|
||||
}
|
||||
|
||||
/** An instruction that reads a parameter. */
|
||||
class ParameterReadAccess extends ParameterAccess, ReadAccess {
|
||||
deprecated class ParameterReadAccess extends ParameterAccess, ReadAccess {
|
||||
override int getPopCount() { result = 0 }
|
||||
}
|
||||
|
||||
/** An instruction that writes to a parameter. */
|
||||
class ParameterWriteAccess extends ParameterAccess, WriteAccess {
|
||||
deprecated class ParameterWriteAccess extends ParameterAccess, WriteAccess {
|
||||
override int getPopCount() { result = 1 }
|
||||
|
||||
override Expr getExpr() { result = this.getOperand(0) }
|
||||
}
|
||||
|
||||
/** An access to the `this` parameter. */
|
||||
class ThisAccess extends ParameterReadAccess {
|
||||
deprecated class ThisAccess extends ParameterReadAccess {
|
||||
ThisAccess() { this.getTarget() instanceof ThisParameter }
|
||||
}
|
||||
|
||||
/** An instruction that accesses a stack variable. */
|
||||
class StackVariableAccess extends VariableAccess, @cil_stack_access {
|
||||
deprecated class StackVariableAccess extends VariableAccess, @cil_stack_access {
|
||||
override StackVariable getTarget() { result = VariableAccess.super.getTarget() }
|
||||
}
|
||||
|
||||
/** An instruction that accesses a local variable. */
|
||||
class LocalVariableAccess extends StackVariableAccess, @cil_local_access {
|
||||
deprecated class LocalVariableAccess extends StackVariableAccess, @cil_local_access {
|
||||
override LocalVariable getTarget() { result = StackVariableAccess.super.getTarget() }
|
||||
}
|
||||
|
||||
/** An instruction that writes to a local variable. */
|
||||
class LocalVariableWriteAccess extends LocalVariableAccess, WriteAccess {
|
||||
deprecated class LocalVariableWriteAccess extends LocalVariableAccess, WriteAccess {
|
||||
override int getPopCount() { result = 1 }
|
||||
|
||||
override Expr getExpr() { result = this.getOperand(0) }
|
||||
@@ -77,12 +77,12 @@ class LocalVariableWriteAccess extends LocalVariableAccess, WriteAccess {
|
||||
}
|
||||
|
||||
/** An instruction that reads a local variable. */
|
||||
class LocalVariableReadAccess extends LocalVariableAccess, ReadAccess {
|
||||
deprecated class LocalVariableReadAccess extends LocalVariableAccess, ReadAccess {
|
||||
override int getPopCount() { result = 0 }
|
||||
}
|
||||
|
||||
/** An instruction that accesses a field. */
|
||||
class FieldAccess extends VariableAccess, @cil_field_access {
|
||||
deprecated class FieldAccess extends VariableAccess, @cil_field_access {
|
||||
override Field getTarget() { result = VariableAccess.super.getTarget() }
|
||||
|
||||
override string getExtra() { result = this.getTarget().getName() }
|
||||
@@ -92,7 +92,7 @@ class FieldAccess extends VariableAccess, @cil_field_access {
|
||||
}
|
||||
|
||||
/** An instruction that reads a field. */
|
||||
abstract class FieldReadAccess extends FieldAccess, ReadAccess { }
|
||||
abstract deprecated class FieldReadAccess extends FieldAccess, ReadAccess { }
|
||||
|
||||
/** An instruction that writes a field. */
|
||||
abstract class FieldWriteAccess extends FieldAccess, WriteAccess { }
|
||||
abstract deprecated class FieldWriteAccess extends FieldAccess, WriteAccess { }
|
||||
|
||||
@@ -4,7 +4,7 @@ private import CIL
|
||||
private import semmle.code.csharp.Location as CS
|
||||
|
||||
/** An attribute to a declaration, such as a method, field, type or parameter. */
|
||||
class Attribute extends Element, @cil_attribute {
|
||||
deprecated class Attribute extends Element, @cil_attribute {
|
||||
/** Gets the declaration this attribute is attached to. */
|
||||
Declaration getDeclaration() { cil_attribute(this, result, _) }
|
||||
|
||||
@@ -29,7 +29,7 @@ class Attribute extends Element, @cil_attribute {
|
||||
}
|
||||
|
||||
/** A generic attribute to a declaration. */
|
||||
class GenericAttribute extends Attribute {
|
||||
deprecated class GenericAttribute extends Attribute {
|
||||
private ConstructedType type;
|
||||
|
||||
GenericAttribute() { type = this.getType() }
|
||||
|
||||
@@ -8,7 +8,7 @@ private import CIL
|
||||
* A basic block, that is, a maximal straight-line sequence of control flow nodes
|
||||
* without branches or joins.
|
||||
*/
|
||||
class BasicBlock extends Cached::TBasicBlockStart {
|
||||
deprecated class BasicBlock extends Cached::TBasicBlockStart {
|
||||
/** Gets an immediate successor of this basic block, if any. */
|
||||
BasicBlock getASuccessor() { result.getFirstNode() = this.getLastNode().getASuccessor() }
|
||||
|
||||
@@ -249,7 +249,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
|
||||
* Internal implementation details.
|
||||
*/
|
||||
cached
|
||||
private module Cached {
|
||||
deprecated private module Cached {
|
||||
/** Internal representation of basic blocks. */
|
||||
cached
|
||||
newtype TBasicBlock = TBasicBlockStart(ControlFlowNode cfn) { startsBB(cfn) }
|
||||
@@ -287,49 +287,54 @@ private module Cached {
|
||||
* Holds if the first node of basic block `succ` is a control flow
|
||||
* successor of the last node of basic block `pred`.
|
||||
*/
|
||||
private predicate succBB(BasicBlock pred, BasicBlock succ) { succ = pred.getASuccessor() }
|
||||
deprecated private predicate succBB(BasicBlock pred, BasicBlock succ) {
|
||||
succ = pred.getASuccessor()
|
||||
}
|
||||
|
||||
/** Holds if `dom` is an immediate dominator of `bb`. */
|
||||
predicate bbIDominates(BasicBlock dom, BasicBlock bb) = idominance(entryBB/1, succBB/2)(_, dom, bb)
|
||||
deprecated predicate bbIDominates(BasicBlock dom, BasicBlock bb) =
|
||||
idominance(entryBB/1, succBB/2)(_, dom, bb)
|
||||
|
||||
/** Holds if `pred` is a basic block predecessor of `succ`. */
|
||||
private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) }
|
||||
deprecated private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) }
|
||||
|
||||
/** Holds if `dom` is an immediate post-dominator of `bb`. */
|
||||
predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) =
|
||||
deprecated predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) =
|
||||
idominance(exitBB/1, predBB/2)(_, dom, bb)
|
||||
|
||||
/**
|
||||
* An entry basic block, that is, a basic block whose first node is
|
||||
* the entry node of a callable.
|
||||
*/
|
||||
class EntryBasicBlock extends BasicBlock {
|
||||
deprecated class EntryBasicBlock extends BasicBlock {
|
||||
EntryBasicBlock() { entryBB(this) }
|
||||
}
|
||||
|
||||
/** Holds if `bb` is an entry basic block. */
|
||||
private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof MethodImplementation }
|
||||
deprecated private predicate entryBB(BasicBlock bb) {
|
||||
bb.getFirstNode() instanceof MethodImplementation
|
||||
}
|
||||
|
||||
/**
|
||||
* An exit basic block, that is, a basic block whose last node is
|
||||
* an exit node.
|
||||
*/
|
||||
class ExitBasicBlock extends BasicBlock {
|
||||
deprecated class ExitBasicBlock extends BasicBlock {
|
||||
ExitBasicBlock() { exitBB(this) }
|
||||
}
|
||||
|
||||
/** Holds if `bb` is an exit basic block. */
|
||||
private predicate exitBB(BasicBlock bb) { not exists(bb.getLastNode().getASuccessor()) }
|
||||
deprecated private predicate exitBB(BasicBlock bb) { not exists(bb.getLastNode().getASuccessor()) }
|
||||
|
||||
/**
|
||||
* A basic block with more than one predecessor.
|
||||
*/
|
||||
class JoinBlock extends BasicBlock {
|
||||
deprecated class JoinBlock extends BasicBlock {
|
||||
JoinBlock() { this.getFirstNode().isJoin() }
|
||||
}
|
||||
|
||||
/** A basic block that terminates in a condition, splitting the subsequent control flow. */
|
||||
class ConditionBlock extends BasicBlock {
|
||||
deprecated class ConditionBlock extends BasicBlock {
|
||||
ConditionBlock() {
|
||||
exists(BasicBlock succ |
|
||||
succ = this.getATrueSuccessor()
|
||||
|
||||
@@ -8,22 +8,26 @@ cached
|
||||
private module Cached {
|
||||
/** Holds if method `m` always returns null. */
|
||||
cached
|
||||
predicate alwaysNullMethod(Method m) { forex(Expr e | m.canReturn(e) | alwaysNullExpr(e)) }
|
||||
deprecated predicate alwaysNullMethod(Method m) {
|
||||
forex(Expr e | m.canReturn(e) | alwaysNullExpr(e))
|
||||
}
|
||||
|
||||
/** Holds if method `m` always returns non-null. */
|
||||
cached
|
||||
predicate alwaysNotNullMethod(Method m) { forex(Expr e | m.canReturn(e) | alwaysNotNullExpr(e)) }
|
||||
deprecated predicate alwaysNotNullMethod(Method m) {
|
||||
forex(Expr e | m.canReturn(e) | alwaysNotNullExpr(e))
|
||||
}
|
||||
|
||||
/** Holds if method `m` always throws an exception. */
|
||||
cached
|
||||
predicate alwaysThrowsMethod(Method m) {
|
||||
deprecated predicate alwaysThrowsMethod(Method m) {
|
||||
m.hasBody() and
|
||||
not exists(m.getImplementation().getAnInstruction().(Return))
|
||||
}
|
||||
|
||||
/** Holds if method `m` always throws an exception of type `t`. */
|
||||
cached
|
||||
predicate alwaysThrowsException(Method m, Type t) {
|
||||
deprecated predicate alwaysThrowsException(Method m, Type t) {
|
||||
alwaysThrowsMethod(m) and
|
||||
forex(Throw ex | ex = m.getImplementation().getAnInstruction() | t = ex.getExceptionType())
|
||||
}
|
||||
@@ -32,12 +36,12 @@ private module Cached {
|
||||
import Cached
|
||||
|
||||
pragma[noinline]
|
||||
private predicate alwaysNullVariableUpdate(VariableUpdate vu) {
|
||||
deprecated private predicate alwaysNullVariableUpdate(VariableUpdate vu) {
|
||||
forex(Expr src | src = vu.getSource() | alwaysNullExpr(src))
|
||||
}
|
||||
|
||||
/** Holds if expression `expr` always evaluates to `null`. */
|
||||
private predicate alwaysNullExpr(Expr expr) {
|
||||
deprecated private predicate alwaysNullExpr(Expr expr) {
|
||||
expr instanceof NullLiteral
|
||||
or
|
||||
alwaysNullMethod(expr.(StaticCall).getTarget())
|
||||
@@ -50,12 +54,12 @@ private predicate alwaysNullExpr(Expr expr) {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate alwaysNotNullVariableUpdate(VariableUpdate vu) {
|
||||
deprecated private predicate alwaysNotNullVariableUpdate(VariableUpdate vu) {
|
||||
forex(Expr src | src = vu.getSource() | alwaysNotNullExpr(src))
|
||||
}
|
||||
|
||||
/** Holds if expression `expr` always evaluates to non-null. */
|
||||
private predicate alwaysNotNullExpr(Expr expr) {
|
||||
deprecated private predicate alwaysNotNullExpr(Expr expr) {
|
||||
expr instanceof Opcodes::NewObj
|
||||
or
|
||||
expr instanceof Literal and not expr instanceof NullLiteral
|
||||
|
||||
@@ -8,15 +8,15 @@ private import semmle.code.csharp.commons.QualifiedName
|
||||
|
||||
private newtype ConsistencyCheck =
|
||||
MissingEntityCheck() or
|
||||
TypeCheck(Type t) or
|
||||
CfgCheck(ControlFlowNode n) or
|
||||
DeclarationCheck(Declaration d) or
|
||||
deprecated TypeCheck(Type t) or
|
||||
deprecated CfgCheck(ControlFlowNode n) or
|
||||
deprecated DeclarationCheck(Declaration d) or
|
||||
MissingCSharpCheck(CS::Declaration d)
|
||||
|
||||
/**
|
||||
* A consistency violation in the database or data model.
|
||||
*/
|
||||
abstract class ConsistencyViolation extends ConsistencyCheck {
|
||||
abstract deprecated class ConsistencyViolation extends ConsistencyCheck {
|
||||
abstract string toString();
|
||||
|
||||
abstract string getMessage();
|
||||
@@ -25,14 +25,14 @@ abstract class ConsistencyViolation extends ConsistencyCheck {
|
||||
/**
|
||||
* A check that is deliberately disabled.
|
||||
*/
|
||||
abstract class DisabledCheck extends ConsistencyViolation {
|
||||
abstract deprecated class DisabledCheck extends ConsistencyViolation {
|
||||
DisabledCheck() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A consistency violation on a control flow node.
|
||||
*/
|
||||
abstract class CfgViolation extends ConsistencyViolation, CfgCheck {
|
||||
abstract deprecated class CfgViolation extends ConsistencyViolation, CfgCheck {
|
||||
ControlFlowNode node;
|
||||
|
||||
CfgViolation() { this = CfgCheck(node) }
|
||||
@@ -43,7 +43,7 @@ abstract class CfgViolation extends ConsistencyViolation, CfgCheck {
|
||||
/**
|
||||
* A consistency violation in a specific instruction.
|
||||
*/
|
||||
abstract class InstructionViolation extends CfgViolation, CfgCheck {
|
||||
abstract deprecated class InstructionViolation extends CfgViolation, CfgCheck {
|
||||
Instruction instruction;
|
||||
|
||||
InstructionViolation() { this = CfgCheck(instruction) }
|
||||
@@ -70,7 +70,7 @@ abstract class InstructionViolation extends CfgViolation, CfgCheck {
|
||||
/**
|
||||
* A literal that does not have exactly one `getValue()`.
|
||||
*/
|
||||
class MissingValue extends InstructionViolation {
|
||||
deprecated class MissingValue extends InstructionViolation {
|
||||
MissingValue() { exists(Literal l | l = instruction | count(l.getValue()) != 1) }
|
||||
|
||||
override string getMessage() { result = "Literal has invalid getValue()" }
|
||||
@@ -79,7 +79,7 @@ class MissingValue extends InstructionViolation {
|
||||
/**
|
||||
* A call that does not have exactly one `getTarget()`.
|
||||
*/
|
||||
class MissingCallTarget extends InstructionViolation {
|
||||
deprecated class MissingCallTarget extends InstructionViolation {
|
||||
MissingCallTarget() {
|
||||
exists(Call c | c = instruction |
|
||||
count(c.getTarget()) != 1 and not c instanceof Opcodes::Calli
|
||||
@@ -94,7 +94,7 @@ class MissingCallTarget extends InstructionViolation {
|
||||
/**
|
||||
* An instruction that has not been assigned a specific QL class.
|
||||
*/
|
||||
class MissingOpCode extends InstructionViolation {
|
||||
deprecated class MissingOpCode extends InstructionViolation {
|
||||
MissingOpCode() { not exists(instruction.getOpcodeName()) }
|
||||
|
||||
override string getMessage() {
|
||||
@@ -114,7 +114,7 @@ class MissingOpCode extends InstructionViolation {
|
||||
* It could also mean that the target of a call has failed and has not determined the
|
||||
* correct number of arguments.
|
||||
*/
|
||||
class MissingOperand extends InstructionViolation {
|
||||
deprecated class MissingOperand extends InstructionViolation {
|
||||
MissingOperand() {
|
||||
exists(int op | op in [0 .. instruction.getPopCount() - 1] |
|
||||
not exists(instruction.getOperand(op)) and not instruction instanceof DeadInstruction
|
||||
@@ -136,7 +136,7 @@ class MissingOperand extends InstructionViolation {
|
||||
* These should not exist, however it turns out that the Mono compiler sometimes
|
||||
* emits them.
|
||||
*/
|
||||
class DeadInstruction extends Instruction {
|
||||
deprecated class DeadInstruction extends Instruction {
|
||||
DeadInstruction() { not exists(EntryPoint e | e.getASuccessor+() = this) }
|
||||
}
|
||||
|
||||
@@ -146,20 +146,20 @@ class DeadInstruction extends Instruction {
|
||||
* If this fails, it means that the calculation of the call graph is incorrect.
|
||||
* Disabled, because Mono compiler sometimes emits dead instructions.
|
||||
*/
|
||||
class DeadInstructionViolation extends InstructionViolation, DisabledCheck {
|
||||
deprecated class DeadInstructionViolation extends InstructionViolation, DisabledCheck {
|
||||
DeadInstructionViolation() { instruction instanceof DeadInstruction }
|
||||
|
||||
override string getMessage() { result = "This instruction is not reachable" }
|
||||
}
|
||||
|
||||
class YesNoBranch extends ConditionalBranch {
|
||||
deprecated class YesNoBranch extends ConditionalBranch {
|
||||
YesNoBranch() { not this instanceof Opcodes::Switch }
|
||||
}
|
||||
|
||||
/**
|
||||
* A branch instruction that does not have exactly 2 successors.
|
||||
*/
|
||||
class InvalidBranchSuccessors extends InstructionViolation {
|
||||
deprecated class InvalidBranchSuccessors extends InstructionViolation {
|
||||
InvalidBranchSuccessors() {
|
||||
// Mono compiler sometimes generates branches to the next instruction, which is just wrong.
|
||||
// However it is valid CIL.
|
||||
@@ -174,7 +174,7 @@ class InvalidBranchSuccessors extends InstructionViolation {
|
||||
/**
|
||||
* An instruction that has a true/false successor but is not a branch.
|
||||
*/
|
||||
class OnlyYesNoBranchHasTrueFalseSuccessors extends InstructionViolation {
|
||||
deprecated class OnlyYesNoBranchHasTrueFalseSuccessors extends InstructionViolation {
|
||||
OnlyYesNoBranchHasTrueFalseSuccessors() {
|
||||
(exists(instruction.getTrueSuccessor()) or exists(instruction.getFalseSuccessor())) and
|
||||
not instruction instanceof YesNoBranch
|
||||
@@ -186,7 +186,7 @@ class OnlyYesNoBranchHasTrueFalseSuccessors extends InstructionViolation {
|
||||
/**
|
||||
* An unconditional branch instruction that has more than one successor.
|
||||
*/
|
||||
class UnconditionalBranchSuccessors extends InstructionViolation {
|
||||
deprecated class UnconditionalBranchSuccessors extends InstructionViolation {
|
||||
UnconditionalBranchSuccessors() {
|
||||
exists(UnconditionalBranch i | i = instruction | count(i.getASuccessor()) != 1)
|
||||
}
|
||||
@@ -199,7 +199,7 @@ class UnconditionalBranchSuccessors extends InstructionViolation {
|
||||
/**
|
||||
* A branch instruction that does not have a true successor.
|
||||
*/
|
||||
class NoTrueSuccessor extends InstructionViolation {
|
||||
deprecated class NoTrueSuccessor extends InstructionViolation {
|
||||
NoTrueSuccessor() { exists(YesNoBranch i | i = instruction | not exists(i.getTrueSuccessor())) }
|
||||
|
||||
override string getMessage() { result = "Missing a true successor" }
|
||||
@@ -208,7 +208,7 @@ class NoTrueSuccessor extends InstructionViolation {
|
||||
/**
|
||||
* A branch instruction that does not have a false successor.
|
||||
*/
|
||||
class NoFalseSuccessor extends InstructionViolation {
|
||||
deprecated class NoFalseSuccessor extends InstructionViolation {
|
||||
NoFalseSuccessor() { exists(YesNoBranch i | i = instruction | not exists(i.getFalseSuccessor())) }
|
||||
|
||||
override string getMessage() { result = "Missing a false successor" }
|
||||
@@ -217,7 +217,7 @@ class NoFalseSuccessor extends InstructionViolation {
|
||||
/**
|
||||
* An instruction whose true successor is not a successor.
|
||||
*/
|
||||
class TrueSuccessorIsSuccessor extends InstructionViolation {
|
||||
deprecated class TrueSuccessorIsSuccessor extends InstructionViolation {
|
||||
TrueSuccessorIsSuccessor() {
|
||||
exists(instruction.getTrueSuccessor()) and
|
||||
not instruction.getTrueSuccessor() = instruction.getASuccessor()
|
||||
@@ -229,7 +229,7 @@ class TrueSuccessorIsSuccessor extends InstructionViolation {
|
||||
/**
|
||||
* An instruction whose false successor is not a successor.
|
||||
*/
|
||||
class FalseSuccessorIsSuccessor extends InstructionViolation {
|
||||
deprecated class FalseSuccessorIsSuccessor extends InstructionViolation {
|
||||
FalseSuccessorIsSuccessor() {
|
||||
exists(instruction.getFalseSuccessor()) and
|
||||
not instruction.getFalseSuccessor() = instruction.getASuccessor()
|
||||
@@ -241,7 +241,7 @@ class FalseSuccessorIsSuccessor extends InstructionViolation {
|
||||
/**
|
||||
* An access that does not have exactly one target.
|
||||
*/
|
||||
class AccessMissingTarget extends InstructionViolation {
|
||||
deprecated class AccessMissingTarget extends InstructionViolation {
|
||||
AccessMissingTarget() { exists(Access i | i = instruction | count(i.getTarget()) != 1) }
|
||||
|
||||
override string getMessage() { result = "Access has invalid getTarget()" }
|
||||
@@ -250,7 +250,7 @@ class AccessMissingTarget extends InstructionViolation {
|
||||
/**
|
||||
* A catch handler that doesn't have a caught exception type.
|
||||
*/
|
||||
class CatchHandlerMissingType extends CfgViolation {
|
||||
deprecated class CatchHandlerMissingType extends CfgViolation {
|
||||
CatchHandlerMissingType() { exists(CatchHandler h | h = node | not exists(h.getCaughtType())) }
|
||||
|
||||
override string getMessage() { result = "Catch handler missing caught type" }
|
||||
@@ -259,7 +259,7 @@ class CatchHandlerMissingType extends CfgViolation {
|
||||
/**
|
||||
* A CFG node that does not have a stack size.
|
||||
*/
|
||||
class MissingStackSize extends CfgViolation {
|
||||
deprecated class MissingStackSize extends CfgViolation {
|
||||
MissingStackSize() {
|
||||
(
|
||||
not exists(node.getStackSizeAfter()) or
|
||||
@@ -275,7 +275,7 @@ class MissingStackSize extends CfgViolation {
|
||||
* A CFG node that does not have exactly one stack size.
|
||||
* Disabled because inconsistent stack sizes have been observed.
|
||||
*/
|
||||
class InvalidStackSize extends CfgViolation, DisabledCheck {
|
||||
deprecated class InvalidStackSize extends CfgViolation, DisabledCheck {
|
||||
InvalidStackSize() {
|
||||
(
|
||||
count(node.getStackSizeAfter()) != 1 or
|
||||
@@ -294,7 +294,7 @@ class InvalidStackSize extends CfgViolation, DisabledCheck {
|
||||
/**
|
||||
* A CFG node that does not have exactly 1 `getPopCount()`.
|
||||
*/
|
||||
class InconsistentPopCount extends CfgViolation {
|
||||
deprecated class InconsistentPopCount extends CfgViolation {
|
||||
InconsistentPopCount() { count(node.getPopCount()) != 1 }
|
||||
|
||||
override string getMessage() {
|
||||
@@ -305,7 +305,7 @@ class InconsistentPopCount extends CfgViolation {
|
||||
/**
|
||||
* A CFG node that does not have exactly one `getPushCount()`.
|
||||
*/
|
||||
class InconsistentPushCount extends CfgViolation {
|
||||
deprecated class InconsistentPushCount extends CfgViolation {
|
||||
InconsistentPushCount() { count(node.getPushCount()) != 1 }
|
||||
|
||||
override string getMessage() {
|
||||
@@ -316,7 +316,7 @@ class InconsistentPushCount extends CfgViolation {
|
||||
/**
|
||||
* A return instruction that does not have a stack size of 0 after it.
|
||||
*/
|
||||
class InvalidReturn extends InstructionViolation {
|
||||
deprecated class InvalidReturn extends InstructionViolation {
|
||||
InvalidReturn() { instruction instanceof Return and instruction.getStackSizeAfter() != 0 }
|
||||
|
||||
override string getMessage() { result = "Return has invalid stack size" }
|
||||
@@ -325,7 +325,7 @@ class InvalidReturn extends InstructionViolation {
|
||||
/**
|
||||
* A throw instruction that does not have a stack size of 0 after it.
|
||||
*/
|
||||
class InvalidThrow extends InstructionViolation, DisabledCheck {
|
||||
deprecated class InvalidThrow extends InstructionViolation, DisabledCheck {
|
||||
InvalidThrow() { instruction instanceof Throw and instruction.getStackSizeAfter() != 0 }
|
||||
|
||||
override string getMessage() {
|
||||
@@ -336,7 +336,7 @@ class InvalidThrow extends InstructionViolation, DisabledCheck {
|
||||
/**
|
||||
* A field access where the field is "static" but the instruction is "instance".
|
||||
*/
|
||||
class StaticFieldTarget extends InstructionViolation {
|
||||
deprecated class StaticFieldTarget extends InstructionViolation {
|
||||
StaticFieldTarget() {
|
||||
exists(FieldAccess i | i = instruction |
|
||||
(i instanceof Opcodes::Stfld or i instanceof Opcodes::Stfld) and
|
||||
@@ -350,7 +350,7 @@ class StaticFieldTarget extends InstructionViolation {
|
||||
/**
|
||||
* A branch without a target.
|
||||
*/
|
||||
class BranchWithoutTarget extends InstructionViolation {
|
||||
deprecated class BranchWithoutTarget extends InstructionViolation {
|
||||
BranchWithoutTarget() {
|
||||
instruction = any(Branch b | not exists(b.getTarget()) and not b instanceof Opcodes::Switch)
|
||||
}
|
||||
@@ -361,7 +361,7 @@ class BranchWithoutTarget extends InstructionViolation {
|
||||
/**
|
||||
* A consistency violation in a type.
|
||||
*/
|
||||
class TypeViolation extends ConsistencyViolation, TypeCheck {
|
||||
deprecated class TypeViolation extends ConsistencyViolation, TypeCheck {
|
||||
/** Gets the type containing the violation. */
|
||||
Type getType() { this = TypeCheck(result) }
|
||||
|
||||
@@ -373,7 +373,7 @@ class TypeViolation extends ConsistencyViolation, TypeCheck {
|
||||
/**
|
||||
* A type that has both type arguments and type parameters.
|
||||
*/
|
||||
class TypeIsBothConstructedAndUnbound extends TypeViolation {
|
||||
deprecated class TypeIsBothConstructedAndUnbound extends TypeViolation {
|
||||
TypeIsBothConstructedAndUnbound() {
|
||||
this.getType() instanceof ConstructedGeneric and this.getType() instanceof UnboundGeneric
|
||||
}
|
||||
@@ -385,7 +385,7 @@ class TypeIsBothConstructedAndUnbound extends TypeViolation {
|
||||
* The location of a constructed generic type should be the same
|
||||
* as the location of its unbound generic type.
|
||||
*/
|
||||
class InconsistentTypeLocation extends TypeViolation {
|
||||
deprecated class InconsistentTypeLocation extends TypeViolation {
|
||||
InconsistentTypeLocation() {
|
||||
this.getType().getLocation() != this.getType().getUnboundDeclaration().getLocation()
|
||||
}
|
||||
@@ -396,7 +396,7 @@ class InconsistentTypeLocation extends TypeViolation {
|
||||
/**
|
||||
* A constructed type that does not match its unbound generic type.
|
||||
*/
|
||||
class TypeParameterMismatch extends TypeViolation {
|
||||
deprecated class TypeParameterMismatch extends TypeViolation {
|
||||
TypeParameterMismatch() {
|
||||
this.getType().(ConstructedGeneric).getNumberOfTypeArguments() !=
|
||||
this.getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters()
|
||||
@@ -415,7 +415,7 @@ class TypeParameterMismatch extends TypeViolation {
|
||||
/**
|
||||
* A consistency violation in a method.
|
||||
*/
|
||||
class MethodViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
deprecated class MethodViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
/** Gets the method containing the violation. */
|
||||
Method getMethod() { this = DeclarationCheck(result) }
|
||||
|
||||
@@ -428,7 +428,7 @@ class MethodViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
* The location of a constructed method should be equal to the
|
||||
* location of its unbound generic.
|
||||
*/
|
||||
class InconsistentMethodLocation extends MethodViolation {
|
||||
deprecated class InconsistentMethodLocation extends MethodViolation {
|
||||
InconsistentMethodLocation() {
|
||||
this.getMethod().getLocation() != this.getMethod().getUnboundDeclaration().getLocation()
|
||||
}
|
||||
@@ -439,7 +439,7 @@ class InconsistentMethodLocation extends MethodViolation {
|
||||
/**
|
||||
* A constructed method that does not match its unbound method.
|
||||
*/
|
||||
class ConstructedMethodTypeParams extends MethodViolation {
|
||||
deprecated class ConstructedMethodTypeParams extends MethodViolation {
|
||||
ConstructedMethodTypeParams() {
|
||||
this.getMethod().(ConstructedGeneric).getNumberOfTypeArguments() !=
|
||||
this.getMethod().getUnboundDeclaration().(UnboundGeneric).getNumberOfTypeParameters()
|
||||
@@ -456,14 +456,14 @@ class ConstructedMethodTypeParams extends MethodViolation {
|
||||
/**
|
||||
* A violation marking an entity that should be present but is not.
|
||||
*/
|
||||
abstract class MissingEntityViolation extends ConsistencyViolation, MissingEntityCheck {
|
||||
abstract deprecated class MissingEntityViolation extends ConsistencyViolation, MissingEntityCheck {
|
||||
override string toString() { result = "Missing entity" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The type `object` is missing from the database.
|
||||
*/
|
||||
class MissingObjectViolation extends MissingEntityViolation {
|
||||
deprecated class MissingObjectViolation extends MissingEntityViolation {
|
||||
MissingObjectViolation() {
|
||||
exists(this) and
|
||||
not exists(ObjectType o)
|
||||
@@ -475,7 +475,7 @@ class MissingObjectViolation extends MissingEntityViolation {
|
||||
/**
|
||||
* An override that is invalid because the overridden method is not in a base class.
|
||||
*/
|
||||
class InvalidOverride extends MethodViolation {
|
||||
deprecated class InvalidOverride extends MethodViolation {
|
||||
private Method base;
|
||||
|
||||
InvalidOverride() {
|
||||
@@ -497,7 +497,7 @@ class InvalidOverride extends MethodViolation {
|
||||
/**
|
||||
* A pointer type that does not have a pointee type.
|
||||
*/
|
||||
class InvalidPointerType extends TypeViolation {
|
||||
deprecated class InvalidPointerType extends TypeViolation {
|
||||
InvalidPointerType() {
|
||||
exists(PointerType p | p = this.getType() | count(p.getReferentType()) != 1)
|
||||
}
|
||||
@@ -508,7 +508,7 @@ class InvalidPointerType extends TypeViolation {
|
||||
/**
|
||||
* An array with an invalid `getElementType`.
|
||||
*/
|
||||
class ArrayTypeMissingElement extends TypeViolation {
|
||||
deprecated class ArrayTypeMissingElement extends TypeViolation {
|
||||
ArrayTypeMissingElement() {
|
||||
exists(ArrayType t | t = this.getType() | count(t.getElementType()) != 1)
|
||||
}
|
||||
@@ -519,7 +519,7 @@ class ArrayTypeMissingElement extends TypeViolation {
|
||||
/**
|
||||
* An array with an invalid `getRank`.
|
||||
*/
|
||||
class ArrayTypeInvalidRank extends TypeViolation {
|
||||
deprecated class ArrayTypeInvalidRank extends TypeViolation {
|
||||
ArrayTypeInvalidRank() { exists(ArrayType t | t = this.getType() | not t.getRank() > 0) }
|
||||
|
||||
override string getMessage() { result = "Invalid ArrayType.getRank()" }
|
||||
@@ -529,7 +529,7 @@ class ArrayTypeInvalidRank extends TypeViolation {
|
||||
* A type should have at most one kind, except for missing referenced types
|
||||
* where the interface/class is unknown.
|
||||
*/
|
||||
class KindViolation extends TypeViolation {
|
||||
deprecated class KindViolation extends TypeViolation {
|
||||
KindViolation() {
|
||||
count(typeKind(this.getType())) != 1 and
|
||||
exists(this.getType().getLocation())
|
||||
@@ -544,7 +544,7 @@ class KindViolation extends TypeViolation {
|
||||
* The type of a kind must be consistent between a constructed generic and its
|
||||
* unbound generic.
|
||||
*/
|
||||
class InconsistentKind extends TypeViolation {
|
||||
deprecated class InconsistentKind extends TypeViolation {
|
||||
InconsistentKind() {
|
||||
typeKind(this.getType()) != typeKind(this.getType().getUnboundDeclaration())
|
||||
}
|
||||
@@ -552,7 +552,7 @@ class InconsistentKind extends TypeViolation {
|
||||
override string getMessage() { result = "Inconsistent type kind of source declaration" }
|
||||
}
|
||||
|
||||
private string typeKind(Type t) {
|
||||
deprecated private string typeKind(Type t) {
|
||||
t instanceof Interface and result = "interface"
|
||||
or
|
||||
t instanceof Class and result = "class"
|
||||
@@ -567,7 +567,7 @@ private string typeKind(Type t) {
|
||||
/**
|
||||
* A violation in a `Member`.
|
||||
*/
|
||||
abstract class DeclarationViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
abstract deprecated class DeclarationViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
abstract override string getMessage();
|
||||
|
||||
/** Gets the member containing the potential violation. */
|
||||
@@ -579,7 +579,7 @@ abstract class DeclarationViolation extends ConsistencyViolation, DeclarationChe
|
||||
/**
|
||||
* Properties that have no accessors.
|
||||
*/
|
||||
class PropertyWithNoAccessors extends DeclarationViolation {
|
||||
deprecated class PropertyWithNoAccessors extends DeclarationViolation {
|
||||
PropertyWithNoAccessors() {
|
||||
exists(Property p | p = this.getDeclaration() | not exists(p.getAnAccessor()))
|
||||
}
|
||||
@@ -590,7 +590,7 @@ class PropertyWithNoAccessors extends DeclarationViolation {
|
||||
/**
|
||||
* An expression that have an unexpected push count.
|
||||
*/
|
||||
class ExprPushCount extends InstructionViolation {
|
||||
deprecated class ExprPushCount extends InstructionViolation {
|
||||
ExprPushCount() {
|
||||
instruction instanceof Expr and
|
||||
not instruction instanceof Opcodes::Dup and
|
||||
@@ -608,7 +608,7 @@ class ExprPushCount extends InstructionViolation {
|
||||
* An expression that does not have exactly one type.
|
||||
* Note that calls with no return have type `System.Void`.
|
||||
*/
|
||||
class ExprMissingType extends InstructionViolation {
|
||||
deprecated class ExprMissingType extends InstructionViolation {
|
||||
ExprMissingType() {
|
||||
// Don't have types for the following op codes:
|
||||
not instruction instanceof Opcodes::Ldftn and
|
||||
@@ -632,7 +632,7 @@ class ExprMissingType extends InstructionViolation {
|
||||
/**
|
||||
* An instruction that has a push count of 0, yet is still used as an operand
|
||||
*/
|
||||
class InvalidExpressionViolation extends InstructionViolation {
|
||||
deprecated class InvalidExpressionViolation extends InstructionViolation {
|
||||
InvalidExpressionViolation() {
|
||||
instruction.getPushCount() = 0 and
|
||||
exists(Instruction expr | instruction = expr.getAnOperand())
|
||||
@@ -647,7 +647,7 @@ class InvalidExpressionViolation extends InstructionViolation {
|
||||
* A type that has multiple entities with the same qualified name in `System`.
|
||||
* .NET Core does sometimes duplicate types, so this check is disabled.
|
||||
*/
|
||||
class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
|
||||
deprecated class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
|
||||
TypeMultiplyDefined() {
|
||||
this.getType().getParent().getName() = "System" and
|
||||
not this.getType() instanceof ConstructedGeneric and
|
||||
@@ -672,7 +672,7 @@ class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
|
||||
/**
|
||||
* A C# declaration which is expected to have a corresponding CIL declaration, but for some reason does not.
|
||||
*/
|
||||
class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck {
|
||||
deprecated class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck {
|
||||
MissingCilDeclaration() {
|
||||
exists(CS::Declaration decl | this = MissingCSharpCheck(decl) |
|
||||
expectedCilDeclaration(decl) and
|
||||
@@ -694,7 +694,7 @@ class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck {
|
||||
/**
|
||||
* Holds if the C# declaration is expected to have a CIl declaration.
|
||||
*/
|
||||
private predicate expectedCilDeclaration(CS::Declaration decl) {
|
||||
deprecated private predicate expectedCilDeclaration(CS::Declaration decl) {
|
||||
decl = decl.getUnboundDeclaration() and
|
||||
not decl instanceof CS::ArrayType and
|
||||
decl.getALocation() instanceof CS::Assembly and
|
||||
@@ -730,7 +730,7 @@ private predicate expectedCilDeclaration(CS::Declaration decl) {
|
||||
}
|
||||
|
||||
/** A member with an invalid name. */
|
||||
class MemberWithInvalidName extends DeclarationViolation {
|
||||
deprecated class MemberWithInvalidName extends DeclarationViolation {
|
||||
MemberWithInvalidName() {
|
||||
exists(string name | name = this.getDeclaration().(Member).getName() |
|
||||
exists(name.indexOf(".")) and
|
||||
@@ -744,7 +744,7 @@ class MemberWithInvalidName extends DeclarationViolation {
|
||||
}
|
||||
}
|
||||
|
||||
class ConstructedSourceDeclarationMethod extends MethodViolation {
|
||||
deprecated class ConstructedSourceDeclarationMethod extends MethodViolation {
|
||||
Method method;
|
||||
|
||||
ConstructedSourceDeclarationMethod() {
|
||||
@@ -762,7 +762,7 @@ class ConstructedSourceDeclarationMethod extends MethodViolation {
|
||||
}
|
||||
|
||||
/** A declaration with multiple labels. */
|
||||
class DeclarationWithMultipleLabels extends DeclarationViolation {
|
||||
deprecated class DeclarationWithMultipleLabels extends DeclarationViolation {
|
||||
DeclarationWithMultipleLabels() {
|
||||
exists(Declaration d | this = DeclarationCheck(d) | strictcount(d.getLabel()) > 1)
|
||||
}
|
||||
@@ -773,7 +773,7 @@ class DeclarationWithMultipleLabels extends DeclarationViolation {
|
||||
}
|
||||
|
||||
/** A declaration without a label. */
|
||||
class DeclarationWithoutLabel extends DeclarationViolation {
|
||||
deprecated class DeclarationWithoutLabel extends DeclarationViolation {
|
||||
DeclarationWithoutLabel() {
|
||||
exists(Declaration d | this = DeclarationCheck(d) |
|
||||
d.isUnboundDeclaration() and
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
private import CIL
|
||||
|
||||
/** A node in the control flow graph. */
|
||||
class ControlFlowNode extends @cil_controlflow_node {
|
||||
deprecated class ControlFlowNode extends @cil_controlflow_node {
|
||||
/** Gets a textual representation of this control flow node. */
|
||||
string toString() { none() }
|
||||
|
||||
@@ -149,31 +149,31 @@ class ControlFlowNode extends @cil_controlflow_node {
|
||||
*
|
||||
* Handlers are control flow nodes because they push the handled exception onto the stack.
|
||||
*/
|
||||
class EntryPoint extends ControlFlowNode, @cil_entry_point {
|
||||
deprecated class EntryPoint extends ControlFlowNode, @cil_entry_point {
|
||||
override int getStackSizeBefore() { result = 0 }
|
||||
}
|
||||
|
||||
private newtype TFlowType =
|
||||
deprecated private newtype TFlowType =
|
||||
TNormalFlow() or
|
||||
TTrueFlow() or
|
||||
TFalseFlow()
|
||||
|
||||
/** A type of control flow. Either normal flow (`NormalFlow`), true flow (`TrueFlow`) or false flow (`FalseFlow`). */
|
||||
abstract class FlowType extends TFlowType {
|
||||
abstract deprecated class FlowType extends TFlowType {
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/** Normal control flow. */
|
||||
class NormalFlow extends FlowType, TNormalFlow {
|
||||
deprecated class NormalFlow extends FlowType, TNormalFlow {
|
||||
override string toString() { result = "" }
|
||||
}
|
||||
|
||||
/** True control flow. */
|
||||
class TrueFlow extends FlowType, TTrueFlow {
|
||||
deprecated class TrueFlow extends FlowType, TTrueFlow {
|
||||
override string toString() { result = "true" }
|
||||
}
|
||||
|
||||
/** False control flow. */
|
||||
class FalseFlow extends FlowType, TFalseFlow {
|
||||
deprecated class FalseFlow extends FlowType, TFalseFlow {
|
||||
override string toString() { result = "false" }
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ private import dotnet
|
||||
* - the type of parameters.
|
||||
* A `CustomModifierReceiver` is therefore either a `Field`, `Property`, `Method`, or `Parameter`.
|
||||
*/
|
||||
class CustomModifierReceiver extends Declaration, @cil_custom_modifier_receiver {
|
||||
deprecated class CustomModifierReceiver extends Declaration, @cil_custom_modifier_receiver {
|
||||
/** Holds if this targeted type has `modifier` applied as `modreq`. */
|
||||
predicate hasRequiredCustomModifier(Type modifier) { cil_custom_modifiers(this, modifier, 1) }
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ private import CIL
|
||||
*
|
||||
* Either an instruction (`Instruction`), a method return (`Method`), or a variable (`Variable`).
|
||||
*/
|
||||
class DataFlowNode extends @cil_dataflow_node {
|
||||
deprecated class DataFlowNode extends @cil_dataflow_node {
|
||||
/** Gets a textual representation of this data flow node. */
|
||||
abstract string toString();
|
||||
|
||||
@@ -24,7 +24,7 @@ class DataFlowNode extends @cil_dataflow_node {
|
||||
}
|
||||
|
||||
/** A node that updates a variable. */
|
||||
abstract class VariableUpdate extends DataFlowNode {
|
||||
abstract deprecated class VariableUpdate extends DataFlowNode {
|
||||
/** Gets the value assigned, if any. */
|
||||
abstract DataFlowNode getSource();
|
||||
|
||||
@@ -35,7 +35,7 @@ abstract class VariableUpdate extends DataFlowNode {
|
||||
abstract predicate updatesAt(BasicBlock bb, int i);
|
||||
}
|
||||
|
||||
private class MethodParameterDef extends VariableUpdate, MethodParameter {
|
||||
deprecated private class MethodParameterDef extends VariableUpdate, MethodParameter {
|
||||
override MethodParameter getSource() { result = this }
|
||||
|
||||
override MethodParameter getVariable() { result = this }
|
||||
@@ -46,7 +46,7 @@ private class MethodParameterDef extends VariableUpdate, MethodParameter {
|
||||
}
|
||||
}
|
||||
|
||||
private class VariableWrite extends VariableUpdate, WriteAccess {
|
||||
deprecated private class VariableWrite extends VariableUpdate, WriteAccess {
|
||||
override Expr getSource() { result = this.getExpr() }
|
||||
|
||||
override Variable getVariable() { result = this.getTarget() }
|
||||
@@ -54,7 +54,7 @@ private class VariableWrite extends VariableUpdate, WriteAccess {
|
||||
override predicate updatesAt(BasicBlock bb, int i) { this = bb.getNode(i) }
|
||||
}
|
||||
|
||||
private class MethodOutOrRefTarget extends VariableUpdate, Call {
|
||||
deprecated private class MethodOutOrRefTarget extends VariableUpdate, Call {
|
||||
int parameterIndex;
|
||||
|
||||
MethodOutOrRefTarget() { this.getTarget().getRawParameter(parameterIndex).hasOutFlag() }
|
||||
|
||||
@@ -10,7 +10,7 @@ private import semmle.code.csharp.commons.QualifiedName
|
||||
/**
|
||||
* A declaration. Either a member (`Member`) or a variable (`Variable`).
|
||||
*/
|
||||
class Declaration extends DotNet::Declaration, Element, @cil_declaration {
|
||||
deprecated class Declaration extends DotNet::Declaration, Element, @cil_declaration {
|
||||
/** Gets an attribute (for example `[Obsolete]`) of this declaration, if any. */
|
||||
Attribute getAnAttribute() { result.getDeclaration() = this }
|
||||
|
||||
@@ -42,14 +42,18 @@ class Declaration extends DotNet::Declaration, Element, @cil_declaration {
|
||||
}
|
||||
}
|
||||
|
||||
private CS::Declaration toCSharpNonTypeParameter(Declaration d) { result.matchesHandle(d) }
|
||||
deprecated private CS::Declaration toCSharpNonTypeParameter(Declaration d) {
|
||||
result.(DotNet::Declaration).matchesHandle(d)
|
||||
}
|
||||
|
||||
private CS::TypeParameter toCSharpTypeParameter(TypeParameter tp) {
|
||||
deprecated private CS::TypeParameter toCSharpTypeParameter(TypeParameter tp) {
|
||||
toCSharpTypeParameterJoin(tp, result.getIndex(), result.getGeneric())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate toCSharpTypeParameterJoin(TypeParameter tp, int i, CS::UnboundGeneric ug) {
|
||||
deprecated private predicate toCSharpTypeParameterJoin(
|
||||
TypeParameter tp, int i, CS::UnboundGeneric ug
|
||||
) {
|
||||
exists(TypeContainer tc |
|
||||
tp.getIndex() = i and
|
||||
tc = tp.getGeneric() and
|
||||
@@ -60,7 +64,7 @@ private predicate toCSharpTypeParameterJoin(TypeParameter tp, int i, CS::Unbound
|
||||
/**
|
||||
* A member of a type. Either a type (`Type`), a method (`Method`), a property (`Property`), or an event (`Event`).
|
||||
*/
|
||||
class Member extends DotNet::Member, Declaration, @cil_member {
|
||||
deprecated class Member extends DotNet::Member, Declaration, @cil_member {
|
||||
override predicate isPublic() { cil_public(this) }
|
||||
|
||||
override predicate isProtected() { cil_protected(this) }
|
||||
@@ -82,7 +86,7 @@ class Member extends DotNet::Member, Declaration, @cil_member {
|
||||
}
|
||||
|
||||
/** A property. */
|
||||
class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_property {
|
||||
deprecated class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_property {
|
||||
override string getName() { cil_property(this, _, result, _) }
|
||||
|
||||
/** Gets the type of this property. */
|
||||
@@ -109,7 +113,7 @@ class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_pr
|
||||
}
|
||||
|
||||
/** A property that is trivial (wraps a field). */
|
||||
class TrivialProperty extends Property {
|
||||
deprecated class TrivialProperty extends Property {
|
||||
TrivialProperty() {
|
||||
this.getGetter().(TrivialGetter).getField() = this.getSetter().(TrivialSetter).getField()
|
||||
}
|
||||
@@ -119,7 +123,7 @@ class TrivialProperty extends Property {
|
||||
}
|
||||
|
||||
/** An event. */
|
||||
class Event extends DotNet::Event, Member, @cil_event {
|
||||
deprecated class Event extends DotNet::Event, Member, @cil_event {
|
||||
override string getName() { cil_event(this, _, result, _) }
|
||||
|
||||
/** Gets the type of this event. */
|
||||
|
||||
@@ -4,12 +4,12 @@ private import dotnet
|
||||
import semmle.code.csharp.Location
|
||||
|
||||
/** An element. */
|
||||
class Element extends DotNet::Element, @cil_element {
|
||||
deprecated class Element extends DotNet::Element, @cil_element {
|
||||
override Location getLocation() { result = bestLocation(this) }
|
||||
}
|
||||
|
||||
cached
|
||||
private Location bestLocation(Element e) {
|
||||
deprecated private Location bestLocation(Element e) {
|
||||
result = e.getALocation() and
|
||||
(e.getALocation().getFile().isPdbSourceFile() implies result.getFile().isPdbSourceFile())
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ private import dotnet
|
||||
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a
|
||||
* constructed generic (`ConstructedGeneric`).
|
||||
*/
|
||||
class Generic extends DotNet::Generic, Declaration, TypeContainer {
|
||||
deprecated class Generic extends DotNet::Generic, Declaration, TypeContainer {
|
||||
Generic() {
|
||||
cil_type_parameter(this, _, _) or
|
||||
cil_type_argument(this, _, _)
|
||||
@@ -15,14 +15,14 @@ class Generic extends DotNet::Generic, Declaration, TypeContainer {
|
||||
}
|
||||
|
||||
/** An unbound generic type or method. */
|
||||
class UnboundGeneric extends Generic, DotNet::UnboundGeneric {
|
||||
deprecated class UnboundGeneric extends Generic, DotNet::UnboundGeneric {
|
||||
UnboundGeneric() { cil_type_parameter(this, _, _) }
|
||||
|
||||
final override TypeParameter getTypeParameter(int n) { cil_type_parameter(this, n, result) }
|
||||
}
|
||||
|
||||
/** A constructed generic type or method. */
|
||||
class ConstructedGeneric extends Generic, DotNet::ConstructedGeneric {
|
||||
deprecated class ConstructedGeneric extends Generic, DotNet::ConstructedGeneric {
|
||||
ConstructedGeneric() { cil_type_argument(this, _, _) }
|
||||
|
||||
final override Type getTypeArgument(int n) { cil_type_argument(this, n, result) }
|
||||
@@ -30,18 +30,18 @@ class ConstructedGeneric extends Generic, DotNet::ConstructedGeneric {
|
||||
|
||||
/** Gets the concatenation of the `getName()` of type arguments. */
|
||||
language[monotonicAggregates]
|
||||
private string getTypeArgumentsNames(ConstructedGeneric cg) {
|
||||
deprecated private string getTypeArgumentsNames(ConstructedGeneric cg) {
|
||||
result = strictconcat(Type t, int i | t = cg.getTypeArgument(i) | t.getName(), "," order by i)
|
||||
}
|
||||
|
||||
/** An unbound generic type. */
|
||||
class UnboundGenericType extends UnboundGeneric, Type { }
|
||||
deprecated class UnboundGenericType extends UnboundGeneric, Type { }
|
||||
|
||||
/** An unbound generic method. */
|
||||
class UnboundGenericMethod extends UnboundGeneric, Method { }
|
||||
deprecated class UnboundGenericMethod extends UnboundGeneric, Method { }
|
||||
|
||||
/** A constructed generic type. */
|
||||
class ConstructedType extends ConstructedGeneric, Type {
|
||||
deprecated class ConstructedType extends ConstructedGeneric, Type {
|
||||
final override UnboundGenericType getUnboundGeneric() { result = this.getUnboundType() }
|
||||
|
||||
override predicate isInterface() { this.getUnboundType().isInterface() }
|
||||
@@ -54,6 +54,6 @@ class ConstructedType extends ConstructedGeneric, Type {
|
||||
}
|
||||
|
||||
/** A constructed generic method. */
|
||||
class ConstructedMethod extends ConstructedGeneric, Method {
|
||||
deprecated class ConstructedMethod extends ConstructedGeneric, Method {
|
||||
final override UnboundGenericMethod getUnboundGeneric() { result = this.getUnboundMethod() }
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ private import CIL
|
||||
* Either a finally handler (`FinallyHandler`), filter handler (`FilterHandler`),
|
||||
* catch handler (`CatchHandler`), or a fault handler (`FaultHandler`).
|
||||
*/
|
||||
class Handler extends Element, EntryPoint, @cil_handler {
|
||||
deprecated class Handler extends Element, EntryPoint, @cil_handler {
|
||||
override MethodImplementation getImplementation() { cil_handler(this, result, _, _, _, _, _) }
|
||||
|
||||
/** Gets the 0-based index of this handler. Handlers are evaluated in this sequence. */
|
||||
@@ -56,12 +56,12 @@ class Handler extends Element, EntryPoint, @cil_handler {
|
||||
}
|
||||
|
||||
/** A handler corresponding to a `finally` block. */
|
||||
class FinallyHandler extends Handler, @cil_finally_handler {
|
||||
deprecated class FinallyHandler extends Handler, @cil_finally_handler {
|
||||
override string toString() { result = "finally {...}" }
|
||||
}
|
||||
|
||||
/** A handler corresponding to a `where()` clause. */
|
||||
class FilterHandler extends Handler, @cil_filter_handler {
|
||||
deprecated class FilterHandler extends Handler, @cil_filter_handler {
|
||||
override string toString() { result = "where (...)" }
|
||||
|
||||
/** Gets the filter clause - the start of a sequence of instructions to evaluate the filter function. */
|
||||
@@ -71,13 +71,13 @@ class FilterHandler extends Handler, @cil_filter_handler {
|
||||
}
|
||||
|
||||
/** A handler corresponding to a `catch` clause. */
|
||||
class CatchHandler extends Handler, @cil_catch_handler {
|
||||
deprecated class CatchHandler extends Handler, @cil_catch_handler {
|
||||
override string toString() { result = "catch(" + this.getCaughtType().getName() + ") {...}" }
|
||||
|
||||
override int getPushCount() { result = 1 }
|
||||
}
|
||||
|
||||
/** A handler for memory faults. */
|
||||
class FaultHandler extends Handler, @cil_fault_handler {
|
||||
deprecated class FaultHandler extends Handler, @cil_fault_handler {
|
||||
override string toString() { result = "fault {...}" }
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
private import CIL
|
||||
|
||||
/** An instruction. */
|
||||
class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instruction {
|
||||
deprecated class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instruction {
|
||||
override string toString() { result = this.getOpcodeName() }
|
||||
|
||||
/** Gets a more verbose textual representation of this instruction. */
|
||||
|
||||
@@ -9,7 +9,7 @@ private import dotnet
|
||||
/**
|
||||
* An instruction that pushes a value onto the stack.
|
||||
*/
|
||||
class Expr extends DotNet::Expr, Instruction, @cil_expr {
|
||||
deprecated class Expr extends DotNet::Expr, Instruction, @cil_expr {
|
||||
override int getPushCount() { result = 1 }
|
||||
|
||||
override Type getType() { result = Instruction.super.getType() }
|
||||
@@ -24,7 +24,7 @@ class Expr extends DotNet::Expr, Instruction, @cil_expr {
|
||||
}
|
||||
|
||||
/** An instruction that changes control flow. */
|
||||
class Branch extends Instruction, @cil_jump {
|
||||
deprecated class Branch extends Instruction, @cil_jump {
|
||||
/** Gets the instruction that is jumped to. */
|
||||
Instruction getTarget() { cil_jump(this, result) }
|
||||
|
||||
@@ -32,7 +32,7 @@ class Branch extends Instruction, @cil_jump {
|
||||
}
|
||||
|
||||
/** An instruction that unconditionally jumps to another instruction. */
|
||||
class UnconditionalBranch extends Branch, @cil_unconditional_jump {
|
||||
deprecated class UnconditionalBranch extends Branch, @cil_unconditional_jump {
|
||||
override Instruction getASuccessorType(FlowType t) {
|
||||
t instanceof NormalFlow and result = this.getTarget()
|
||||
}
|
||||
@@ -41,7 +41,7 @@ class UnconditionalBranch extends Branch, @cil_unconditional_jump {
|
||||
}
|
||||
|
||||
/** An instruction that jumps to a target based on a condition. */
|
||||
class ConditionalBranch extends Branch, @cil_conditional_jump {
|
||||
deprecated class ConditionalBranch extends Branch, @cil_conditional_jump {
|
||||
override Instruction getASuccessorType(FlowType t) {
|
||||
t instanceof TrueFlow and result = this.getTarget()
|
||||
or
|
||||
@@ -52,12 +52,12 @@ class ConditionalBranch extends Branch, @cil_conditional_jump {
|
||||
}
|
||||
|
||||
/** An expression with two operands. */
|
||||
class BinaryExpr extends Expr, @cil_binary_expr {
|
||||
deprecated class BinaryExpr extends Expr, @cil_binary_expr {
|
||||
override int getPopCount() { result = 2 }
|
||||
}
|
||||
|
||||
/** An expression with one operand. */
|
||||
class UnaryExpr extends Expr, @cil_unary_expr {
|
||||
deprecated class UnaryExpr extends Expr, @cil_unary_expr {
|
||||
override int getPopCount() { result = 1 }
|
||||
|
||||
/** Gets the operand of this unary expression. */
|
||||
@@ -65,12 +65,12 @@ class UnaryExpr extends Expr, @cil_unary_expr {
|
||||
}
|
||||
|
||||
/** A binary expression that compares two values. */
|
||||
class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
|
||||
deprecated class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
|
||||
override BoolType getType() { exists(result) }
|
||||
}
|
||||
|
||||
/** A binary arithmetic expression. */
|
||||
class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
|
||||
deprecated class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
|
||||
override Type getType() {
|
||||
exists(Type t0, Type t1 |
|
||||
t0 = this.getOperandType(0).getUnderlyingType() and
|
||||
@@ -86,28 +86,28 @@ class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation
|
||||
}
|
||||
|
||||
/** A binary bitwise expression. */
|
||||
class BinaryBitwiseOperation extends BinaryExpr, @cil_binary_bitwise_operation {
|
||||
deprecated class BinaryBitwiseOperation extends BinaryExpr, @cil_binary_bitwise_operation {
|
||||
// This is wrong but efficient - should depend on the types of the operands.
|
||||
override IntType getType() { exists(result) }
|
||||
}
|
||||
|
||||
/** A unary bitwise expression. */
|
||||
class UnaryBitwiseOperation extends UnaryExpr, @cil_unary_bitwise_operation {
|
||||
deprecated class UnaryBitwiseOperation extends UnaryExpr, @cil_unary_bitwise_operation {
|
||||
// This is wrong but efficient - should depend on the types of the operands.
|
||||
override IntType getType() { exists(result) }
|
||||
}
|
||||
|
||||
/** A unary expression that converts a value from one primitive type to another. */
|
||||
class Conversion extends UnaryExpr, @cil_conversion_operation {
|
||||
deprecated class Conversion extends UnaryExpr, @cil_conversion_operation {
|
||||
/** Gets the expression being converted. */
|
||||
Expr getExpr() { result = this.getOperand(0) }
|
||||
}
|
||||
|
||||
/** A branch that leaves the scope of a `Handler`. */
|
||||
class Leave extends UnconditionalBranch, @cil_leave_any { }
|
||||
deprecated class Leave extends UnconditionalBranch, @cil_leave_any { }
|
||||
|
||||
/** An expression that pushes a literal value onto the stack. */
|
||||
class Literal extends DotNet::Literal, Expr, @cil_literal {
|
||||
deprecated class Literal extends DotNet::Literal, Expr, @cil_literal {
|
||||
/** Gets the pushed value. */
|
||||
override string getValue() { cil_value(this, result) }
|
||||
|
||||
@@ -115,37 +115,37 @@ class Literal extends DotNet::Literal, Expr, @cil_literal {
|
||||
}
|
||||
|
||||
/** An integer literal. */
|
||||
class IntLiteral extends Literal, @cil_ldc_i {
|
||||
deprecated class IntLiteral extends Literal, @cil_ldc_i {
|
||||
override string getExtra() { none() }
|
||||
|
||||
override IntType getType() { exists(result) }
|
||||
}
|
||||
|
||||
/** An expression that pushes a `float`/`Single`. */
|
||||
class FloatLiteral extends Literal, @cil_ldc_r { }
|
||||
deprecated class FloatLiteral extends Literal, @cil_ldc_r { }
|
||||
|
||||
/** An expression that pushes a `null` value onto the stack. */
|
||||
class NullLiteral extends Literal, @cil_ldnull { }
|
||||
deprecated class NullLiteral extends Literal, @cil_ldnull { }
|
||||
|
||||
/** An expression that pushes a string onto the stack. */
|
||||
class StringLiteral extends Literal, @cil_ldstr { }
|
||||
deprecated class StringLiteral extends Literal, @cil_ldstr { }
|
||||
|
||||
/** A branch with one operand. */
|
||||
class UnaryBranch extends ConditionalBranch, @cil_unary_jump {
|
||||
deprecated class UnaryBranch extends ConditionalBranch, @cil_unary_jump {
|
||||
override int getPopCount() { result = 1 }
|
||||
|
||||
override int getPushCount() { result = 0 }
|
||||
}
|
||||
|
||||
/** A branch with two operands. */
|
||||
class BinaryBranch extends ConditionalBranch, @cil_binary_jump {
|
||||
deprecated class BinaryBranch extends ConditionalBranch, @cil_binary_jump {
|
||||
override int getPopCount() { result = 2 }
|
||||
|
||||
override int getPushCount() { result = 0 }
|
||||
}
|
||||
|
||||
/** A call. */
|
||||
class Call extends Expr, DotNet::Call, @cil_call_any {
|
||||
deprecated class Call extends Expr, DotNet::Call, @cil_call_any {
|
||||
/** Gets the method that is called. */
|
||||
override Method getTarget() { cil_access(this, result) }
|
||||
|
||||
@@ -198,24 +198,24 @@ class Call extends Expr, DotNet::Call, @cil_call_any {
|
||||
}
|
||||
|
||||
/** A tail call. */
|
||||
class TailCall extends Call {
|
||||
deprecated class TailCall extends Call {
|
||||
TailCall() { this.isTailCall() }
|
||||
|
||||
override predicate canFlowNext() { none() }
|
||||
}
|
||||
|
||||
/** A call to a static target. */
|
||||
class StaticCall extends Call {
|
||||
deprecated class StaticCall extends Call {
|
||||
StaticCall() { not this.isVirtual() }
|
||||
}
|
||||
|
||||
/** A call to a virtual target. */
|
||||
class VirtualCall extends Call {
|
||||
deprecated class VirtualCall extends Call {
|
||||
VirtualCall() { this.isVirtual() }
|
||||
}
|
||||
|
||||
/** A read of an array element. */
|
||||
class ReadArrayElement extends BinaryExpr, @cil_read_array {
|
||||
deprecated class ReadArrayElement extends BinaryExpr, @cil_read_array {
|
||||
/** Gets the array being read. */
|
||||
Expr getArray() { result = this.getOperand(1) }
|
||||
|
||||
@@ -224,14 +224,14 @@ class ReadArrayElement extends BinaryExpr, @cil_read_array {
|
||||
}
|
||||
|
||||
/** A write of an array element. */
|
||||
class WriteArrayElement extends Instruction, @cil_write_array {
|
||||
deprecated class WriteArrayElement extends Instruction, @cil_write_array {
|
||||
override int getPushCount() { result = 0 }
|
||||
|
||||
override int getPopCount() { result = 3 }
|
||||
}
|
||||
|
||||
/** A `return` statement. */
|
||||
class Return extends Instruction, @cil_ret {
|
||||
deprecated class Return extends Instruction, @cil_ret {
|
||||
/** Gets the expression being returned, if any. */
|
||||
Expr getExpr() { result = this.getOperand(0) }
|
||||
|
||||
@@ -239,7 +239,7 @@ class Return extends Instruction, @cil_ret {
|
||||
}
|
||||
|
||||
/** A `throw` statement. */
|
||||
class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
|
||||
deprecated class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
|
||||
override Expr getExpr() { result = this.getOperand(0) }
|
||||
|
||||
/** Gets the type of the exception being thrown. */
|
||||
@@ -249,7 +249,7 @@ class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
|
||||
}
|
||||
|
||||
/** Stores a value at an address/location. */
|
||||
class StoreIndirect extends Instruction, @cil_stind {
|
||||
deprecated class StoreIndirect extends Instruction, @cil_stind {
|
||||
override int getPopCount() { result = 2 }
|
||||
|
||||
/** Gets the location to store the value at. */
|
||||
@@ -260,4 +260,4 @@ class StoreIndirect extends Instruction, @cil_stind {
|
||||
}
|
||||
|
||||
/** Loads a value from an address/location. */
|
||||
class LoadIndirect extends UnaryExpr, @cil_ldind { }
|
||||
deprecated class LoadIndirect extends UnaryExpr, @cil_ldind { }
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
private import CIL
|
||||
private import semmle.code.dotnet.Variable as DotNet
|
||||
|
||||
module Opcodes {
|
||||
deprecated module Opcodes {
|
||||
/** An `ldc.i4.m1` instruction. */
|
||||
class Ldc_i4_m1 extends IntLiteral, @cil_ldc_i4_m1 {
|
||||
override string getOpcodeName() { result = "ldc.i4.m1" }
|
||||
|
||||
@@ -12,7 +12,7 @@ private import dotnet
|
||||
/**
|
||||
* An implementation of a method in an assembly.
|
||||
*/
|
||||
class MethodImplementation extends EntryPoint, @cil_method_implementation {
|
||||
deprecated class MethodImplementation extends EntryPoint, @cil_method_implementation {
|
||||
/** Gets the method of this implementation. */
|
||||
Method getMethod() { cil_method_implementation(this, result, _) }
|
||||
|
||||
@@ -66,7 +66,7 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation {
|
||||
* A method, which corresponds to any callable in C#, including constructors,
|
||||
* destructors, operators, accessors and so on.
|
||||
*/
|
||||
class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode,
|
||||
deprecated class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode,
|
||||
CustomModifierReceiver, Parameterizable, @cil_method
|
||||
{
|
||||
/**
|
||||
@@ -191,27 +191,27 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
|
||||
}
|
||||
|
||||
/** A destructor/finalizer. */
|
||||
class Destructor extends Method, DotNet::Destructor {
|
||||
deprecated class Destructor extends Method, DotNet::Destructor {
|
||||
Destructor() { this.isFinalizer() }
|
||||
}
|
||||
|
||||
/** A constructor. */
|
||||
class Constructor extends Method, DotNet::Constructor {
|
||||
deprecated class Constructor extends Method, DotNet::Constructor {
|
||||
Constructor() { this.isConstructor() }
|
||||
}
|
||||
|
||||
/** A static/class constructor. */
|
||||
class StaticConstructor extends Constructor {
|
||||
deprecated class StaticConstructor extends Constructor {
|
||||
StaticConstructor() { this.isStaticConstructor() }
|
||||
}
|
||||
|
||||
/** An instance constructor. */
|
||||
class InstanceConstructor extends Constructor {
|
||||
deprecated class InstanceConstructor extends Constructor {
|
||||
InstanceConstructor() { this.isInstanceConstructor() }
|
||||
}
|
||||
|
||||
/** A method that always returns the `this` parameter. */
|
||||
class ChainingMethod extends Method {
|
||||
deprecated class ChainingMethod extends Method {
|
||||
ChainingMethod() {
|
||||
forex(Return ret | ret = this.getImplementation().getAnInstruction() |
|
||||
ret.getExpr() instanceof ThisAccess
|
||||
@@ -220,13 +220,13 @@ class ChainingMethod extends Method {
|
||||
}
|
||||
|
||||
/** An accessor. */
|
||||
abstract class Accessor extends Method {
|
||||
abstract deprecated class Accessor extends Method {
|
||||
/** Gets the property declaring this accessor. */
|
||||
abstract Property getProperty();
|
||||
}
|
||||
|
||||
/** A getter. */
|
||||
class Getter extends Accessor {
|
||||
deprecated class Getter extends Accessor {
|
||||
Getter() { cil_getter(_, this) }
|
||||
|
||||
override Property getProperty() { cil_getter(result, this) }
|
||||
@@ -236,7 +236,7 @@ class Getter extends Accessor {
|
||||
* A method that does nothing but retrieve a field.
|
||||
* Note that this is not necessarily a property getter.
|
||||
*/
|
||||
class TrivialGetter extends Method {
|
||||
deprecated class TrivialGetter extends Method {
|
||||
TrivialGetter() {
|
||||
exists(MethodImplementation impl | impl = this.getAnImplementation() |
|
||||
impl.getInstruction(0) instanceof ThisAccess and
|
||||
@@ -252,7 +252,7 @@ class TrivialGetter extends Method {
|
||||
}
|
||||
|
||||
/** A setter. */
|
||||
class Setter extends Accessor {
|
||||
deprecated class Setter extends Accessor {
|
||||
Setter() { cil_setter(_, this) }
|
||||
|
||||
override Property getProperty() { cil_setter(result, this) }
|
||||
@@ -269,7 +269,7 @@ class Setter extends Accessor {
|
||||
* A method that does nothing but set a field.
|
||||
* This is not necessarily a property setter.
|
||||
*/
|
||||
class TrivialSetter extends Method {
|
||||
deprecated class TrivialSetter extends Method {
|
||||
TrivialSetter() {
|
||||
exists(MethodImplementation impl | impl = this.getAnImplementation() |
|
||||
impl.getInstruction(0) instanceof ThisAccess and
|
||||
@@ -285,10 +285,10 @@ class TrivialSetter extends Method {
|
||||
}
|
||||
|
||||
/** An alias for `Method` for compatibility with the C# data model. */
|
||||
class Callable = Method;
|
||||
deprecated class Callable = Method;
|
||||
|
||||
/** An operator. */
|
||||
class Operator extends Method {
|
||||
deprecated class Operator extends Method {
|
||||
Operator() { this.isOperator() }
|
||||
|
||||
/** Gets the name of the implementing method (for compatibility with C# data model). */
|
||||
|
||||
@@ -8,7 +8,7 @@ private import dotnet
|
||||
/**
|
||||
* A parameterizable entity, such as `FunctionPointerType` or `Method`.
|
||||
*/
|
||||
class Parameterizable extends DotNet::Parameterizable, Element, @cil_parameterizable {
|
||||
deprecated class Parameterizable extends DotNet::Parameterizable, Element, @cil_parameterizable {
|
||||
override Parameter getRawParameter(int n) { cil_parameter(result, this, n, _) }
|
||||
|
||||
override Parameter getParameter(int n) { cil_parameter(result, this, n, _) }
|
||||
|
||||
@@ -7,7 +7,7 @@ private import CIL
|
||||
/**
|
||||
* Provides classes for working with static single assignment (SSA) form.
|
||||
*/
|
||||
module Ssa {
|
||||
deprecated module Ssa {
|
||||
private import internal.SsaImpl as SsaImpl
|
||||
|
||||
/** An SSA definition. */
|
||||
|
||||
@@ -8,7 +8,7 @@ import CIL
|
||||
* The average number of instructions per method,
|
||||
* below which an assembly is probably a stub.
|
||||
*/
|
||||
private float stubInstructionThreshold() { result = 5.1 }
|
||||
deprecated private float stubInstructionThreshold() { result = 5.1 }
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
@@ -18,7 +18,7 @@ private module Cached {
|
||||
* Look at the average number of instructions per method.
|
||||
*/
|
||||
cached
|
||||
predicate assemblyIsStubImpl(Assembly asm) {
|
||||
deprecated predicate assemblyIsStubImpl(Assembly asm) {
|
||||
exists(int totalInstructions, int totalImplementations |
|
||||
totalInstructions = count(Instruction i | i.getImplementation().getLocation() = asm) and
|
||||
totalImplementations =
|
||||
@@ -28,7 +28,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate bestImplementation(MethodImplementation mi) {
|
||||
deprecated predicate bestImplementation(MethodImplementation mi) {
|
||||
exists(Assembly asm |
|
||||
asm = mi.getLocation() and
|
||||
(assemblyIsStubImpl(asm) implies asm.getFile().extractedQlTest()) and
|
||||
@@ -45,13 +45,13 @@ private module Cached {
|
||||
|
||||
private import Cached
|
||||
|
||||
predicate assemblyIsStub = assemblyIsStubImpl/1;
|
||||
deprecated predicate assemblyIsStub = assemblyIsStubImpl/1;
|
||||
|
||||
/**
|
||||
* A method implementation that is the "best" one for a particular method,
|
||||
* if there are several potential implementations to choose between, and
|
||||
* excludes implementations that are probably from stub/reference assemblies.
|
||||
*/
|
||||
class BestImplementation extends MethodImplementation {
|
||||
deprecated class BestImplementation extends MethodImplementation {
|
||||
BestImplementation() { bestImplementation(this) }
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ private import semmle.code.csharp.commons.QualifiedName
|
||||
*
|
||||
* Either a type (`Type`), a method(`Method`), or a namespace (`Namespace`).
|
||||
*/
|
||||
class TypeContainer extends DotNet::NamedElement, @cil_type_container {
|
||||
deprecated class TypeContainer extends DotNet::NamedElement, @cil_type_container {
|
||||
/** Gets the parent of this type container, if any. */
|
||||
TypeContainer getParent() { none() }
|
||||
|
||||
@@ -19,7 +19,7 @@ class TypeContainer extends DotNet::NamedElement, @cil_type_container {
|
||||
}
|
||||
|
||||
/** A namespace. */
|
||||
class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
|
||||
deprecated class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
|
||||
override string toString() { result = this.getFullName() }
|
||||
|
||||
override Namespace getParent() { result = this.getParentNamespace() }
|
||||
@@ -32,7 +32,7 @@ class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
|
||||
/**
|
||||
* A type.
|
||||
*/
|
||||
class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
|
||||
deprecated class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
|
||||
override TypeContainer getParent() { cil_type(this, _, _, result, _) }
|
||||
|
||||
override string getName() { cil_type(this, result, _, _, _) }
|
||||
|
||||
@@ -6,7 +6,7 @@ private import CIL
|
||||
private import dotnet
|
||||
|
||||
/** A type parameter. */
|
||||
class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
|
||||
deprecated class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
|
||||
override int getIndex() { cil_type_parameter(_, result, this) }
|
||||
|
||||
/** Gets the generic type/method declaring this type parameter. */
|
||||
@@ -33,7 +33,7 @@ class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
|
||||
}
|
||||
|
||||
/** A value or reference type. */
|
||||
class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_valueorreftype {
|
||||
deprecated class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_valueorreftype {
|
||||
override ValueOrRefType getDeclaringType() { result = this.getParent() }
|
||||
|
||||
override string getUndecoratedName() { cil_type(this, result, _, _, _) }
|
||||
@@ -44,7 +44,7 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_valueorreftype {
|
||||
}
|
||||
|
||||
/** An `enum`. */
|
||||
class Enum extends ValueOrRefType {
|
||||
deprecated class Enum extends ValueOrRefType {
|
||||
Enum() { this.isEnum() }
|
||||
|
||||
override IntegralType getUnderlyingType() {
|
||||
@@ -56,17 +56,17 @@ class Enum extends ValueOrRefType {
|
||||
}
|
||||
|
||||
/** A `class`. */
|
||||
class Class extends ValueOrRefType {
|
||||
deprecated class Class extends ValueOrRefType {
|
||||
Class() { this.isClass() }
|
||||
}
|
||||
|
||||
/** An `interface`. */
|
||||
class Interface extends ValueOrRefType {
|
||||
deprecated class Interface extends ValueOrRefType {
|
||||
Interface() { this.isInterface() }
|
||||
}
|
||||
|
||||
/** An array. */
|
||||
class ArrayType extends DotNet::ArrayType, Type, @cil_array_type {
|
||||
deprecated class ArrayType extends DotNet::ArrayType, Type, @cil_array_type {
|
||||
override Type getElementType() { cil_array_type(this, result, _) }
|
||||
|
||||
/** Gets the rank of this array. */
|
||||
@@ -80,7 +80,7 @@ class ArrayType extends DotNet::ArrayType, Type, @cil_array_type {
|
||||
}
|
||||
|
||||
/** A pointer type. */
|
||||
class PointerType extends DotNet::PointerType, PrimitiveType, @cil_pointer_type {
|
||||
deprecated class PointerType extends DotNet::PointerType, PrimitiveType, @cil_pointer_type {
|
||||
override Type getReferentType() { cil_pointer_type(this, result) }
|
||||
|
||||
override IntType getUnderlyingType() { any() }
|
||||
@@ -95,31 +95,31 @@ class PointerType extends DotNet::PointerType, PrimitiveType, @cil_pointer_type
|
||||
}
|
||||
|
||||
/** A primitive type, built into the runtime. */
|
||||
abstract class PrimitiveType extends Type { }
|
||||
abstract deprecated class PrimitiveType extends Type { }
|
||||
|
||||
/**
|
||||
* A primitive numeric type.
|
||||
* Either an integral type (`IntegralType`) or a floating point type (`FloatingPointType`).
|
||||
*/
|
||||
abstract class NumericType extends PrimitiveType, ValueOrRefType { }
|
||||
abstract deprecated class NumericType extends PrimitiveType, ValueOrRefType { }
|
||||
|
||||
/** A floating point type. Either single precision (`FloatType`) or double precision (`DoubleType`). */
|
||||
abstract class FloatingPointType extends NumericType { }
|
||||
abstract deprecated class FloatingPointType extends NumericType { }
|
||||
|
||||
/**
|
||||
* An integral numeric type. Either a signed integral type (`SignedIntegralType`)
|
||||
* or an unsigned integral type (`UnsignedIntegralType`).
|
||||
*/
|
||||
abstract class IntegralType extends NumericType { }
|
||||
abstract deprecated class IntegralType extends NumericType { }
|
||||
|
||||
/** A signed integral type. */
|
||||
abstract class SignedIntegralType extends IntegralType { }
|
||||
abstract deprecated class SignedIntegralType extends IntegralType { }
|
||||
|
||||
/** An unsigned integral type. */
|
||||
abstract class UnsignedIntegralType extends IntegralType { }
|
||||
abstract deprecated class UnsignedIntegralType extends IntegralType { }
|
||||
|
||||
/** The `void` type, `System.Void`. */
|
||||
class VoidType extends PrimitiveType {
|
||||
deprecated class VoidType extends PrimitiveType {
|
||||
VoidType() { this.isSystemType("Void") }
|
||||
|
||||
override string toString() { result = "void" }
|
||||
@@ -128,7 +128,7 @@ class VoidType extends PrimitiveType {
|
||||
}
|
||||
|
||||
/** The type `System.Int32`. */
|
||||
class IntType extends SignedIntegralType {
|
||||
deprecated class IntType extends SignedIntegralType {
|
||||
IntType() { this.isSystemType("Int32") }
|
||||
|
||||
override string toStringWithTypes() { result = "int" }
|
||||
@@ -139,21 +139,21 @@ class IntType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.IntPtr`. */
|
||||
class IntPtrType extends PrimitiveType {
|
||||
deprecated class IntPtrType extends PrimitiveType {
|
||||
IntPtrType() { this.isSystemType("IntPtr") }
|
||||
|
||||
override IntType getUnderlyingType() { any() }
|
||||
}
|
||||
|
||||
/** The type `System.UIntPtr`. */
|
||||
class UIntPtrType extends PrimitiveType {
|
||||
deprecated class UIntPtrType extends PrimitiveType {
|
||||
UIntPtrType() { this.isSystemType("UIntPtr") }
|
||||
|
||||
override IntType getUnderlyingType() { any() }
|
||||
}
|
||||
|
||||
/** The type `System.UInt32`. */
|
||||
class UIntType extends UnsignedIntegralType {
|
||||
deprecated class UIntType extends UnsignedIntegralType {
|
||||
UIntType() { this.isSystemType("UInt32") }
|
||||
|
||||
override string toStringWithTypes() { result = "uint" }
|
||||
@@ -164,7 +164,7 @@ class UIntType extends UnsignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.SByte`. */
|
||||
class SByteType extends SignedIntegralType {
|
||||
deprecated class SByteType extends SignedIntegralType {
|
||||
SByteType() { this.isSystemType("SByte") }
|
||||
|
||||
override string toStringWithTypes() { result = "sbyte" }
|
||||
@@ -173,7 +173,7 @@ class SByteType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Byte`. */
|
||||
class ByteType extends UnsignedIntegralType {
|
||||
deprecated class ByteType extends UnsignedIntegralType {
|
||||
ByteType() { this.isSystemType("Byte") }
|
||||
|
||||
override string toStringWithTypes() { result = "byte" }
|
||||
@@ -184,7 +184,7 @@ class ByteType extends UnsignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Int16`. */
|
||||
class ShortType extends SignedIntegralType {
|
||||
deprecated class ShortType extends SignedIntegralType {
|
||||
ShortType() { this.isSystemType("Int16") }
|
||||
|
||||
override string toStringWithTypes() { result = "short" }
|
||||
@@ -193,7 +193,7 @@ class ShortType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.UInt16`. */
|
||||
class UShortType extends UnsignedIntegralType {
|
||||
deprecated class UShortType extends UnsignedIntegralType {
|
||||
UShortType() { this.isSystemType("UInt16") }
|
||||
|
||||
override string toStringWithTypes() { result = "ushort" }
|
||||
@@ -204,7 +204,7 @@ class UShortType extends UnsignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Int64`. */
|
||||
class LongType extends SignedIntegralType {
|
||||
deprecated class LongType extends SignedIntegralType {
|
||||
LongType() { this.isSystemType("Int64") }
|
||||
|
||||
override string toStringWithTypes() { result = "long" }
|
||||
@@ -213,7 +213,7 @@ class LongType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.UInt64`. */
|
||||
class ULongType extends UnsignedIntegralType {
|
||||
deprecated class ULongType extends UnsignedIntegralType {
|
||||
ULongType() { this.isSystemType("UInt64") }
|
||||
|
||||
override string toStringWithTypes() { result = "ulong" }
|
||||
@@ -224,7 +224,7 @@ class ULongType extends UnsignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Decimal`. */
|
||||
class DecimalType extends SignedIntegralType {
|
||||
deprecated class DecimalType extends SignedIntegralType {
|
||||
DecimalType() { this.isSystemType("Decimal") }
|
||||
|
||||
override string toStringWithTypes() { result = "decimal" }
|
||||
@@ -233,21 +233,21 @@ class DecimalType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.String`. */
|
||||
class StringType extends PrimitiveType, ValueOrRefType {
|
||||
deprecated class StringType extends PrimitiveType, ValueOrRefType {
|
||||
StringType() { this.isSystemType("String") }
|
||||
|
||||
override string toStringWithTypes() { result = "string" }
|
||||
}
|
||||
|
||||
/** The type `System.Object`. */
|
||||
class ObjectType extends ValueOrRefType {
|
||||
deprecated class ObjectType extends ValueOrRefType {
|
||||
ObjectType() { this.isSystemType("Object") }
|
||||
|
||||
override string toStringWithTypes() { result = "object" }
|
||||
}
|
||||
|
||||
/** The type `System.Boolean`. */
|
||||
class BoolType extends PrimitiveType, ValueOrRefType {
|
||||
deprecated class BoolType extends PrimitiveType, ValueOrRefType {
|
||||
BoolType() { this.isSystemType("Boolean") }
|
||||
|
||||
override string toStringWithTypes() { result = "bool" }
|
||||
@@ -256,7 +256,7 @@ class BoolType extends PrimitiveType, ValueOrRefType {
|
||||
}
|
||||
|
||||
/** The type `System.Double`. */
|
||||
class DoubleType extends FloatingPointType {
|
||||
deprecated class DoubleType extends FloatingPointType {
|
||||
DoubleType() { this.isSystemType("Double") }
|
||||
|
||||
override string toStringWithTypes() { result = "double" }
|
||||
@@ -265,7 +265,7 @@ class DoubleType extends FloatingPointType {
|
||||
}
|
||||
|
||||
/** The type `System.Single`. */
|
||||
class FloatType extends FloatingPointType {
|
||||
deprecated class FloatType extends FloatingPointType {
|
||||
FloatType() { this.isSystemType("Single") }
|
||||
|
||||
override string toStringWithTypes() { result = "float" }
|
||||
@@ -274,7 +274,7 @@ class FloatType extends FloatingPointType {
|
||||
}
|
||||
|
||||
/** The type `System.Char`. */
|
||||
class CharType extends IntegralType {
|
||||
deprecated class CharType extends IntegralType {
|
||||
CharType() { this.isSystemType("Char") }
|
||||
|
||||
override string toStringWithTypes() { result = "char" }
|
||||
@@ -285,7 +285,7 @@ class CharType extends IntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Type`. */
|
||||
class SystemType extends ValueOrRefType {
|
||||
deprecated class SystemType extends ValueOrRefType {
|
||||
SystemType() { this.isSystemType("Type") }
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ class SystemType extends ValueOrRefType {
|
||||
* delegate*<int, void>
|
||||
* ```
|
||||
*/
|
||||
class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable,
|
||||
deprecated class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable,
|
||||
@cil_function_pointer_type
|
||||
{
|
||||
/** Gets the return type of this function pointer. */
|
||||
|
||||
@@ -6,7 +6,7 @@ private import CIL
|
||||
private import dotnet
|
||||
|
||||
/** A variable. Either a stack variable (`StackVariable`) or a field (`Field`). */
|
||||
class Variable extends DotNet::Variable, Declaration, DataFlowNode, @cil_variable {
|
||||
deprecated class Variable extends DotNet::Variable, Declaration, DataFlowNode, @cil_variable {
|
||||
/** Gets the type of this variable. */
|
||||
override Type getType() { none() }
|
||||
|
||||
@@ -28,7 +28,7 @@ class Variable extends DotNet::Variable, Declaration, DataFlowNode, @cil_variabl
|
||||
}
|
||||
|
||||
/** A stack variable. Either a local variable (`LocalVariable`) or a parameter (`Parameter`). */
|
||||
class StackVariable extends Variable, @cil_stack_variable {
|
||||
deprecated class StackVariable extends Variable, @cil_stack_variable {
|
||||
deprecated override predicate hasQualifiedName(string qualifier, string name) { none() }
|
||||
|
||||
override predicate hasFullyQualifiedName(string qualifier, string name) { none() }
|
||||
@@ -39,7 +39,7 @@ class StackVariable extends Variable, @cil_stack_variable {
|
||||
*
|
||||
* Each method in CIL has a number of typed local variables, in addition to the evaluation stack.
|
||||
*/
|
||||
class LocalVariable extends StackVariable, @cil_local_variable {
|
||||
deprecated class LocalVariable extends StackVariable, @cil_local_variable {
|
||||
override string toString() {
|
||||
result =
|
||||
"Local variable " + this.getIndex() + " of method " +
|
||||
@@ -60,7 +60,7 @@ class LocalVariable extends StackVariable, @cil_local_variable {
|
||||
}
|
||||
|
||||
/** A parameter of a `Method` or `FunctionPointerType`. */
|
||||
class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_parameter {
|
||||
deprecated class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_parameter {
|
||||
override Parameterizable getDeclaringElement() { cil_parameter(this, result, _, _) }
|
||||
|
||||
/** Gets the index of this parameter. */
|
||||
@@ -107,7 +107,7 @@ class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_paramete
|
||||
}
|
||||
|
||||
/** A method parameter. */
|
||||
class MethodParameter extends Parameter, StackVariable {
|
||||
deprecated class MethodParameter extends Parameter, StackVariable {
|
||||
/** Gets the method declaring this parameter. */
|
||||
override Method getMethod() { this = result.getARawParameter() }
|
||||
|
||||
@@ -132,7 +132,7 @@ class MethodParameter extends Parameter, StackVariable {
|
||||
}
|
||||
|
||||
/** A parameter corresponding to `this`. */
|
||||
class ThisParameter extends MethodParameter {
|
||||
deprecated class ThisParameter extends MethodParameter {
|
||||
ThisParameter() {
|
||||
not this.getMethod().isStatic() and
|
||||
this.getIndex() = 0
|
||||
@@ -140,7 +140,7 @@ class ThisParameter extends MethodParameter {
|
||||
}
|
||||
|
||||
/** A field. */
|
||||
class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @cil_field {
|
||||
deprecated class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @cil_field {
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override string toStringWithTypes() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
private import cil
|
||||
private import codeql.ssa.Ssa as SsaImplCommon
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig<CIL::Location> {
|
||||
deprecated private module SsaInput implements SsaImplCommon::InputSig<CIL::Location> {
|
||||
class BasicBlock = CIL::BasicBlock;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }
|
||||
@@ -29,17 +29,17 @@ private module SsaInput implements SsaImplCommon::InputSig<CIL::Location> {
|
||||
}
|
||||
}
|
||||
|
||||
import SsaImplCommon::Make<CIL::Location, SsaInput>
|
||||
deprecated import SsaImplCommon::Make<CIL::Location, SsaInput>
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
private import CIL
|
||||
|
||||
cached
|
||||
predicate forceCachingInSameStage() { any() }
|
||||
deprecated predicate forceCachingInSameStage() { any() }
|
||||
|
||||
cached
|
||||
ReadAccess getARead(Definition def) {
|
||||
deprecated ReadAccess getARead(Definition def) {
|
||||
exists(BasicBlock bb, int i |
|
||||
ssaDefReachesRead(_, def, bb, i) and
|
||||
result = bb.getNode(i)
|
||||
@@ -47,7 +47,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
ReadAccess getAFirstReadExt(DefinitionExt def) {
|
||||
deprecated ReadAccess getAFirstReadExt(DefinitionExt def) {
|
||||
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
def.definesAt(_, bb1, i1, _) and
|
||||
adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and
|
||||
@@ -56,7 +56,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasAdjacentReadsExt(DefinitionExt def, ReadAccess first, ReadAccess second) {
|
||||
deprecated predicate hasAdjacentReadsExt(DefinitionExt def, ReadAccess first, ReadAccess second) {
|
||||
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
first = bb1.getNode(i1) and
|
||||
adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and
|
||||
@@ -65,10 +65,12 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) }
|
||||
deprecated Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) }
|
||||
|
||||
cached
|
||||
predicate lastRefBeforeRedefExt(DefinitionExt def, BasicBlock bb, int i, DefinitionExt next) {
|
||||
deprecated predicate lastRefBeforeRedefExt(
|
||||
DefinitionExt def, BasicBlock bb, int i, DefinitionExt next
|
||||
) {
|
||||
lastRefRedefExt(def, _, bb, i, next)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import Stmt
|
||||
import Type
|
||||
import exprs.Call
|
||||
private import commons.QualifiedName
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import semmle.code.csharp.metrics.Complexity
|
||||
private import TypeRef
|
||||
@@ -21,8 +20,73 @@ private import TypeRef
|
||||
* an anonymous function (`AnonymousFunctionExpr`), or a local function
|
||||
* (`LocalFunction`).
|
||||
*/
|
||||
class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @callable {
|
||||
override Type getReturnType() { none() }
|
||||
class Callable extends Parameterizable, ExprOrStmtParent, @callable {
|
||||
pragma[noinline]
|
||||
deprecated private string getDeclaringTypeLabel() { result = this.getDeclaringType().getLabel() }
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getParameterTypeLabelNonGeneric(int p) {
|
||||
not this instanceof Generic and
|
||||
result = this.getParameter(p).getType().getLabel()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
pragma[nomagic]
|
||||
deprecated private string getMethodParamListNonGeneric() {
|
||||
result =
|
||||
concat(int p |
|
||||
p in [0 .. this.getNumberOfParameters() - 1]
|
||||
|
|
||||
this.getParameterTypeLabelNonGeneric(p), "," order by p
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getParameterTypeLabelGeneric(int p) {
|
||||
this instanceof Generic and
|
||||
result = this.getParameter(p).getType().getLabel()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
pragma[nomagic]
|
||||
deprecated private string getMethodParamListGeneric() {
|
||||
result =
|
||||
concat(int p |
|
||||
p in [0 .. this.getNumberOfParameters() - 1]
|
||||
|
|
||||
this.getParameterTypeLabelGeneric(p), "," order by p
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getLabelNonGeneric() {
|
||||
not this instanceof Generic and
|
||||
result =
|
||||
this.getReturnTypeLabel() + " " + this.getDeclaringTypeLabel() + "." +
|
||||
this.getUndecoratedName() + "(" + this.getMethodParamListNonGeneric() + ")"
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getLabelGeneric() {
|
||||
result =
|
||||
this.getReturnTypeLabel() + " " + this.getDeclaringTypeLabel() + "." +
|
||||
this.getUndecoratedName() + getGenericsLabel(this) + "(" + this.getMethodParamListGeneric() +
|
||||
")"
|
||||
}
|
||||
|
||||
deprecated final override string getLabel() {
|
||||
result = this.getLabelNonGeneric() or
|
||||
result = this.getLabelGeneric()
|
||||
}
|
||||
|
||||
deprecated private string getReturnTypeLabel() {
|
||||
result = this.getReturnType().getLabel()
|
||||
or
|
||||
not exists(this.getReturnType()) and result = "System.Void"
|
||||
}
|
||||
|
||||
/** Gets the return type of this callable. */
|
||||
Type getReturnType() { none() }
|
||||
|
||||
/** Gets the annotated return type of this callable. */
|
||||
final AnnotatedType getAnnotatedReturnType() { result.appliesTo(this) }
|
||||
@@ -65,7 +129,8 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
|
||||
result = this.getExpressionBody()
|
||||
}
|
||||
|
||||
override predicate hasBody() { exists(this.getBody()) }
|
||||
/** Holds if this callable has a body or an implementation. */
|
||||
predicate hasBody() { exists(this.getBody()) }
|
||||
|
||||
/**
|
||||
* Holds if this callable has a non-empty body. That is, either it has
|
||||
@@ -196,7 +261,8 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
|
||||
)
|
||||
}
|
||||
|
||||
override predicate canReturn(DotNet::Expr e) {
|
||||
/** Holds if this callable can return expression `e`. */
|
||||
predicate canReturn(Expr e) {
|
||||
exists(ReturnStmt ret | ret.getEnclosingCallable() = this | e = ret.getExpr())
|
||||
or
|
||||
e = this.getExpressionBody() and
|
||||
@@ -218,8 +284,6 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
|
||||
|
||||
/** Gets a `Call` that has this callable as a target. */
|
||||
Call getACall() { this = result.getTarget() }
|
||||
|
||||
override Parameter getAParameter() { result = Parameterizable.super.getAParameter() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,7 +389,7 @@ class ExtensionMethod extends Method {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Constructor extends DotNet::Constructor, Callable, Member, Attributable, @constructor {
|
||||
class Constructor extends Callable, Member, Attributable, @constructor {
|
||||
override string getName() { constructors(this, result, _, _) }
|
||||
|
||||
override Type getReturnType() {
|
||||
@@ -435,7 +499,7 @@ class PrimaryConstructor extends Constructor {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Destructor extends DotNet::Destructor, Callable, Member, Attributable, @destructor {
|
||||
class Destructor extends Callable, Member, Attributable, @destructor {
|
||||
override string getName() { destructors(this, result, _, _) }
|
||||
|
||||
override Type getReturnType() {
|
||||
@@ -497,10 +561,33 @@ class Operator extends Callable, Member, Attributable, Overridable, @operator {
|
||||
override Parameter getRawParameter(int i) { result = this.getParameter(i) }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ValueOrRefType getARecordBaseType(ValueOrRefType t) {
|
||||
exists(Callable c |
|
||||
c.hasName("<Clone>$") and
|
||||
c.getNumberOfParameters() = 0 and
|
||||
t = c.getDeclaringType() and
|
||||
result = t
|
||||
)
|
||||
or
|
||||
result = getARecordBaseType(t).getABaseType()
|
||||
}
|
||||
|
||||
/** A clone method on a record. */
|
||||
class RecordCloneMethod extends Method, DotNet::RecordCloneCallable {
|
||||
override Constructor getConstructor() {
|
||||
result = DotNet::RecordCloneCallable.super.getConstructor()
|
||||
class RecordCloneMethod extends Method {
|
||||
RecordCloneMethod() {
|
||||
this.hasName("<Clone>$") and
|
||||
this.getNumberOfParameters() = 0 and
|
||||
this.getReturnType() = getARecordBaseType(this.getDeclaringType()) and
|
||||
this.isPublic() and
|
||||
not this.isStatic()
|
||||
}
|
||||
|
||||
/** Gets the constructor that this clone method calls. */
|
||||
Constructor getConstructor() {
|
||||
result.getDeclaringType() = this.getDeclaringType() and
|
||||
result.getNumberOfParameters() = 1 and
|
||||
result.getParameter(0).getType() = this.getDeclaringType()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
import Location
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import dotnet
|
||||
private import commons.QualifiedName
|
||||
|
||||
/**
|
||||
@@ -14,18 +13,64 @@ private import commons.QualifiedName
|
||||
* (`NamespaceDeclaration`), a `using` directive (`UsingDirective`), or type
|
||||
* parameter constraints (`TypeParameterConstraints`).
|
||||
*/
|
||||
class Element extends DotNet::Element, @element {
|
||||
override string toStringWithTypes() { result = this.toString() }
|
||||
class Element extends @element {
|
||||
/** Gets a textual representation of this element. */
|
||||
cached
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the file containing this element. */
|
||||
final File getFile() { result = this.getLocation().getFile() }
|
||||
|
||||
/** Holds if this element is from source code. */
|
||||
predicate fromSource() { this.getFile().fromSource() }
|
||||
|
||||
/** Holds if this element is from an assembly. */
|
||||
predicate fromLibrary() { this.getFile().fromLibrary() }
|
||||
|
||||
/**
|
||||
* Gets the "language" of this program element, as defined by the extension of the filename.
|
||||
* For example, C# has language "cs", and Visual Basic has language "vb".
|
||||
*/
|
||||
deprecated final string getLanguage() { result = this.getLocation().getFile().getExtension() }
|
||||
|
||||
/**
|
||||
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
|
||||
*
|
||||
* If no primary class can be determined, the result is `"???"`.
|
||||
*/
|
||||
final string getPrimaryQlClasses() {
|
||||
result = strictconcat(this.getAPrimaryQlClass(), ",")
|
||||
or
|
||||
not exists(this.getAPrimaryQlClass()) and
|
||||
result = "???"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of a primary CodeQL class to which this element belongs.
|
||||
*
|
||||
* For most elements, this is simply the most precise syntactic category to
|
||||
* which they belong; for example, `AddExpr` is a primary class, but
|
||||
* `BinaryOperation` is not.
|
||||
*
|
||||
* If no primary classes match, this predicate has no result. If multiple
|
||||
* primary classes match, this predicate can have multiple results.
|
||||
*
|
||||
* See also `getPrimaryQlClasses`, which is better to use in most cases.
|
||||
*/
|
||||
string getAPrimaryQlClass() { none() }
|
||||
|
||||
/** Gets the full textual representation of this element, including type information. */
|
||||
string toStringWithTypes() { result = this.toString() }
|
||||
|
||||
/**
|
||||
* Gets the location of this element. Where an element has locations in
|
||||
* source and assemblies, choose the source location. If there are multiple
|
||||
* assembly locations, choose only one.
|
||||
*/
|
||||
final override Location getLocation() { result = bestLocation(this) }
|
||||
final Location getLocation() { result = bestLocation(this) }
|
||||
|
||||
/** Gets a location of this element, including sources and assemblies. */
|
||||
override Location getALocation() { none() }
|
||||
Location getALocation() { none() }
|
||||
|
||||
/** Gets the parent of this element, if any. */
|
||||
Element getParent() { result.getAChild() = this }
|
||||
@@ -46,3 +91,96 @@ class Element extends DotNet::Element, @element {
|
||||
*/
|
||||
int getIndex() { exists(Element parent | parent.getChild(result) = this) }
|
||||
}
|
||||
|
||||
/** An element that has a name. */
|
||||
class NamedElement extends Element, @named_element {
|
||||
/** Gets the name of this element. */
|
||||
cached
|
||||
string getName() { none() }
|
||||
|
||||
/** Holds if this element has name 'name'. */
|
||||
final predicate hasName(string name) { name = this.getName() }
|
||||
|
||||
/**
|
||||
* Gets the fully qualified name of this element, for example the
|
||||
* fully qualified name of `M` on line 3 is `N.C.M` in
|
||||
*
|
||||
* ```csharp
|
||||
* namespace N {
|
||||
* class C {
|
||||
* void M(int i, string s) { }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
cached
|
||||
deprecated final string getQualifiedName() {
|
||||
exists(string qualifier, string name | this.hasQualifiedName(qualifier, name) |
|
||||
if qualifier = "" then result = name else result = qualifier + "." + name
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified name of this element, for example the
|
||||
* fully qualified name of `M` on line 3 is `N.C.M` in
|
||||
*
|
||||
* ```csharp
|
||||
* namespace N {
|
||||
* class C {
|
||||
* void M(int i, string s) { }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Unbound generic types, such as `IList<T>`, are represented as
|
||||
* ``System.Collections.Generic.IList`1``.
|
||||
*/
|
||||
cached
|
||||
final string getFullyQualifiedName() {
|
||||
exists(string qualifier, string name | this.hasFullyQualifiedName(qualifier, name) |
|
||||
if qualifier = "" then result = name else result = qualifier + "." + name
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `hasFullyQualifiedName` instead.
|
||||
*
|
||||
* Holds if this element has the qualified name `qualifier`.`name`.
|
||||
*/
|
||||
cached
|
||||
deprecated predicate hasQualifiedName(string qualifier, string name) {
|
||||
qualifier = "" and name = this.getName()
|
||||
}
|
||||
|
||||
/** Holds if this element has the fully qualified name `qualifier`.`name`. */
|
||||
cached
|
||||
predicate hasFullyQualifiedName(string qualifier, string name) {
|
||||
qualifier = "" and name = this.getName()
|
||||
}
|
||||
|
||||
/** Gets a unique string label for this element. */
|
||||
cached
|
||||
deprecated string getLabel() { none() }
|
||||
|
||||
/** Holds if `other` has the same metadata handle in the same assembly. */
|
||||
deprecated predicate matchesHandle(NamedElement other) {
|
||||
exists(Assembly asm, int handle |
|
||||
metadata_handle(this, asm, handle) and
|
||||
metadata_handle(other, asm, handle)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element was compiled from source code that is also present in the
|
||||
* database. That is, this element corresponds to another element from source.
|
||||
*/
|
||||
deprecated predicate compiledFromSource() {
|
||||
not this.fromSource() and
|
||||
exists(NamedElement other | other != this |
|
||||
this.matchesHandle(other) and
|
||||
other.fromSource()
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
import Location
|
||||
import Namespace
|
||||
private import commons.QualifiedName
|
||||
private import dotnet
|
||||
private import TypeRef
|
||||
|
||||
/**
|
||||
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a
|
||||
* constructed generic (`ConstructedGeneric`).
|
||||
*/
|
||||
class Generic extends DotNet::Generic, Declaration, @generic {
|
||||
class Generic extends Declaration, @generic {
|
||||
Generic() {
|
||||
type_parameters(_, _, this, _) or
|
||||
type_arguments(_, _, this) or
|
||||
@@ -37,16 +36,23 @@ class Generic extends DotNet::Generic, Declaration, @generic {
|
||||
* Either an unbound generic type (`UnboundGenericType`) or an unbound generic method
|
||||
* (`UnboundGenericMethod`).
|
||||
*/
|
||||
class UnboundGeneric extends DotNet::UnboundGeneric, Generic {
|
||||
class UnboundGeneric extends Generic {
|
||||
UnboundGeneric() { type_parameters(_, _, this, _) }
|
||||
|
||||
final override TypeParameter getTypeParameter(int n) { type_parameters(result, n, this, _) }
|
||||
/** Gets the `i`th type parameter, if any. */
|
||||
final TypeParameter getTypeParameter(int n) { type_parameters(result, n, this, _) }
|
||||
|
||||
override ConstructedGeneric getAConstructedGeneric() { result.getUnboundGeneric() = this }
|
||||
/** Gets a type parameter. */
|
||||
TypeParameter getATypeParameter() { result = this.getTypeParameter(_) }
|
||||
|
||||
override TypeParameter getATypeParameter() {
|
||||
result = DotNet::UnboundGeneric.super.getATypeParameter()
|
||||
}
|
||||
/**
|
||||
* Gets one of the constructed versions of this declaration,
|
||||
* which has been bound to a specific set of types.
|
||||
*/
|
||||
ConstructedGeneric getAConstructedGeneric() { result.getUnboundGeneric() = this }
|
||||
|
||||
/** Gets the total number of type parameters. */
|
||||
int getNumberOfTypeParameters() { result = count(int i | exists(this.getTypeParameter(i))) }
|
||||
}
|
||||
|
||||
/** Gets the type parameters as a comma-separated string. */
|
||||
@@ -67,25 +73,61 @@ private string getTypeParameterBacktick(UnboundGeneric ug) {
|
||||
* Either a constructed generic type (`ConstructedType`) or a constructed
|
||||
* generic method (`ConstructedMethod`).
|
||||
*/
|
||||
class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
|
||||
class ConstructedGeneric extends Generic {
|
||||
ConstructedGeneric() {
|
||||
type_arguments(_, _, this)
|
||||
or
|
||||
nullable_underlying_type(this, _)
|
||||
}
|
||||
|
||||
override UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
|
||||
/**
|
||||
* Gets the unbound generic declaration from which this declaration was
|
||||
* constructed.
|
||||
*/
|
||||
UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
|
||||
|
||||
override UnboundGeneric getUnboundDeclaration() {
|
||||
result = this.getUnboundGeneric().getUnboundDeclaration()
|
||||
}
|
||||
|
||||
override Type getTypeArgument(int i) { none() }
|
||||
/** Gets the `i`th type argument, if any. */
|
||||
Type getTypeArgument(int i) { none() }
|
||||
|
||||
override Type getATypeArgument() { result = this.getTypeArgument(_) }
|
||||
/** Gets a type argument. */
|
||||
Type getATypeArgument() { result = this.getTypeArgument(_) }
|
||||
|
||||
/** Gets the annotated type of type argument `i`. */
|
||||
final AnnotatedType getAnnotatedTypeArgument(int i) { result.appliesToTypeArgument(this, i) }
|
||||
|
||||
/** Gets the total number of type arguments. */
|
||||
final int getNumberOfTypeArguments() { result = count(int i | exists(this.getTypeArgument(i))) }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Constructs the label suffix for a generic method or type.
|
||||
*/
|
||||
deprecated string getGenericsLabel(Generic g) {
|
||||
result = "`" + g.(UnboundGeneric).getNumberOfTypeParameters()
|
||||
or
|
||||
result = "<" + typeArgs(g) + ">"
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getTypeArgumentLabel(ConstructedGeneric generic, int p) {
|
||||
result = generic.getTypeArgument(p).getLabel()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
pragma[nomagic]
|
||||
deprecated private string typeArgs(ConstructedGeneric generic) {
|
||||
result =
|
||||
concat(int p |
|
||||
p in [0 .. generic.getNumberOfTypeArguments() - 1]
|
||||
|
|
||||
getTypeArgumentLabel(generic, p), ","
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the type arguments as a comma-separated string. */
|
||||
@@ -160,7 +202,10 @@ class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
|
||||
/**
|
||||
* A type parameter, for example `T` in `List<T>`.
|
||||
*/
|
||||
class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
|
||||
class TypeParameter extends Type, @type_parameter {
|
||||
/** Gets the generic type or method declaring this type parameter. */
|
||||
UnboundGeneric getDeclaringGeneric() { this = result.getATypeParameter() }
|
||||
|
||||
/** Gets the constraints on this type parameter, if any. */
|
||||
TypeParameterConstraints getConstraints() { result.getTypeParameter() = this }
|
||||
|
||||
@@ -216,8 +261,13 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
|
||||
result = this.getASuppliedType().(TypeParameter).getAnUltimatelySuppliedType()
|
||||
}
|
||||
|
||||
/** Gets the index of this type parameter. For example the index of `U` in `Func<T,U>` is 1. */
|
||||
override int getIndex() { type_parameters(this, result, _, _) }
|
||||
|
||||
deprecated final override string getLabel() { result = "!" + this.getIndex() }
|
||||
|
||||
override string getUndecoratedName() { result = "!" + this.getIndex() }
|
||||
|
||||
/** Gets the generic that defines this type parameter. */
|
||||
UnboundGeneric getGeneric() { type_parameters(this, _, result, _) }
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import Callable
|
||||
import Element
|
||||
import Modifier
|
||||
import Variable
|
||||
private import dotnet
|
||||
private import Implements
|
||||
private import TypeRef
|
||||
private import commons.QualifiedName
|
||||
@@ -26,8 +25,46 @@ private module FullyQualifiedNameInput implements QualifiedNameInputSig {
|
||||
*
|
||||
* Either a modifiable (`Modifiable`) or an assignable (`Assignable`).
|
||||
*/
|
||||
class Declaration extends DotNet::Declaration, Element, @declaration {
|
||||
override ValueOrRefType getDeclaringType() { none() }
|
||||
class Declaration extends NamedElement, @declaration {
|
||||
/** Gets the name of this declaration, without additional decoration such as `<...>`. */
|
||||
string getUndecoratedName() { none() }
|
||||
|
||||
/** Holds if this element has undecorated name 'name'. */
|
||||
final predicate hasUndecoratedName(string name) { name = this.getUndecoratedName() }
|
||||
|
||||
/**
|
||||
* Gets the unbound version of this declaration, that is, the declaration where
|
||||
* all type arguments have been removed. For example, in
|
||||
*
|
||||
* ```csharp
|
||||
* class C<T>
|
||||
* {
|
||||
* class Nested
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* void Method<S>() { }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* we have the following
|
||||
*
|
||||
* | Declaration | Unbound declaration |
|
||||
* |-------------------------|---------------------|
|
||||
* | `C<int>` | ``C`1`` |
|
||||
* | ``C`1.Nested`` | ``C`1.Nested`` |
|
||||
* | `C<int>.Nested` | ``C`1.Nested`` |
|
||||
* | ``C`1.Method`1`` | ``C`1.Method`1`` |
|
||||
* | ``C<int>.Method`1`` | ``C`1.Method`1`` |
|
||||
* | `C<int>.Method<string>` | ``C`1.Method`1`` |
|
||||
*/
|
||||
Declaration getUnboundDeclaration() { result = this }
|
||||
|
||||
/** Holds if this declaration is unbound. */
|
||||
final predicate isUnboundDeclaration() { this.getUnboundDeclaration() = this }
|
||||
|
||||
/** Gets the type containing this declaration, if any. */
|
||||
ValueOrRefType getDeclaringType() { none() }
|
||||
|
||||
/** Holds if this declaration is unconstructed and in source code. */
|
||||
final predicate isSourceDeclaration() { this.fromSource() and this.isUnboundDeclaration() }
|
||||
@@ -222,33 +259,27 @@ class Modifiable extends Declaration, @modifiable {
|
||||
}
|
||||
|
||||
/** A declaration that is a member of a type. */
|
||||
class Member extends DotNet::Member, Modifiable, @member {
|
||||
class Member extends Modifiable, @member {
|
||||
/** Gets an access to this member. */
|
||||
MemberAccess getAnAccess() { result.getTarget() = this }
|
||||
|
||||
override predicate isPublic() { Modifiable.super.isPublic() }
|
||||
|
||||
override predicate isProtected() { Modifiable.super.isProtected() }
|
||||
|
||||
override predicate isPrivate() { Modifiable.super.isPrivate() }
|
||||
|
||||
override predicate isInternal() { Modifiable.super.isInternal() }
|
||||
|
||||
override predicate isSealed() { Modifiable.super.isSealed() }
|
||||
|
||||
override predicate isAbstract() { Modifiable.super.isAbstract() }
|
||||
|
||||
override predicate isStatic() { Modifiable.super.isStatic() }
|
||||
|
||||
override predicate isRequired() { Modifiable.super.isRequired() }
|
||||
|
||||
override predicate isFile() { Modifiable.super.isFile() }
|
||||
|
||||
deprecated final override predicate hasQualifiedName(string namespace, string type, string name) {
|
||||
/**
|
||||
* DEPRECATED: Use `hasFullyQualifiedName` instead.
|
||||
*
|
||||
* Holds if this member has name `name` and is defined in type `type`
|
||||
* with namespace `namespace`.
|
||||
*/
|
||||
cached
|
||||
deprecated final predicate hasQualifiedName(string namespace, string type, string name) {
|
||||
QualifiedName<QualifiedNameInput>::hasQualifiedName(this, namespace, type, name)
|
||||
}
|
||||
|
||||
final override predicate hasFullyQualifiedName(string namespace, string type, string name) {
|
||||
/**
|
||||
* Holds if this member has name `name` and is defined in type `type`
|
||||
* with namespace `namespace`.
|
||||
*/
|
||||
cached
|
||||
final predicate hasFullyQualifiedName(string namespace, string type, string name) {
|
||||
QualifiedName<FullyQualifiedNameInput>::hasQualifiedName(this, namespace, type, name)
|
||||
}
|
||||
}
|
||||
@@ -477,10 +508,24 @@ class Virtualizable extends Overridable, Member, @virtualizable {
|
||||
* A parameterizable declaration. Either a callable (`Callable`), a delegate
|
||||
* type (`DelegateType`), or an indexer (`Indexer`).
|
||||
*/
|
||||
class Parameterizable extends DotNet::Parameterizable, Declaration, @parameterizable {
|
||||
override Parameter getRawParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
class Parameterizable extends Declaration, @parameterizable {
|
||||
/** Gets raw parameter `i`, including the `this` parameter at index 0. */
|
||||
Parameter getRawParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
override Parameter getParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
/** Gets the `i`th parameter, excluding the `this` parameter. */
|
||||
Parameter getParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
/** Gets the number of parameters of this callable. */
|
||||
int getNumberOfParameters() { result = count(this.getAParameter()) }
|
||||
|
||||
/** Holds if this declaration has no parameters. */
|
||||
predicate hasNoParameters() { not exists(this.getAParameter()) }
|
||||
|
||||
/** Gets a parameter, if any. */
|
||||
Parameter getAParameter() { result = this.getParameter(_) }
|
||||
|
||||
/** Gets a raw parameter (including the qualifier), if any. */
|
||||
final Parameter getARawParameter() { result = this.getRawParameter(_) }
|
||||
|
||||
/**
|
||||
* Gets the type of the parameter, possibly prefixed
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/** Provides classes for namespaces. */
|
||||
|
||||
private import semmle.code.csharp.commons.QualifiedName
|
||||
import Element
|
||||
import Type
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A type container. Either a namespace (`Namespace`) or a type (`Type`).
|
||||
@@ -18,24 +18,44 @@ class TypeContainer extends Declaration, @type_container { }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Namespace extends DotNet::Namespace, TypeContainer, Declaration, @namespace {
|
||||
class Namespace extends TypeContainer, Declaration, @namespace {
|
||||
override Namespace getParent() { result = this.getParentNamespace() }
|
||||
|
||||
override Namespace getParentNamespace() { parent_namespace(this, result) }
|
||||
/**
|
||||
* Gets the parent namespace, if any. For example the parent namespace of `System.IO`
|
||||
* is `System`. The parent namespace of `System` is the global namespace.
|
||||
*/
|
||||
Namespace getParentNamespace() { parent_namespace(this, result) }
|
||||
|
||||
override Namespace getAChildNamespace() { parent_namespace(result, this) }
|
||||
/**
|
||||
* Gets a child namespace, if any. For example `System.IO` is a child in
|
||||
* the namespace `System`.
|
||||
*/
|
||||
Namespace getAChildNamespace() { parent_namespace(result, this) }
|
||||
|
||||
override TypeContainer getChild(int i) {
|
||||
i = 0 and
|
||||
parent_namespace(result, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this namespace has the qualified name `qualifier`.`name`.
|
||||
*
|
||||
* For example if the qualified name is `System.Collections.Generic`, then
|
||||
* `qualifier`=`System.Collections` and `name`=`Generic`.
|
||||
*/
|
||||
deprecated override predicate hasQualifiedName(string qualifier, string name) {
|
||||
DotNet::Namespace.super.hasQualifiedName(qualifier, name)
|
||||
namespaceHasQualifiedName(this, qualifier, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this namespace has the qualified name `qualifier`.`name`.
|
||||
*
|
||||
* For example if the qualified name is `System.Collections.Generic`, then
|
||||
* `qualifier`=`System.Collections` and `name`=`Generic`.
|
||||
*/
|
||||
override predicate hasFullyQualifiedName(string qualifier, string name) {
|
||||
DotNet::Namespace.super.hasFullyQualifiedName(qualifier, name)
|
||||
namespaceHasQualifiedName(this, qualifier, name)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,7 +143,28 @@ class Namespace extends DotNet::Namespace, TypeContainer, Declaration, @namespac
|
||||
|
||||
override Location getALocation() { result = this.getADeclaration().getALocation() }
|
||||
|
||||
override string toString() { result = DotNet::Namespace.super.toString() }
|
||||
/** Gets a textual representation of this namespace. */
|
||||
override string toString() { result = this.getFullName() }
|
||||
|
||||
/** Holds if this is the global namespace. */
|
||||
final predicate isGlobalNamespace() { this.getName() = "" }
|
||||
|
||||
/** Gets the simple name of this namespace, for example `IO` in `System.IO`. */
|
||||
final override string getName() { namespaces(this, result) }
|
||||
|
||||
final override string getUndecoratedName() { namespaces(this, result) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Namespace" }
|
||||
|
||||
/**
|
||||
* Get the fully qualified name of this namespace.
|
||||
*/
|
||||
string getFullName() {
|
||||
exists(string namespace, string name |
|
||||
namespaceHasQualifiedName(this, namespace, name) and
|
||||
result = getQualifiedName(namespace, name)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
import Member
|
||||
import Stmt
|
||||
import Type
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import TypeRef
|
||||
|
||||
@@ -113,7 +111,7 @@ class DeclarationWithGetSetAccessors extends DeclarationWithAccessors, TopLevelE
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Property extends DotNet::Property, DeclarationWithGetSetAccessors, @property {
|
||||
class Property extends DeclarationWithGetSetAccessors, @property {
|
||||
override string getName() { properties(this, result, _, _, _) }
|
||||
|
||||
override string getUndecoratedName() { properties(this, result, _, _, _) }
|
||||
@@ -558,8 +556,6 @@ class TrivialProperty extends Property {
|
||||
this.isAutoImplemented()
|
||||
or
|
||||
this.getGetter().trivialGetterField() = this.getSetter().trivialSetterField()
|
||||
or
|
||||
exists(CIL::TrivialProperty prop | this.matchesHandle(prop))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import Location
|
||||
import Namespace
|
||||
import Property
|
||||
private import Conversion
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.metrics.Coupling
|
||||
private import TypeRef
|
||||
private import semmle.code.csharp.frameworks.System
|
||||
@@ -20,7 +19,10 @@ private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
|
||||
* a pointer type (`PointerType`), the arglist type (`ArglistType`), an unknown
|
||||
* type (`UnknownType`), or a type parameter (`TypeParameter`).
|
||||
*/
|
||||
class Type extends DotNet::Type, Member, TypeContainer, @type {
|
||||
class Type extends Member, TypeContainer, @type {
|
||||
/** Gets the name of this type without additional syntax such as `[]` or `*`. */
|
||||
override string getUndecoratedName() { none() }
|
||||
|
||||
override string getName() { types(this, _, result) }
|
||||
|
||||
override Type getUnboundDeclaration() { result = this }
|
||||
@@ -56,7 +58,7 @@ private predicate isObjectClass(Class c) { c instanceof ObjectType }
|
||||
*
|
||||
* Either a value type (`ValueType`) or a reference type (`RefType`).
|
||||
*/
|
||||
class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_or_ref_type {
|
||||
class ValueOrRefType extends Type, Attributable, @value_or_ref_type {
|
||||
/** Gets the namespace containing this type. */
|
||||
Namespace getNamespace() {
|
||||
if exists(this.getDeclaringType())
|
||||
@@ -64,7 +66,8 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
|
||||
else result.getATypeDeclaration() = this
|
||||
}
|
||||
|
||||
override Namespace getDeclaringNamespace() { this = result.getATypeDeclaration() }
|
||||
/** Gets the namespace declaring this type, if any. */
|
||||
Namespace getDeclaringNamespace() { this = result.getATypeDeclaration() }
|
||||
|
||||
override ValueOrRefType getDeclaringType() { none() }
|
||||
|
||||
@@ -73,6 +76,30 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
|
||||
/** Gets a nested child type, if any. */
|
||||
NestedType getAChildType() { nested_types(result, this, _) }
|
||||
|
||||
deprecated private string getPrefixWithTypes() {
|
||||
result = this.getDeclaringType().getLabel() + "."
|
||||
or
|
||||
if this.getDeclaringNamespace().isGlobalNamespace()
|
||||
then result = ""
|
||||
else result = this.getDeclaringNamespace().getFullName() + "."
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getLabelNonGeneric() {
|
||||
not this instanceof Generic and
|
||||
result = this.getPrefixWithTypes() + this.getUndecoratedName()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getLabelGeneric() {
|
||||
result = this.getPrefixWithTypes() + this.getUndecoratedName() + getGenericsLabel(this)
|
||||
}
|
||||
|
||||
deprecated override string getLabel() {
|
||||
result = this.getLabelNonGeneric() or
|
||||
result = this.getLabelGeneric()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source namespace declaration in which this type is declared, if any.
|
||||
* This only holds for non-nested types.
|
||||
@@ -120,7 +147,7 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
|
||||
}
|
||||
|
||||
/** Gets an immediate base type of this type, if any. */
|
||||
override ValueOrRefType getABaseType() {
|
||||
ValueOrRefType getABaseType() {
|
||||
result = this.getBaseClass() or
|
||||
result = this.getABaseInterface()
|
||||
}
|
||||
@@ -360,7 +387,8 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
|
||||
nested_types(this, _, result)
|
||||
}
|
||||
|
||||
override predicate isRecord() { this.hasModifier("record") }
|
||||
/** Holds if this type is a `record`. */
|
||||
predicate isRecord() { this.hasModifier("record") }
|
||||
|
||||
override string toString() { result = Type.super.toString() }
|
||||
}
|
||||
@@ -969,7 +997,7 @@ class FunctionPointerType extends Type, Parameterizable, @function_pointer_type
|
||||
|
||||
override string getAPrimaryQlClass() { result = "FunctionPointerType" }
|
||||
|
||||
override string getLabel() { result = this.getName() }
|
||||
deprecated override string getLabel() { result = this.getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1064,7 +1092,7 @@ class InlineArrayType extends ValueType, @inline_array_type {
|
||||
/**
|
||||
* An array type, for example `int[]`.
|
||||
*/
|
||||
class ArrayType extends DotNet::ArrayType, RefType, @array_type {
|
||||
class ArrayType extends RefType, @array_type {
|
||||
/**
|
||||
* Gets the dimension of this array type. For example `int[][]` is of
|
||||
* dimension 2, while `int[]` is of dimension 1.
|
||||
@@ -1081,13 +1109,15 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
|
||||
predicate isMultiDimensional() { this.getRank() > 1 }
|
||||
|
||||
/** Gets the element type of this array, for example `int` in `int[]`. */
|
||||
override Type getElementType() {
|
||||
Type getElementType() {
|
||||
array_element_type(this, _, _, result)
|
||||
or
|
||||
not array_element_type(this, _, _, any(Type t)) and
|
||||
array_element_type(this, _, _, getTypeRef(result))
|
||||
}
|
||||
|
||||
deprecated final override string getLabel() { result = this.getElementType().getLabel() + "[]" }
|
||||
|
||||
/** Holds if this array type has the same shape (dimension and rank) as `that` array type. */
|
||||
predicate hasSameShapeAs(ArrayType that) {
|
||||
this.getDimension() = that.getDimension() and
|
||||
@@ -1128,33 +1158,36 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
|
||||
not type_location(this, _) and
|
||||
result = this.getElementType().getALocation()
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ArrayType" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A pointer type, for example `char*`.
|
||||
*/
|
||||
class PointerType extends DotNet::PointerType, Type, @pointer_type {
|
||||
override Type getReferentType() {
|
||||
class PointerType extends Type, @pointer_type {
|
||||
/** Gets the type referred by this pointer type, for example `char` in `char*`. */
|
||||
Type getReferentType() {
|
||||
pointer_referent_type(this, result)
|
||||
or
|
||||
not pointer_referent_type(this, any(Type t)) and
|
||||
pointer_referent_type(this, getTypeRef(result))
|
||||
}
|
||||
|
||||
override string toStringWithTypes() { result = DotNet::PointerType.super.toStringWithTypes() }
|
||||
override string toStringWithTypes() { result = this.getReferentType().toStringWithTypes() + "*" }
|
||||
|
||||
override Type getChild(int n) { result = this.getReferentType() and n = 0 }
|
||||
|
||||
final override string getName() { types(this, _, result) }
|
||||
|
||||
deprecated final override string getLabel() { result = this.getReferentType().getLabel() + "*" }
|
||||
|
||||
final override string getUndecoratedName() {
|
||||
result = this.getReferentType().getUndecoratedName()
|
||||
}
|
||||
|
||||
override Location getALocation() { result = this.getReferentType().getALocation() }
|
||||
|
||||
override string toString() { result = DotNet::PointerType.super.toString() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "PointerType" }
|
||||
}
|
||||
|
||||
@@ -1238,7 +1271,7 @@ class TupleType extends ValueType, @tuple_type {
|
||||
")"
|
||||
}
|
||||
|
||||
override string getLabel() { result = this.getUnderlyingType().getLabel() }
|
||||
deprecated override string getLabel() { result = this.getUnderlyingType().getLabel() }
|
||||
|
||||
override Type getChild(int i) { result = this.getUnderlyingType().getChild(i) }
|
||||
|
||||
|
||||
@@ -7,18 +7,18 @@ import Assignable
|
||||
import Callable
|
||||
import Element
|
||||
import Type
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import TypeRef
|
||||
|
||||
/**
|
||||
* A variable. Either a variable with local scope (`LocalScopeVariable`) or a field (`Field`).
|
||||
*/
|
||||
class Variable extends Assignable, DotNet::Variable, @variable {
|
||||
class Variable extends Assignable, @variable {
|
||||
override Variable getUnboundDeclaration() { result = this }
|
||||
|
||||
override VariableAccess getAnAccess() { result.getTarget() = this }
|
||||
|
||||
/** Gets the type of this variable. */
|
||||
override Type getType() { none() }
|
||||
|
||||
/** Gets the expression used to initialise this variable, if any. */
|
||||
@@ -87,9 +87,10 @@ class LocalScopeVariable extends Variable, @local_scope_variable {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, TopLevelExprParent,
|
||||
@parameter
|
||||
{
|
||||
class Parameter extends LocalScopeVariable, Attributable, TopLevelExprParent, @parameter {
|
||||
/** Gets the raw position of this parameter, including the `this` parameter at index 0. */
|
||||
final int getRawPosition() { this = this.getDeclaringElement().getRawParameter(result) }
|
||||
|
||||
/**
|
||||
* Gets the position of this parameter. For example, the position of `x` is
|
||||
* 0 and the position of `y` is 1 in
|
||||
@@ -100,7 +101,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override int getPosition() { params(this, _, _, result, _, _, _) }
|
||||
int getPosition() { params(this, _, _, result, _, _, _) }
|
||||
|
||||
override int getIndex() { result = this.getPosition() }
|
||||
|
||||
@@ -138,7 +139,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override predicate isOut() { params(this, _, _, _, 2, _, _) }
|
||||
predicate isOut() { params(this, _, _, _, 2, _, _) }
|
||||
|
||||
/**
|
||||
* Holds if this parameter is a value type that is passed in by reference.
|
||||
@@ -193,7 +194,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
|
||||
predicate hasExtensionMethodModifier() { params(this, _, _, _, 4, _, _) }
|
||||
|
||||
/** Gets the declaring element of this parameter. */
|
||||
override Parameterizable getDeclaringElement() { params(this, _, _, _, _, result, _) }
|
||||
Parameterizable getDeclaringElement() { params(this, _, _, _, _, result, _) }
|
||||
|
||||
override Parameter getUnboundDeclaration() { params(this, _, _, _, _, _, result) }
|
||||
|
||||
@@ -396,9 +397,7 @@ class LocalConstant extends LocalVariable, @local_constant {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent, DotNet::Field,
|
||||
@field
|
||||
{
|
||||
class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent, @field {
|
||||
/**
|
||||
* Gets the initial value of this field, if any. For example, the initial
|
||||
* value of `F` on line 2 is `20` in
|
||||
|
||||
@@ -3,56 +3,13 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
|
||||
private predicate isDisposeMethod(DotNet::Callable method) {
|
||||
private predicate isDisposeMethod(Callable method) {
|
||||
method.getName() = "Dispose" and
|
||||
method.getNumberOfParameters() = 0
|
||||
}
|
||||
|
||||
private predicate cilVariableReadFlowsToNode(CIL::Variable variable, DataFlow::Node n) {
|
||||
n.asExpr() = variable.getARead()
|
||||
or
|
||||
exists(DataFlow::Node mid |
|
||||
cilVariableReadFlowsToNode(variable, mid) and
|
||||
DataFlow::localFlowStep(mid, n)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate cilVariableReadFlowsTo(CIL::Variable variable, CIL::DataFlowNode n) {
|
||||
cilVariableReadFlowsToNode(variable, DataFlow::exprNode(n))
|
||||
}
|
||||
|
||||
private predicate disposedCilVariable(CIL::Variable variable) {
|
||||
// `variable` is the `this` parameter on a dispose method.
|
||||
isDisposeMethod(variable.(CIL::ThisParameter).getMethod())
|
||||
or
|
||||
// `variable` is passed to a method that disposes it.
|
||||
exists(CIL::Call call, CIL::Parameter param |
|
||||
cilVariableReadFlowsTo(variable, call.getArgumentForParameter(param)) and
|
||||
disposedCilVariable(param)
|
||||
)
|
||||
or
|
||||
// A parameter is disposed if its source declaration is disposed
|
||||
disposedCilVariable(variable.(CIL::Parameter).getUnboundDeclaration())
|
||||
or
|
||||
// A variable is disposed if it's assigned to another variable
|
||||
// that may be disposed.
|
||||
exists(CIL::WriteAccess write |
|
||||
cilVariableReadFlowsTo(variable, write.getExpr()) and
|
||||
disposedCilVariable(write.getTarget())
|
||||
)
|
||||
}
|
||||
|
||||
private predicate disposedCSharpVariable(Variable variable) {
|
||||
// A C# parameter is disposed if its corresponding CIL parameter is disposed
|
||||
exists(CIL::Method m, CIL::Parameter p, int i |
|
||||
disposedCilVariable(p) and p = m.getRawParameter(i)
|
||||
|
|
||||
variable = any(Callable c2 | c2.matchesHandle(m)).getRawParameter(i)
|
||||
)
|
||||
or
|
||||
// Call to a method that disposes it
|
||||
exists(Call call, int arg, VariableRead read |
|
||||
read.getTarget() = variable and
|
||||
@@ -83,7 +40,4 @@ private predicate disposedCSharpVariable(Variable variable) {
|
||||
* Hold if `variable` might be disposed.
|
||||
* This is a conservative overestimate.
|
||||
*/
|
||||
predicate mayBeDisposed(DotNet::Variable variable) {
|
||||
disposedCSharpVariable(variable) or
|
||||
disposedCilVariable(variable)
|
||||
}
|
||||
predicate mayBeDisposed(Variable variable) { disposedCSharpVariable(variable) }
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/** Provides predicates for working with fully qualified names. */
|
||||
|
||||
private import csharp
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* Holds if namespace `n` has the qualified name `qualifier`.`name`.
|
||||
@@ -9,8 +8,8 @@ private import dotnet
|
||||
* For example if the qualified name is `System.Collections.Generic`, then
|
||||
* `qualifier`=`System.Collections` and `name`=`Generic`.
|
||||
*/
|
||||
predicate namespaceHasQualifiedName(DotNet::Namespace n, string qualifier, string name) {
|
||||
if n instanceof DotNet::GlobalNamespace
|
||||
predicate namespaceHasQualifiedName(Namespace n, string qualifier, string name) {
|
||||
if n instanceof GlobalNamespace
|
||||
then qualifier = "" and name = ""
|
||||
else (
|
||||
exists(string pqualifier, string pname |
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import ControlFlow::SuccessorTypes
|
||||
private import semmle.code.csharp.commons.Assertions
|
||||
private import semmle.code.csharp.commons.ComparisonTest
|
||||
@@ -844,8 +842,6 @@ class NullGuardedDataFlowNode extends GuardedDataFlowNode {
|
||||
|
||||
/** INTERNAL: Do not use. */
|
||||
module Internal {
|
||||
private import semmle.code.cil.CallableReturns
|
||||
|
||||
newtype TAbstractValue =
|
||||
TBooleanValue(boolean b) { b = true or b = false } or
|
||||
TIntegerValue(int i) { i = any(Expr e).getValue().toInt() } or
|
||||
@@ -856,20 +852,11 @@ module Internal {
|
||||
} or
|
||||
TEmptyCollectionValue(boolean b) { b = true or b = false }
|
||||
|
||||
/** A callable that always returns a `null` value. */
|
||||
private class NullCallable extends Callable {
|
||||
NullCallable() {
|
||||
exists(CIL::Method m | m.matchesHandle(this) | alwaysNullMethod(m) and not m.isVirtual())
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if expression `e` is a `null` value. */
|
||||
predicate nullValue(Expr e) {
|
||||
e instanceof NullLiteral
|
||||
or
|
||||
e instanceof DefaultValueExpr and e.getType().isRefType()
|
||||
or
|
||||
e.(Call).getTarget().getUnboundDeclaration() instanceof NullCallable
|
||||
}
|
||||
|
||||
/** Holds if expression `e2` is a `null` value whenever `e1` is. */
|
||||
@@ -890,11 +877,7 @@ module Internal {
|
||||
|
||||
/** A callable that always returns a non-`null` value. */
|
||||
private class NonNullCallable extends Callable {
|
||||
NonNullCallable() {
|
||||
exists(CIL::Method m | m.matchesHandle(this) | alwaysNotNullMethod(m) and not m.isVirtual())
|
||||
or
|
||||
this = any(SystemObjectClass c).getGetTypeMethod()
|
||||
}
|
||||
NonNullCallable() { this = any(SystemObjectClass c).getGetTypeMethod() }
|
||||
}
|
||||
|
||||
/** Holds if expression `e` is a non-`null` value. */
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import semmle.code.cil.CallableReturns
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import semmle.code.csharp.commons.Assertions
|
||||
private import semmle.code.csharp.frameworks.System
|
||||
@@ -39,15 +37,6 @@ private class ThrowingCall extends NonReturningCall {
|
||||
or
|
||||
this.(FailingAssertion).getAssertionFailure().isException(c.getExceptionClass())
|
||||
or
|
||||
exists(Callable target, CIL::Method m, CIL::Type ex |
|
||||
target = this.getTarget() and
|
||||
not target.hasBody() and
|
||||
target.matchesHandle(m) and
|
||||
alwaysThrowsException(m, ex) and
|
||||
c.getExceptionClass().matchesHandle(ex) and
|
||||
not m.isVirtual()
|
||||
)
|
||||
or
|
||||
this =
|
||||
any(MethodCall mc |
|
||||
mc.getTarget()
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import semmle.code.csharp.dataflow.Nullness
|
||||
private import semmle.code.cil.CallableReturns as CR
|
||||
|
||||
private predicate finalCallable(Callable c) {
|
||||
not c.(Virtualizable).isVirtual() and
|
||||
@@ -15,19 +13,11 @@ private predicate finalCallable(Callable c) {
|
||||
/** Holds if callable `c` always returns null. */
|
||||
predicate alwaysNullCallable(Callable c) {
|
||||
finalCallable(c) and
|
||||
(
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNullMethod(m))
|
||||
or
|
||||
forex(Expr e | c.canReturn(e) | e instanceof AlwaysNullExpr)
|
||||
)
|
||||
forex(Expr e | c.canReturn(e) | e instanceof AlwaysNullExpr)
|
||||
}
|
||||
|
||||
/** Holds if callable `c` always returns a non-null value. */
|
||||
predicate alwaysNotNullCallable(Callable c) {
|
||||
finalCallable(c) and
|
||||
(
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNotNullMethod(m))
|
||||
or
|
||||
forex(Expr e | c.canReturn(e) | e instanceof NonNullExpr)
|
||||
)
|
||||
forex(Expr e | c.canReturn(e) | e instanceof NonNullExpr)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
private import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import DataFlowPublic
|
||||
private import DataFlowPrivate
|
||||
@@ -14,30 +12,11 @@ private import semmle.code.csharp.frameworks.system.collections.Generic
|
||||
/**
|
||||
* Gets a source declaration of callable `c` that has a body or has
|
||||
* a flow summary.
|
||||
*
|
||||
* If the callable has both CIL and source code, return only the source
|
||||
* code version.
|
||||
*/
|
||||
DotNet::Callable getCallableForDataFlow(DotNet::Callable c) {
|
||||
exists(DotNet::Callable unboundDecl | unboundDecl = c.getUnboundDeclaration() |
|
||||
result.hasBody() and
|
||||
if unboundDecl.getFile().fromSource()
|
||||
then
|
||||
// C# callable with C# implementation in the database
|
||||
result = unboundDecl
|
||||
else
|
||||
if unboundDecl instanceof CIL::Callable
|
||||
then
|
||||
// CIL callable with C# implementation in the database
|
||||
unboundDecl.matchesHandle(result.(Callable))
|
||||
or
|
||||
// CIL callable without C# implementation in the database
|
||||
not unboundDecl.matchesHandle(any(Callable k | k.hasBody())) and
|
||||
result = unboundDecl
|
||||
else
|
||||
// C# callable without C# implementation in the database
|
||||
unboundDecl.matchesHandle(result.(CIL::Callable))
|
||||
)
|
||||
Callable getCallableForDataFlow(Callable c) {
|
||||
result = c.getUnboundDeclaration() and
|
||||
result.hasBody() and
|
||||
result.getFile().fromSource()
|
||||
}
|
||||
|
||||
newtype TReturnKind =
|
||||
@@ -67,7 +46,7 @@ private module Cached {
|
||||
*/
|
||||
cached
|
||||
newtype TDataFlowCallable =
|
||||
TDotNetCallable(DotNet::Callable c) { c.isUnboundDeclaration() } or
|
||||
TCallable(Callable c) { c.isUnboundDeclaration() } or
|
||||
TSummarizedCallable(DataFlowSummarizedCallable sc) or
|
||||
TFieldOrPropertyCallable(FieldOrProperty f) or
|
||||
TCapturedVariableCallable(LocalScopeVariable v) { v.isCaptured() }
|
||||
@@ -81,10 +60,6 @@ private module Cached {
|
||||
TExplicitDelegateLikeCall(ControlFlow::Nodes::ElementNode cfn, DelegateLikeCall dc) {
|
||||
cfn.getAstNode() = dc
|
||||
} or
|
||||
TCilCall(CIL::Call call) {
|
||||
// No need to include calls that are compiled from source
|
||||
not call.getImplementation().getMethod().compiledFromSource()
|
||||
} or
|
||||
TSummaryCall(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
@@ -197,7 +172,7 @@ class RefReturnKind extends OutRefReturnKind, TRefReturnKind {
|
||||
/** A callable used for data flow. */
|
||||
class DataFlowCallable extends TDataFlowCallable {
|
||||
/** Gets the underlying source code callable, if any. */
|
||||
DotNet::Callable asCallable() { this = TDotNetCallable(result) }
|
||||
Callable asCallable() { this = TCallable(result) }
|
||||
|
||||
/** Gets the underlying summarized callable, if any. */
|
||||
FlowSummary::SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) }
|
||||
@@ -208,7 +183,7 @@ class DataFlowCallable extends TDataFlowCallable {
|
||||
LocalScopeVariable asCapturedVariable() { this = TCapturedVariableCallable(result) }
|
||||
|
||||
/** Gets the underlying callable. */
|
||||
DotNet::Callable getUnderlyingCallable() {
|
||||
Callable getUnderlyingCallable() {
|
||||
result = this.asCallable() or result = this.asSummarizedCallable()
|
||||
}
|
||||
|
||||
@@ -235,8 +210,7 @@ class DataFlowCallable extends TDataFlowCallable {
|
||||
abstract class DataFlowCall extends TDataFlowCall {
|
||||
/**
|
||||
* Gets a run-time target of this call. A target is always a source
|
||||
* declaration, and if the callable has both CIL and source code, only
|
||||
* the source code version is returned.
|
||||
* declaration.
|
||||
*/
|
||||
abstract DataFlowCallable getARuntimeTarget();
|
||||
|
||||
@@ -250,7 +224,7 @@ abstract class DataFlowCall extends TDataFlowCall {
|
||||
abstract DataFlowCallable getEnclosingCallable();
|
||||
|
||||
/** Gets the underlying expression, if any. */
|
||||
final DotNet::Expr getExpr() { result = this.getNode().asExpr() }
|
||||
final Expr getExpr() { result = this.getNode().asExpr() }
|
||||
|
||||
/** Gets the argument at position `pos` of this call. */
|
||||
final ArgumentNode getArgument(ArgumentPosition pos) { result.argumentOf(this, pos) }
|
||||
@@ -348,33 +322,6 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe
|
||||
override Location getLocation() { result = cfn.getLocation() }
|
||||
}
|
||||
|
||||
/** A CIL call relevant for data flow. */
|
||||
class CilDataFlowCall extends DataFlowCall, TCilCall {
|
||||
private CIL::Call call;
|
||||
|
||||
CilDataFlowCall() { this = TCilCall(call) }
|
||||
|
||||
/** Gets the underlying CIL call. */
|
||||
CIL::Call getCilCall() { result = call }
|
||||
|
||||
override DataFlowCallable getARuntimeTarget() {
|
||||
// There is no dispatch library for CIL, so do not consider overrides for now
|
||||
result.getUnderlyingCallable() = getCallableForDataFlow(call.getTarget())
|
||||
}
|
||||
|
||||
override ControlFlow::Nodes::ElementNode getControlFlowNode() { none() }
|
||||
|
||||
override DataFlow::ExprNode getNode() { result.getExpr() = call }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asCallable() = call.getEnclosingCallable()
|
||||
}
|
||||
|
||||
override string toString() { result = call.toString() }
|
||||
|
||||
override Location getLocation() { result = call.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A synthesized call inside a callable with a flow summary.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
private import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import DataFlowPublic
|
||||
private import DataFlowDispatch
|
||||
private import DataFlowImplCommon
|
||||
@@ -18,8 +16,6 @@ private import semmle.code.csharp.frameworks.NHibernate
|
||||
private import semmle.code.csharp.frameworks.Razor
|
||||
private import semmle.code.csharp.frameworks.system.Collections
|
||||
private import semmle.code.csharp.frameworks.system.threading.Tasks
|
||||
private import semmle.code.cil.Ssa::Ssa as CilSsa
|
||||
private import semmle.code.cil.internal.SsaImpl as CilSsaImpl
|
||||
private import codeql.util.Unit
|
||||
private import codeql.util.Boolean
|
||||
|
||||
@@ -57,15 +53,15 @@ abstract class NodeImpl extends Node {
|
||||
|
||||
/** Do not call: use `getType()` instead. */
|
||||
cached
|
||||
abstract DotNet::Type getTypeImpl();
|
||||
abstract Type getTypeImpl();
|
||||
|
||||
/** Gets the type of this node used for type pruning. */
|
||||
DataFlowType getDataFlowType() {
|
||||
forceCachingInSameStage() and
|
||||
exists(Type t0 | result.asGvnType() = Gvn::getGlobalValueNumber(t0) |
|
||||
t0 = getCSharpType(this.getType())
|
||||
t0 = this.getType()
|
||||
or
|
||||
not exists(getCSharpType(this.getType())) and
|
||||
not exists(this.getType()) and
|
||||
t0 instanceof ObjectType
|
||||
)
|
||||
}
|
||||
@@ -96,16 +92,12 @@ private DataFlowCallable getEnclosingStaticFieldOrProperty(Expr e) {
|
||||
|
||||
private class ExprNodeImpl extends ExprNode, NodeImpl {
|
||||
override DataFlowCallable getEnclosingCallableImpl() {
|
||||
result.asCallable() =
|
||||
[
|
||||
this.getExpr().(CIL::Expr).getEnclosingCallable().(DotNet::Callable),
|
||||
this.getControlFlowNodeImpl().getEnclosingCallable()
|
||||
]
|
||||
result.asCallable() = this.getControlFlowNodeImpl().getEnclosingCallable()
|
||||
or
|
||||
result = getEnclosingStaticFieldOrProperty(this.asExpr())
|
||||
}
|
||||
|
||||
override DotNet::Type getTypeImpl() {
|
||||
override Type getTypeImpl() {
|
||||
forceCachingInSameStage() and
|
||||
result = this.getExpr().getType()
|
||||
}
|
||||
@@ -121,11 +113,6 @@ private class ExprNodeImpl extends ExprNode, NodeImpl {
|
||||
override string toStringImpl() {
|
||||
forceCachingInSameStage() and
|
||||
result = this.getControlFlowNodeImpl().toString()
|
||||
or
|
||||
exists(CIL::Expr e |
|
||||
this = TCilExprNode(e) and
|
||||
result = e.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +135,7 @@ abstract private class LocalFunctionCreationNode extends NodeImpl, TLocalFunctio
|
||||
LocalFunction getFunction() { result = function }
|
||||
|
||||
ExprNode getAnAccess(boolean inSameCallable) {
|
||||
result.getExpr().(LocalFunctionAccess).getTarget() = this.getFunction() and
|
||||
isLocalFunctionCallReceiver(_, result.getExpr(), this.getFunction()) and
|
||||
if result.getEnclosingCallable() = this.getEnclosingCallable()
|
||||
then inSameCallable = true
|
||||
else inSameCallable = false
|
||||
@@ -260,12 +247,6 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the CIL data-flow node for `node`, if any. */
|
||||
CIL::DataFlowNode asCilDataFlowNode(Node node) {
|
||||
result = node.asParameter() or
|
||||
result = node.asExpr()
|
||||
}
|
||||
|
||||
/** Provides logic related to captured variables. */
|
||||
module VariableCapture {
|
||||
private import codeql.dataflow.VariableCapture as Shared
|
||||
@@ -399,7 +380,11 @@ module VariableCapture {
|
||||
|
||||
predicate hasBody(Callable body) { body = c }
|
||||
|
||||
predicate hasAliasedAccess(Expr f) { closureFlowStep+(this, f) and not closureFlowStep(f, _) }
|
||||
predicate hasAliasedAccess(Expr f) {
|
||||
closureFlowStep+(this, f) and not closureFlowStep(f, _)
|
||||
or
|
||||
isLocalFunctionCallReceiver(_, f.getAstNode(), c)
|
||||
}
|
||||
}
|
||||
|
||||
class Callable extends Cs::Callable {
|
||||
@@ -727,79 +712,6 @@ module LocalFlow {
|
||||
)
|
||||
}
|
||||
|
||||
private module CilFlow {
|
||||
/**
|
||||
* Holds if `nodeFrom` is a last node referencing SSA definition `def`, which
|
||||
* can reach `next`.
|
||||
*/
|
||||
private predicate localFlowCilSsaInput(
|
||||
Node nodeFrom, CilSsaImpl::DefinitionExt def, CilSsaImpl::DefinitionExt next
|
||||
) {
|
||||
exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedefExt(def, bb, i, next) |
|
||||
def.definesAt(_, bb, i, _) and
|
||||
def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() and
|
||||
def != next
|
||||
or
|
||||
nodeFrom = TCilExprNode(bb.getNode(i).(CIL::ReadAccess))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
|
||||
* CIL SSA definition `def`.
|
||||
*/
|
||||
private predicate localCilSsaFlowStep(CilSsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
// Flow into SSA definition
|
||||
exists(CIL::VariableUpdate vu |
|
||||
vu = def.(CilSsa::Definition).getVariableUpdate() and
|
||||
vu.getSource() = asCilDataFlowNode(nodeFrom) and
|
||||
def = nodeTo.(CilSsaDefinitionExtNode).getDefinition()
|
||||
)
|
||||
or
|
||||
// Flow from SSA definition to first read
|
||||
def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() and
|
||||
nodeTo = TCilExprNode(CilSsaImpl::getAFirstReadExt(def))
|
||||
or
|
||||
// Flow from read to next read
|
||||
exists(CIL::ReadAccess readFrom, CIL::ReadAccess readTo |
|
||||
CilSsaImpl::hasAdjacentReadsExt(def, readFrom, readTo) and
|
||||
nodeTo = TCilExprNode(readTo) and
|
||||
nodeFrom = TCilExprNode(readFrom) and
|
||||
nodeFrom != nodeTo
|
||||
)
|
||||
or
|
||||
// Flow into phi (read) node
|
||||
exists(CilSsaImpl::DefinitionExt phi |
|
||||
localFlowCilSsaInput(nodeFrom, def, phi) and
|
||||
phi = nodeTo.(CilSsaDefinitionExtNode).getDefinition()
|
||||
|
|
||||
phi instanceof CilSsa::PhiNode
|
||||
or
|
||||
phi instanceof CilSsaImpl::PhiReadNode
|
||||
)
|
||||
}
|
||||
|
||||
private predicate localExactStep(CIL::DataFlowNode src, CIL::DataFlowNode sink) {
|
||||
src = sink.(CIL::Opcodes::Dup).getAnOperand()
|
||||
or
|
||||
src = sink.(CIL::Conversion).getExpr()
|
||||
or
|
||||
src = sink.(CIL::WriteAccess).getExpr()
|
||||
or
|
||||
src = sink.(CIL::Method).getAnImplementation().getAnInstruction().(CIL::Return)
|
||||
or
|
||||
src = sink.(CIL::Return).getExpr()
|
||||
or
|
||||
src = sink.(CIL::ConditionalBranch).getAnOperand()
|
||||
}
|
||||
|
||||
predicate localFlowStepCil(Node nodeFrom, Node nodeTo) {
|
||||
localExactStep(asCilDataFlowNode(nodeFrom), asCilDataFlowNode(nodeTo))
|
||||
or
|
||||
localCilSsaFlowStep(_, nodeFrom, nodeTo)
|
||||
}
|
||||
}
|
||||
|
||||
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
|
||||
hasNodePath(any(LocalExprStepConfiguration x), nodeFrom, nodeTo)
|
||||
or
|
||||
@@ -808,8 +720,6 @@ module LocalFlow {
|
||||
or
|
||||
ThisFlow::adjacentThisRefs(nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
|
||||
or
|
||||
CilFlow::localFlowStepCil(nodeFrom, nodeTo)
|
||||
or
|
||||
exists(AssignableDefinition def, ControlFlow::Node cfn, Ssa::ExplicitDefinition ssaDef |
|
||||
ssaDef.getADefinition() = def and
|
||||
ssaDef.getControlFlowNode() = cfn and
|
||||
@@ -881,7 +791,7 @@ module LocalFlow {
|
||||
exists(SsaImpl::getAReadAtNode(def, node2.(ExprNode).getControlFlowNode()))
|
||||
)
|
||||
or
|
||||
delegateCreationStep(node1, node2)
|
||||
node2 = node1.(LocalFunctionCreationNode).getAnAccess(true)
|
||||
or
|
||||
node1 =
|
||||
unique(FlowSummaryNode n1 |
|
||||
@@ -1111,13 +1021,6 @@ private predicate arrayStore(Expr e, Expr src, Expr a, boolean postUpdate) {
|
||||
*/
|
||||
private predicate arrayRead(Expr e1, ArrayRead e2) { e1 = e2.getQualifier() }
|
||||
|
||||
private Type getCSharpType(DotNet::Type t) {
|
||||
result = t
|
||||
or
|
||||
not t instanceof Type and
|
||||
result.matchesHandle(t)
|
||||
}
|
||||
|
||||
private class RelevantGvnType extends Gvn::GvnType {
|
||||
RelevantGvnType() { this = any(NodeImpl n).getDataFlowType().asGvnType() }
|
||||
}
|
||||
@@ -1189,8 +1092,6 @@ private module Cached {
|
||||
cached
|
||||
newtype TNode =
|
||||
TExprNode(ControlFlow::Nodes::ElementNode cfn) { cfn.getAstNode() instanceof Expr } or
|
||||
TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or
|
||||
TCilSsaDefinitionExtNode(CilSsaImpl::DefinitionExt def) or
|
||||
TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) {
|
||||
// Handled by `TExplicitParameterNode` below
|
||||
not def.(Ssa::ExplicitDefinition).getADefinition() instanceof
|
||||
@@ -1201,7 +1102,7 @@ private module Cached {
|
||||
// Handled by `TExplicitParameterNode` below
|
||||
not def instanceof AssignableDefinitions::ImplicitParameterDefinition
|
||||
} or
|
||||
TExplicitParameterNode(DotNet::Parameter p) {
|
||||
TExplicitParameterNode(Parameter p) {
|
||||
p = any(DataFlowCallable dfc).asCallable().getAParameter()
|
||||
} or
|
||||
TInstanceParameterNode(InstanceCallable c) or
|
||||
@@ -1371,28 +1272,6 @@ predicate nodeIsHidden(Node n) {
|
||||
n instanceof CaptureNode
|
||||
}
|
||||
|
||||
/** A CIL SSA definition, viewed as a node in a data flow graph. */
|
||||
class CilSsaDefinitionExtNode extends NodeImpl, TCilSsaDefinitionExtNode {
|
||||
CilSsaImpl::DefinitionExt def;
|
||||
|
||||
CilSsaDefinitionExtNode() { this = TCilSsaDefinitionExtNode(def) }
|
||||
|
||||
/** Gets the underlying SSA definition. */
|
||||
CilSsaImpl::DefinitionExt getDefinition() { result = def }
|
||||
|
||||
override DataFlowCallable getEnclosingCallableImpl() {
|
||||
result.asCallable() = def.getBasicBlock().getFirstNode().getImplementation().getMethod()
|
||||
}
|
||||
|
||||
override CIL::Type getTypeImpl() { result = def.getSourceVariable().getType() }
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { none() }
|
||||
|
||||
override Location getLocationImpl() { result = def.getBasicBlock().getLocation() }
|
||||
|
||||
override string toStringImpl() { result = def.toString() }
|
||||
}
|
||||
|
||||
/** An SSA definition, viewed as a node in a data flow graph. */
|
||||
class SsaDefinitionExtNode extends NodeImpl, TSsaDefinitionExtNode {
|
||||
SsaImpl::DefinitionExt def;
|
||||
@@ -1464,7 +1343,7 @@ private module ParameterNodes {
|
||||
* flow graph.
|
||||
*/
|
||||
class ExplicitParameterNode extends ParameterNodeImpl, TExplicitParameterNode {
|
||||
private DotNet::Parameter parameter;
|
||||
private Parameter parameter;
|
||||
|
||||
ExplicitParameterNode() { this = TExplicitParameterNode(parameter) }
|
||||
|
||||
@@ -1482,7 +1361,7 @@ private module ParameterNodes {
|
||||
result.asCallable() = parameter.getCallable()
|
||||
}
|
||||
|
||||
override DotNet::Type getTypeImpl() { result = parameter.getType() }
|
||||
override Type getTypeImpl() { result = parameter.getType() }
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { none() }
|
||||
|
||||
@@ -1539,7 +1418,7 @@ private module ParameterNodes {
|
||||
|
||||
override Location getLocationImpl() { result = callable.getLocation() }
|
||||
|
||||
override DotNet::Type getTypeImpl() { none() }
|
||||
override Type getTypeImpl() { none() }
|
||||
|
||||
override DataFlowType getDataFlowType() { callable = result.asDelegate() }
|
||||
|
||||
@@ -1608,11 +1487,7 @@ private module ArgumentNodes {
|
||||
|
||||
/** A data-flow node that represents an explicit call argument. */
|
||||
class ExplicitArgumentNode extends ArgumentNodeImpl {
|
||||
ExplicitArgumentNode() {
|
||||
this.asExpr() instanceof Argument
|
||||
or
|
||||
this.asExpr() = any(CilDataFlowCall cc).getCilCall().getAnArgument()
|
||||
}
|
||||
ExplicitArgumentNode() { this.asExpr() instanceof Argument }
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
exists(ArgumentConfiguration x, Expr c, Argument arg |
|
||||
@@ -1621,12 +1496,6 @@ private module ArgumentNodes {
|
||||
arg.isArgumentOf(c, pos) and
|
||||
x.hasExprPath(_, this.getControlFlowNode(), _, call.getControlFlowNode())
|
||||
)
|
||||
or
|
||||
exists(CIL::Call c, CIL::Expr arg |
|
||||
arg = this.asExpr() and
|
||||
c = call.getExpr() and
|
||||
arg = c.getArgument(pos.getPosition())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1743,7 +1612,7 @@ private module ReturnNodes {
|
||||
*/
|
||||
class ExprReturnNode extends ReturnNode, ExprNode {
|
||||
ExprReturnNode() {
|
||||
exists(DotNet::Callable c, DotNet::Expr e | e = this.getExpr() |
|
||||
exists(Callable c, Expr e | e = this.getExpr() |
|
||||
c.canReturn(e) and not c.(Modifiable).isAsync()
|
||||
)
|
||||
}
|
||||
@@ -1877,17 +1746,13 @@ private module OutNodes {
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that reads a value returned directly by a callable,
|
||||
* either via a C# call or a CIL call.
|
||||
* A data-flow node that reads a value returned directly by a callable.
|
||||
*/
|
||||
class ExprOutNode extends OutNode, ExprNode {
|
||||
private DataFlowCall call;
|
||||
|
||||
ExprOutNode() {
|
||||
exists(DotNet::Expr e | e = this.getExpr() |
|
||||
call = csharpCall(e, this.getControlFlowNode()) or
|
||||
call = TCilCall(e)
|
||||
)
|
||||
exists(Expr e | e = this.getExpr() | call = csharpCall(e, this.getControlFlowNode()))
|
||||
}
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) {
|
||||
@@ -1969,7 +1834,7 @@ class FlowSummaryNode extends NodeImpl, TFlowSummaryNode {
|
||||
result = FlowSummaryImpl::Private::summaryNodeType(this.getSummaryNode())
|
||||
}
|
||||
|
||||
override DotNet::Type getTypeImpl() { none() }
|
||||
override Type getTypeImpl() { none() }
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { none() }
|
||||
|
||||
@@ -2130,8 +1995,6 @@ class FieldOrProperty extends Assignable, Modifiable {
|
||||
or
|
||||
p.isAutoImplementedReadOnly()
|
||||
or
|
||||
p.matchesHandle(any(CIL::TrivialProperty tp))
|
||||
or
|
||||
p.getDeclaringType() instanceof AnonymousClass
|
||||
)
|
||||
)
|
||||
@@ -2549,9 +2412,10 @@ class DataFlowType extends TDataFlowType {
|
||||
* creations associated with the same type.
|
||||
*/
|
||||
ControlFlowElement getADelegateCreation() {
|
||||
exists(Callable callable |
|
||||
lambdaCreationExpr(result, callable) and
|
||||
this = TDelegateDataFlowType(callable)
|
||||
exists(Callable callable | this = TDelegateDataFlowType(callable) |
|
||||
lambdaCreationExpr(result, callable)
|
||||
or
|
||||
isLocalFunctionCallReceiver(_, result, callable)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2566,12 +2430,7 @@ class DataFlowType extends TDataFlowType {
|
||||
DataFlowType getNodeType(Node n) {
|
||||
result = n.(NodeImpl).getDataFlowType() and
|
||||
not lambdaCreation(n, _, _) and
|
||||
not delegateCreationStep(_, n)
|
||||
or
|
||||
exists(Node arg |
|
||||
delegateCreationStep(arg, n) and
|
||||
result = getNodeType(arg)
|
||||
)
|
||||
not isLocalFunctionCallReceiver(_, n.asExpr(), _)
|
||||
or
|
||||
[
|
||||
n.asExpr().(ControlFlowElement),
|
||||
@@ -2740,7 +2599,7 @@ module PostUpdateNodes {
|
||||
result = getEnclosingStaticFieldOrProperty(oc)
|
||||
}
|
||||
|
||||
override DotNet::Type getTypeImpl() { result = oc.getType() }
|
||||
override Type getTypeImpl() { result = oc.getType() }
|
||||
|
||||
override ControlFlow::Nodes::ElementNode getControlFlowNodeImpl() { result = cfn }
|
||||
|
||||
@@ -2853,7 +2712,7 @@ class CastNode extends Node {
|
||||
}
|
||||
}
|
||||
|
||||
class DataFlowExpr = DotNet::Expr;
|
||||
class DataFlowExpr = Expr;
|
||||
|
||||
/** Holds if `e` is an expression that always has the same Boolean value `val`. */
|
||||
private predicate constantBooleanExpr(Expr e, boolean val) {
|
||||
@@ -2896,7 +2755,7 @@ private predicate lambdaCreationExpr(ControlFlowElement creation, Callable c) {
|
||||
c =
|
||||
[
|
||||
creation.(AnonymousFunctionExpr),
|
||||
creation.(CallableAccess).getTarget().getUnboundDeclaration(),
|
||||
creation.(DelegateCreation).getArgument().(CallableAccess).getTarget().getUnboundDeclaration(),
|
||||
creation.(AddressOfExpr).getOperand().(CallableAccess).getTarget().getUnboundDeclaration(),
|
||||
creation.(LocalFunctionStmt).getLocalFunction()
|
||||
]
|
||||
@@ -2910,6 +2769,13 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
private predicate isLocalFunctionCallReceiver(
|
||||
LocalFunctionCall call, LocalFunctionAccess receiver, LocalFunction f
|
||||
) {
|
||||
receiver.getParent() = call and
|
||||
f = receiver.getTarget().getUnboundDeclaration()
|
||||
}
|
||||
|
||||
private class LambdaConfiguration extends ControlFlowReachabilityConfiguration {
|
||||
LambdaConfiguration() { this = "LambdaConfiguration" }
|
||||
|
||||
@@ -2926,7 +2792,7 @@ private class LambdaConfiguration extends ControlFlowReachabilityConfiguration {
|
||||
scope = e2 and
|
||||
isSuccessor = true
|
||||
or
|
||||
e1.(LocalFunctionAccess).getParent() = e2.(LocalFunctionCall) and
|
||||
isLocalFunctionCallReceiver(e2, e1, _) and
|
||||
exactScope = false and
|
||||
scope = e2 and
|
||||
isSuccessor = true
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
private import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import DataFlowDispatch
|
||||
private import DataFlowPrivate
|
||||
private import semmle.code.csharp.controlflow.Guards
|
||||
@@ -12,7 +10,7 @@ private import semmle.code.csharp.Unification
|
||||
*/
|
||||
class Node extends TNode {
|
||||
/** Gets the expression corresponding to this node, if any. */
|
||||
DotNet::Expr asExpr() { result = this.(ExprNode).getExpr() }
|
||||
Expr asExpr() { result = this.(ExprNode).getExpr() }
|
||||
|
||||
/**
|
||||
* Gets the expression corresponding to this node, at control flow node `cfn`,
|
||||
@@ -23,7 +21,7 @@ class Node extends TNode {
|
||||
}
|
||||
|
||||
/** Gets the parameter corresponding to this node, if any. */
|
||||
DotNet::Parameter asParameter() { result = this.(ParameterNode).getParameter() }
|
||||
Parameter asParameter() { result = this.(ParameterNode).getParameter() }
|
||||
|
||||
/** Gets the definition corresponding to this node, if any. */
|
||||
AssignableDefinition asDefinition() { result = this.asDefinitionAtNode(_) }
|
||||
@@ -37,7 +35,7 @@ class Node extends TNode {
|
||||
}
|
||||
|
||||
/** Gets the type of this node. */
|
||||
final DotNet::Type getType() { result = this.(NodeImpl).getTypeImpl() }
|
||||
final Type getType() { result = this.(NodeImpl).getTypeImpl() }
|
||||
|
||||
/** Gets the enclosing callable of this node. */
|
||||
final Callable getEnclosingCallable() {
|
||||
@@ -67,8 +65,6 @@ class Node extends TNode {
|
||||
}
|
||||
}
|
||||
|
||||
private class TExprNode_ = TExprNode or TCilExprNode;
|
||||
|
||||
/**
|
||||
* An expression, viewed as a node in a data flow graph.
|
||||
*
|
||||
@@ -76,13 +72,9 @@ private class TExprNode_ = TExprNode or TCilExprNode;
|
||||
* to multiple `ExprNode`s, just like it may correspond to multiple
|
||||
* `ControlFlow::Node`s.
|
||||
*/
|
||||
class ExprNode extends Node, TExprNode_ {
|
||||
class ExprNode extends Node, TExprNode {
|
||||
/** Gets the expression corresponding to this node. */
|
||||
DotNet::Expr getExpr() {
|
||||
result = this.getExprAtNode(_)
|
||||
or
|
||||
this = TCilExprNode(result)
|
||||
}
|
||||
Expr getExpr() { result = this.getExprAtNode(_) }
|
||||
|
||||
/**
|
||||
* Gets the expression corresponding to this node, at control flow node `cfn`,
|
||||
@@ -94,16 +86,22 @@ class ExprNode extends Node, TExprNode_ {
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isParameterOf0(DataFlowCallable c, ParameterPosition ppos, Parameter p) {
|
||||
p.getCallable() = c.asCallable() and
|
||||
p.getPosition() = ppos.getPosition()
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of a parameter at function entry, viewed as a node in a data
|
||||
* flow graph.
|
||||
*/
|
||||
class ParameterNode extends Node instanceof ParameterNodeImpl {
|
||||
/** Gets the parameter corresponding to this node, if any. */
|
||||
DotNet::Parameter getParameter() {
|
||||
Parameter getParameter() {
|
||||
exists(DataFlowCallable c, ParameterPosition ppos |
|
||||
super.isParameterOf(c, ppos) and
|
||||
result = c.asCallable().getParameter(ppos.getPosition())
|
||||
isParameterOf0(c, ppos, result)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -120,12 +118,12 @@ class AssignableDefinitionNode extends Node instanceof AssignableDefinitionNodeI
|
||||
}
|
||||
|
||||
/** Gets a node corresponding to expression `e`. */
|
||||
ExprNode exprNode(DotNet::Expr e) { result.getExpr() = e }
|
||||
ExprNode exprNode(Expr e) { result.getExpr() = e }
|
||||
|
||||
/**
|
||||
* Gets the node corresponding to the value of parameter `p` at function entry.
|
||||
*/
|
||||
ParameterNode parameterNode(DotNet::Parameter p) { result.getParameter() = p }
|
||||
ParameterNode parameterNode(Parameter p) { result.getParameter() = p }
|
||||
|
||||
/** Gets a node corresponding to the definition `def`. */
|
||||
AssignableDefinitionNode assignableDefinitionNode(AssignableDefinition def) {
|
||||
@@ -146,7 +144,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
|
||||
* local (intra-procedural) steps.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate localExprFlow(DotNet::Expr e1, DotNet::Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
|
||||
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
|
||||
|
||||
/**
|
||||
* A data flow node that jumps between callables. This can be extended in
|
||||
|
||||
@@ -7,8 +7,6 @@ private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.csharp.dataflow.internal.ControlFlowReachability
|
||||
private import semmle.code.csharp.dispatch.Dispatch
|
||||
private import semmle.code.csharp.commons.ComparisonTest
|
||||
private import cil
|
||||
private import dotnet
|
||||
// import `TaintedMember` definitions from other files to avoid potential reevaluation
|
||||
private import semmle.code.csharp.frameworks.JsonNET
|
||||
private import semmle.code.csharp.frameworks.WCF
|
||||
@@ -33,16 +31,6 @@ predicate defaultTaintSanitizer(DataFlow::Node node) {
|
||||
bindingset[node]
|
||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() }
|
||||
|
||||
private predicate localCilTaintStep(CIL::DataFlowNode src, CIL::DataFlowNode sink) {
|
||||
src = sink.(CIL::BinaryArithmeticExpr).getAnOperand() or
|
||||
src = sink.(CIL::Opcodes::Neg).getOperand() or
|
||||
src = sink.(CIL::UnaryBitwiseOperation).getOperand()
|
||||
}
|
||||
|
||||
private predicate localTaintStepCil(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
localCilTaintStep(asCilDataFlowNode(nodeFrom), asCilDataFlowNode(nodeTo))
|
||||
}
|
||||
|
||||
private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityConfiguration {
|
||||
LocalTaintExprStepConfiguration() { this = "LocalTaintExprStepConfiguration" }
|
||||
|
||||
@@ -106,8 +94,6 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
|
||||
|
||||
private predicate localTaintStepCommon(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
hasNodePath(any(LocalTaintExprStepConfiguration x), nodeFrom, nodeTo)
|
||||
or
|
||||
localTaintStepCil(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
cached
|
||||
|
||||
@@ -5,14 +5,12 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A run-time callable. That is, a callable that is neither abstract
|
||||
* nor defined in an interface.
|
||||
*/
|
||||
class RuntimeCallable extends DotNet::Callable {
|
||||
class RuntimeCallable extends Callable {
|
||||
RuntimeCallable() {
|
||||
not this.(Modifiable).isAbstract() and
|
||||
(
|
||||
@@ -23,15 +21,7 @@ class RuntimeCallable extends DotNet::Callable {
|
||||
}
|
||||
|
||||
/** A run-time method. */
|
||||
class RuntimeMethod extends RuntimeCallable {
|
||||
RuntimeMethod() {
|
||||
this instanceof Method or
|
||||
this instanceof CIL::Method
|
||||
}
|
||||
|
||||
/** Holds if the method is `static`. */
|
||||
predicate isStatic() { this.(Method).isStatic() or this.(CIL::Method).isStatic() }
|
||||
}
|
||||
class RuntimeMethod extends RuntimeCallable, Method { }
|
||||
|
||||
/** A run-time instance method. */
|
||||
class RuntimeInstanceMethod extends RuntimeMethod {
|
||||
|
||||
@@ -8,7 +8,6 @@ import Expr
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon
|
||||
private import semmle.code.csharp.dispatch.Dispatch
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A call. Either a method call (`MethodCall`), a constructor initializer call
|
||||
@@ -16,7 +15,7 @@ private import dotnet
|
||||
* a delegate call (`DelegateCall`), an accessor call (`AccessorCall`), a
|
||||
* constructor call (`ObjectCreation`), or a local function call (`LocalFunctionCall`).
|
||||
*/
|
||||
class Call extends DotNet::Call, Expr, @call {
|
||||
class Call extends Expr, @call {
|
||||
/**
|
||||
* Gets the static (compile-time) target of this call. For example, the
|
||||
* static target of `x.M()` on line 9 is `A.M` in
|
||||
@@ -38,13 +37,19 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
* Use `getARuntimeTarget()` instead to get a potential run-time target (will
|
||||
* include `B.M` in the example above).
|
||||
*/
|
||||
override Callable getTarget() { none() }
|
||||
Callable getTarget() { none() }
|
||||
|
||||
override Expr getArgument(int i) { result = this.getChild(i) and i >= 0 }
|
||||
/** Gets the `i`th argument to this call, if any. */
|
||||
Expr getArgument(int i) { result = this.getChild(i) and i >= 0 }
|
||||
|
||||
override Expr getRawArgument(int i) { result = this.getArgument(i) }
|
||||
/**
|
||||
* Gets the `i`th "raw" argument to this call, if any.
|
||||
* For instance methods, argument 0 is the qualifier.
|
||||
*/
|
||||
Expr getRawArgument(int i) { result = this.getArgument(i) }
|
||||
|
||||
override Expr getAnArgument() { result = this.getArgument(_) }
|
||||
/** Gets an argument to this call. */
|
||||
Expr getAnArgument() { result = this.getArgument(_) }
|
||||
|
||||
/** Gets the number of arguments of this call. */
|
||||
int getNumberOfArguments() { result = count(this.getAnArgument()) }
|
||||
@@ -59,7 +64,7 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
* consider default arguments.
|
||||
*/
|
||||
cached
|
||||
override Expr getArgumentForParameter(DotNet::Parameter p) {
|
||||
Expr getArgumentForParameter(Parameter p) {
|
||||
// Appears in the positional part of the call
|
||||
result = this.getImplicitArgument(p)
|
||||
or
|
||||
@@ -69,7 +74,7 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Expr getImplicitArgument(DotNet::Parameter p) {
|
||||
private Expr getImplicitArgument(Parameter p) {
|
||||
this.getTarget().getAParameter() = p and
|
||||
not exists(result.getExplicitArgumentName()) and
|
||||
(
|
||||
@@ -144,7 +149,7 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
* - Line 16: There is no static target (delegate call) but the delegate `i => { }`
|
||||
* (line 20) is a run-time target.
|
||||
*/
|
||||
override Callable getARuntimeTarget() {
|
||||
Callable getARuntimeTarget() {
|
||||
exists(DispatchCall dc | dc.getCall() = this | result = dc.getADynamicTarget())
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import semmle.code.csharp.controlflow.ControlFlowElement
|
||||
import semmle.code.csharp.Location
|
||||
import semmle.code.csharp.Stmt
|
||||
import semmle.code.csharp.Type
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import semmle.code.csharp.frameworks.System
|
||||
private import semmle.code.csharp.TypeRef
|
||||
@@ -38,11 +37,11 @@ private import semmle.code.csharp.TypeRef
|
||||
* interpolated string (`InterpolatedStringExpr`), a qualifiable expression
|
||||
* (`QualifiableExpr`), or a literal (`Literal`).
|
||||
*/
|
||||
class Expr extends DotNet::Expr, ControlFlowElement, @expr {
|
||||
class Expr extends ControlFlowElement, @expr {
|
||||
override Location getALocation() { expr_location(this, result) }
|
||||
|
||||
/** Gets the type of this expression. */
|
||||
override Type getType() {
|
||||
Type getType() {
|
||||
expressions(this, _, result)
|
||||
or
|
||||
not expressions(this, _, any(Type t)) and
|
||||
@@ -53,7 +52,10 @@ class Expr extends DotNet::Expr, ControlFlowElement, @expr {
|
||||
final AnnotatedType getAnnotatedType() { result.appliesTo(this) }
|
||||
|
||||
/** Gets the value of this expression, if any */
|
||||
override string getValue() { expr_value(this, result) }
|
||||
string getValue() { expr_value(this, result) }
|
||||
|
||||
/** Holds if this expression has a value. */
|
||||
final predicate hasValue() { exists(this.getValue()) }
|
||||
|
||||
/** Gets the enclosing statement of this expression, if any. */
|
||||
final Stmt getEnclosingStmt() { enclosingStmt(this, result) }
|
||||
@@ -88,6 +90,10 @@ class Expr extends DotNet::Expr, ControlFlowElement, @expr {
|
||||
*/
|
||||
string getExplicitArgumentName() { expr_argument_name(this, result) }
|
||||
|
||||
/**
|
||||
* Gets the parent of this expression. This is for example the element
|
||||
* that uses the result of this expression.
|
||||
*/
|
||||
override Element getParent() { result = ControlFlowElement.super.getParent() }
|
||||
|
||||
/** Holds if the nullable flow state of this expression is not null. */
|
||||
@@ -943,13 +949,13 @@ class InterpolatedStringExpr extends Expr, @interpolated_string_expr {
|
||||
* A `throw` element. Either a `throw` expression (`ThrowExpr`)
|
||||
* or a `throw` statement (`ThrowStmt`).
|
||||
*/
|
||||
class ThrowElement extends ControlFlowElement, DotNet::Throw, @throw_element {
|
||||
class ThrowElement extends ControlFlowElement, @throw_element {
|
||||
/**
|
||||
* Gets the expression of the exception being thrown, if any.
|
||||
*
|
||||
* For example, `new Exception("Syntax error")` in `throw new Exception("Syntax error");`.
|
||||
*/
|
||||
override Expr getExpr() { result = this.getChild(0) }
|
||||
Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
/** Gets the type of exception being thrown. */
|
||||
Class getThrownExceptionType() {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
import Expr
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A literal. Either a Boolean literal (`BoolLiteral`), a Unicode character
|
||||
@@ -13,7 +12,7 @@ private import dotnet
|
||||
* point literal (`RealLiteral`), a `string` literal (`StringLiteral`), or a
|
||||
* `null` literal (`NullLiteral`).
|
||||
*/
|
||||
class Literal extends DotNet::Literal, Expr, @literal_expr {
|
||||
class Literal extends Expr, @literal_expr {
|
||||
override string toString() { result = this.getValue() }
|
||||
}
|
||||
|
||||
@@ -43,7 +42,7 @@ class CharLiteral extends Literal, @char_literal_expr {
|
||||
* literal (`LongLiteral`), a `uint` literal (`UIntLiteral`), or a `ulong`
|
||||
* literal (`ULongLiteral`).
|
||||
*/
|
||||
class IntegerLiteral extends DotNet::IntLiteral, Literal, @integer_literal_expr { }
|
||||
class IntegerLiteral extends Literal, @integer_literal_expr { }
|
||||
|
||||
/**
|
||||
* An `int` literal, for example `0`.
|
||||
@@ -105,7 +104,7 @@ class DecimalLiteral extends RealLiteral, @decimal_literal_expr {
|
||||
* A `string` literal. Either a `string` literal (`StringLiteralUtf16`),
|
||||
* or a `u8` literal (`StringLiteralUtf8`).
|
||||
*/
|
||||
class StringLiteral extends DotNet::StringLiteral, Literal, @string_literal_expr {
|
||||
class StringLiteral extends Literal, @string_literal_expr {
|
||||
override string toString() { result = "\"" + this.getValue().replaceAll("\"", "\\\"") + "\"" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "StringLiteral" }
|
||||
@@ -128,6 +127,6 @@ class StringLiteralUtf8 extends StringLiteral, @utf8_string_literal_expr {
|
||||
/**
|
||||
* A `null` literal.
|
||||
*/
|
||||
class NullLiteral extends DotNet::NullLiteral, Literal, @null_literal_expr {
|
||||
class NullLiteral extends Literal, @null_literal_expr {
|
||||
override string getAPrimaryQlClass() { result = "NullLiteral" }
|
||||
}
|
||||
|
||||
@@ -68,8 +68,6 @@ deprecated class RemoteSource extends DataFlow::Node instanceof RemoteFlowSource
|
||||
*/
|
||||
deprecated class LocalSource extends DataFlow::Node instanceof LocalFlowSource { }
|
||||
|
||||
private class AddLocalSource extends Source instanceof LocalFlowSource { }
|
||||
|
||||
/** A source supported by the current threat model. */
|
||||
class ThreatModelSource extends Source instanceof ThreatModelFlowSource { }
|
||||
|
||||
|
||||
@@ -67,8 +67,6 @@ deprecated class RemoteSource extends DataFlow::Node instanceof RemoteFlowSource
|
||||
*/
|
||||
deprecated class LocalSource extends DataFlow::Node instanceof LocalFlowSource { }
|
||||
|
||||
private class AddLocalSource extends Source instanceof LocalFlowSource { }
|
||||
|
||||
/** A source supported by the current threat model. */
|
||||
class ThreatModelSource extends Source instanceof ThreatModelFlowSource { }
|
||||
|
||||
|
||||
@@ -78,8 +78,6 @@ deprecated class RemoteSource extends DataFlow::Node instanceof RemoteFlowSource
|
||||
*/
|
||||
deprecated class LocalSource extends DataFlow::Node instanceof LocalFlowSource { }
|
||||
|
||||
private class AddLocalSource extends Source instanceof LocalFlowSource { }
|
||||
|
||||
/** A source supported by the current threat model. */
|
||||
class ThreatModelSource extends Source instanceof ThreatModelFlowSource { }
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import csharp
|
||||
private import semmle.code.csharp.frameworks.system.windows.Forms
|
||||
private import semmle.code.csharp.dataflow.internal.ExternalFlow
|
||||
private import semmle.code.csharp.security.dataflow.flowsources.FlowSources
|
||||
private import semmle.code.csharp.commons.Util
|
||||
|
||||
/** A data flow source of local data. */
|
||||
abstract class LocalFlowSource extends SourceNode {
|
||||
@@ -29,3 +30,28 @@ class TextFieldSource extends LocalUserInputSource {
|
||||
|
||||
override string getSourceType() { result = "TextBox text" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A dataflow source that represents the access of an environment variable.
|
||||
*/
|
||||
abstract class EnvironmentVariableSource extends LocalFlowSource {
|
||||
override string getThreatModel() { result = "environment" }
|
||||
|
||||
override string getSourceType() { result = "environment variable" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A dataflow source that represents the access of a command line argument.
|
||||
*/
|
||||
abstract class CommandLineArgumentSource extends LocalFlowSource {
|
||||
override string getThreatModel() { result = "commandargs" }
|
||||
|
||||
override string getSourceType() { result = "command line argument" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow source that represents the parameters of the `Main` method of a program.
|
||||
*/
|
||||
private class MainMethodArgumentSource extends CommandLineArgumentSource {
|
||||
MainMethodArgumentSource() { this.asParameter() = any(MainMethod mainMethod).getAParameter() }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import Expr
|
||||
import Parameterizable
|
||||
|
||||
/** A .Net callable. */
|
||||
class Callable extends Parameterizable, @dotnet_callable {
|
||||
deprecated class Callable extends Parameterizable, @dotnet_callable {
|
||||
/** Holds if this callable has a body or an implementation. */
|
||||
predicate hasBody() { none() }
|
||||
|
||||
@@ -85,13 +85,13 @@ class Callable extends Parameterizable, @dotnet_callable {
|
||||
}
|
||||
|
||||
/** A constructor. */
|
||||
abstract class Constructor extends Callable { }
|
||||
abstract deprecated class Constructor extends Callable { }
|
||||
|
||||
/** A destructor/finalizer. */
|
||||
abstract class Destructor extends Callable { }
|
||||
abstract deprecated class Destructor extends Callable { }
|
||||
|
||||
pragma[nomagic]
|
||||
private ValueOrRefType getARecordBaseType(ValueOrRefType t) {
|
||||
deprecated private ValueOrRefType getARecordBaseType(ValueOrRefType t) {
|
||||
exists(Callable c |
|
||||
c.hasName("<Clone>$") and
|
||||
c.getNumberOfParameters() = 0 and
|
||||
@@ -103,7 +103,7 @@ private ValueOrRefType getARecordBaseType(ValueOrRefType t) {
|
||||
}
|
||||
|
||||
/** A clone method on a record. */
|
||||
class RecordCloneCallable extends Callable {
|
||||
deprecated class RecordCloneCallable extends Callable {
|
||||
RecordCloneCallable() {
|
||||
this.getDeclaringType() instanceof ValueOrRefType and
|
||||
this.hasName("<Clone>$") and
|
||||
|
||||
@@ -7,7 +7,7 @@ import Type
|
||||
private import semmle.code.csharp.commons.QualifiedName
|
||||
|
||||
/** A declaration. */
|
||||
class Declaration extends NamedElement, @dotnet_declaration {
|
||||
deprecated class Declaration extends NamedElement, @dotnet_declaration {
|
||||
/** Gets the name of this declaration, without additional decoration such as `<...>`. */
|
||||
string getUndecoratedName() { none() }
|
||||
|
||||
@@ -50,7 +50,7 @@ class Declaration extends NamedElement, @dotnet_declaration {
|
||||
}
|
||||
|
||||
/** A member of a type. */
|
||||
class Member extends Declaration, @dotnet_member {
|
||||
deprecated class Member extends Declaration, @dotnet_member {
|
||||
/** Holds if this member is declared `public`. */
|
||||
predicate isPublic() { none() }
|
||||
|
||||
@@ -102,7 +102,7 @@ class Member extends Declaration, @dotnet_member {
|
||||
}
|
||||
|
||||
/** A property. */
|
||||
class Property extends Member, @dotnet_property {
|
||||
deprecated class Property extends Member, @dotnet_property {
|
||||
/** Gets the getter of this property, if any. */
|
||||
Callable getGetter() { none() }
|
||||
|
||||
@@ -114,7 +114,7 @@ class Property extends Member, @dotnet_property {
|
||||
}
|
||||
|
||||
/** An event. */
|
||||
class Event extends Member, @dotnet_event {
|
||||
deprecated class Event extends Member, @dotnet_event {
|
||||
/** Gets the adder of this event, if any. */
|
||||
Callable getAdder() { none() }
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import semmle.code.csharp.Location
|
||||
/**
|
||||
* A .Net program element.
|
||||
*/
|
||||
class Element extends @dotnet_element {
|
||||
deprecated class Element extends @dotnet_element {
|
||||
/** Gets a textual representation of this element. */
|
||||
cached
|
||||
string toString() { none() }
|
||||
@@ -69,7 +69,7 @@ class Element extends @dotnet_element {
|
||||
}
|
||||
|
||||
/** An element that has a name. */
|
||||
class NamedElement extends Element, @dotnet_named_element {
|
||||
deprecated class NamedElement extends Element, @dotnet_named_element {
|
||||
/** Gets the name of this element. */
|
||||
cached
|
||||
string getName() { none() }
|
||||
|
||||
@@ -7,7 +7,7 @@ import Type
|
||||
import Callable
|
||||
|
||||
/** An expression. */
|
||||
class Expr extends Element, @dotnet_expr {
|
||||
deprecated class Expr extends Element, @dotnet_expr {
|
||||
/** Gets the callable containing this expression. */
|
||||
Callable getEnclosingCallable() { none() }
|
||||
|
||||
@@ -28,7 +28,7 @@ class Expr extends Element, @dotnet_expr {
|
||||
}
|
||||
|
||||
/** A call. */
|
||||
class Call extends Expr, @dotnet_call {
|
||||
deprecated class Call extends Expr, @dotnet_call {
|
||||
/** Gets the target of this call. */
|
||||
Callable getTarget() { none() }
|
||||
|
||||
@@ -52,13 +52,13 @@ class Call extends Expr, @dotnet_call {
|
||||
}
|
||||
|
||||
/** A literal expression. */
|
||||
class Literal extends Expr, @dotnet_literal { }
|
||||
deprecated class Literal extends Expr, @dotnet_literal { }
|
||||
|
||||
/** A string literal expression. */
|
||||
class StringLiteral extends Literal, @dotnet_string_literal { }
|
||||
deprecated class StringLiteral extends Literal, @dotnet_string_literal { }
|
||||
|
||||
/** An integer literal expression. */
|
||||
class IntLiteral extends Literal, @dotnet_int_literal { }
|
||||
deprecated class IntLiteral extends Literal, @dotnet_int_literal { }
|
||||
|
||||
/** A `null` literal expression. */
|
||||
class NullLiteral extends Literal, @dotnet_null_literal { }
|
||||
deprecated class NullLiteral extends Literal, @dotnet_null_literal { }
|
||||
|
||||
@@ -6,10 +6,10 @@ import Declaration
|
||||
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a
|
||||
* constructed generic (`ConstructedGeneric`).
|
||||
*/
|
||||
abstract class Generic extends Declaration, @dotnet_generic { }
|
||||
abstract deprecated class Generic extends Declaration, @dotnet_generic { }
|
||||
|
||||
/** An unbound generic. */
|
||||
abstract class UnboundGeneric extends Generic {
|
||||
abstract deprecated class UnboundGeneric extends Generic {
|
||||
/** Gets the `i`th type parameter, if any. */
|
||||
abstract TypeParameter getTypeParameter(int i);
|
||||
|
||||
@@ -27,7 +27,7 @@ abstract class UnboundGeneric extends Generic {
|
||||
}
|
||||
|
||||
/** A constructed generic. */
|
||||
abstract class ConstructedGeneric extends Generic {
|
||||
abstract deprecated class ConstructedGeneric extends Generic {
|
||||
/** Gets the `i`th type argument, if any. */
|
||||
abstract Type getTypeArgument(int i);
|
||||
|
||||
@@ -49,20 +49,20 @@ abstract class ConstructedGeneric extends Generic {
|
||||
*
|
||||
* Constructs the label suffix for a generic method or type.
|
||||
*/
|
||||
string getGenericsLabel(Generic g) {
|
||||
deprecated string getGenericsLabel(Generic g) {
|
||||
result = "`" + g.(UnboundGeneric).getNumberOfTypeParameters()
|
||||
or
|
||||
result = "<" + typeArgs(g) + ">"
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private string getTypeArgumentLabel(ConstructedGeneric generic, int p) {
|
||||
deprecated private string getTypeArgumentLabel(ConstructedGeneric generic, int p) {
|
||||
result = generic.getTypeArgument(p).getLabel()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
pragma[nomagic]
|
||||
private string typeArgs(ConstructedGeneric generic) {
|
||||
deprecated private string typeArgs(ConstructedGeneric generic) {
|
||||
result =
|
||||
concat(int p |
|
||||
p in [0 .. generic.getNumberOfTypeArguments() - 1]
|
||||
|
||||
@@ -6,7 +6,7 @@ private import Declaration
|
||||
private import semmle.code.csharp.commons.QualifiedName
|
||||
|
||||
/** A namespace. */
|
||||
class Namespace extends Declaration, @namespace {
|
||||
deprecated class Namespace extends Declaration, @namespace {
|
||||
/**
|
||||
* Gets the parent namespace, if any. For example the parent namespace of `System.IO`
|
||||
* is `System`. The parent namespace of `System` is the global namespace.
|
||||
@@ -64,6 +64,6 @@ class Namespace extends Declaration, @namespace {
|
||||
}
|
||||
|
||||
/** The global namespace. */
|
||||
class GlobalNamespace extends Namespace {
|
||||
deprecated class GlobalNamespace extends Namespace {
|
||||
GlobalNamespace() { this.getName() = "" }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import Declaration
|
||||
* A general parameterizable entity, such as a callable, delegate type, accessor,
|
||||
* indexer, or function pointer type.
|
||||
*/
|
||||
class Parameterizable extends Declaration, @dotnet_parameterizable {
|
||||
deprecated class Parameterizable extends Declaration, @dotnet_parameterizable {
|
||||
/** Gets raw parameter `i`, including the `this` parameter at index 0. */
|
||||
Parameter getRawParameter(int i) { none() }
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user