Skip to content

Commit 469d09c

Browse files
committed
Merge branch 'main' into redsun82/just2
2 parents 9d52a08 + 5c0300c commit 469d09c

File tree

470 files changed

+8881
-3691
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

470 files changed

+8881
-3691
lines changed

.bazelrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ common --registry=https://bcr.bazel.build
3030

3131
common --@rules_dotnet//dotnet/settings:strict_deps=false
3232

33+
# we only configure a nightly toolchain
34+
common --@rules_rust//rust/toolchain/channel=nightly
35+
36+
# rust does not like the gold linker, while bazel does by default, so let's avoid using it
37+
common:linux --linkopt=-fuse-ld=lld
38+
common:macos --linkopt=-fuse-ld=lld
39+
3340
# Reduce this eventually to empty, once we've fixed all our usages of java, and https://github.com/bazel-contrib/rules_go/issues/4193 is fixed
3441
common --incompatible_autoload_externally="+@rules_java,+@rules_shell"
3542

MODULE.bazel

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ local_path_override(
1515
# see https://registry.bazel.build/ for a list of available packages
1616

1717
bazel_dep(name = "platforms", version = "0.0.11")
18-
bazel_dep(name = "rules_go", version = "0.50.1")
18+
bazel_dep(name = "rules_go", version = "0.56.1")
1919
bazel_dep(name = "rules_pkg", version = "1.0.1")
2020
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
2121
bazel_dep(name = "rules_python", version = "0.40.0")
@@ -28,7 +28,7 @@ bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1")
2828
bazel_dep(name = "gazelle", version = "0.40.0")
2929
bazel_dep(name = "rules_dotnet", version = "0.17.4")
3030
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
31-
bazel_dep(name = "rules_rust", version = "0.58.0")
31+
bazel_dep(name = "rules_rust", version = "0.63.0")
3232
bazel_dep(name = "zstd", version = "1.5.5.bcr.1")
3333

3434
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
@@ -38,7 +38,10 @@ bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True
3838
RUST_EDITION = "2024"
3939

4040
# run buildutils-internal/scripts/fill-rust-sha256s.py when updating (internal repo)
41-
RUST_VERSION = "1.86.0"
41+
# a nightly toolchain is required to enable experimental_use_cc_common_link, which we require internally
42+
# we prefer to run the same version as internally, even if experimental_use_cc_common_link is not really
43+
# required in this repo
44+
RUST_VERSION = "nightly/2025-08-01"
4245

4346
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
4447
rust.toolchain(
@@ -50,26 +53,26 @@ rust.toolchain(
5053
],
5154
# generated by buildutils-internal/scripts/fill-rust-sha256s.py (internal repo)
5255
sha256s = {
53-
"rustc-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "4438b809ce4a083af31ed17aeeedcc8fc60ccffc0625bef1926620751b6989d7",
54-
"rustc-1.86.0-x86_64-apple-darwin.tar.xz": "42b76253626febb7912541a30d3379f463dec89581aad4cb72c6c04fb5a71dc5",
55-
"rustc-1.86.0-aarch64-apple-darwin.tar.xz": "23b8f52102249a47ab5bc859d54c9a3cb588a3259ba3f00f557d50edeca4fde9",
56-
"rustc-1.86.0-x86_64-pc-windows-msvc.tar.xz": "fdde839fea274529a31e51eb85c6df1782cc8479c9d1bc24e2914d66a0de41ab",
57-
"clippy-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "02aaff2c1407d2da8dba19aa4970dd873e311902b120a66cbcdbe51eb8836edf",
58-
"clippy-1.86.0-x86_64-apple-darwin.tar.xz": "bb85efda7bbffaf124867f5ca36d50932b1e8f533c62ee923438afb32ff8fe9a",
59-
"clippy-1.86.0-aarch64-apple-darwin.tar.xz": "239fa3a604b124f0312f2af08537874a1227dba63385484b468cca62e7c4f2f2",
60-
"clippy-1.86.0-x86_64-pc-windows-msvc.tar.xz": "d00498f47d49219f032e2c5eeebdfc3d32317c0dc3d3fd7125327445bc482cb4",
61-
"cargo-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "c5c1590f7e9246ad9f4f97cfe26ffa92707b52a769726596a9ef81565ebd908b",
62-
"cargo-1.86.0-x86_64-apple-darwin.tar.xz": "af163eb02d1a178044d1b4f2375960efd47130f795f6e33d09e345454bb26f4e",
63-
"cargo-1.86.0-aarch64-apple-darwin.tar.xz": "3cb13873d48c3e1e4cc684d42c245226a11fba52af6b047c3346ed654e7a05c0",
64-
"cargo-1.86.0-x86_64-pc-windows-msvc.tar.xz": "e57a9d89619b5604899bac443e68927bdd371e40f2e03e18950b6ceb3eb67966",
65-
"llvm-tools-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "282145ab7a63c98b625856f44b905b4dc726b497246b824632a5790debe95a78",
66-
"llvm-tools-1.86.0-x86_64-apple-darwin.tar.xz": "b55706e92f7da989207c50c13c7add483a9fedd233bc431b106eca2a8f151ec9",
67-
"llvm-tools-1.86.0-aarch64-apple-darwin.tar.xz": "04d3618c686845853585f036e3211eb9e18f2d290f4610a7a78bdc1fcce1ebd9",
68-
"llvm-tools-1.86.0-x86_64-pc-windows-msvc.tar.xz": "721a17cc8dc219177e4277a3592253934ef08daa1e1b12eda669a67d15fad8dd",
69-
"rust-std-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "67be7184ea388d8ce0feaf7fdea46f1775cfc2970930264343b3089898501d37",
70-
"rust-std-1.86.0-x86_64-apple-darwin.tar.xz": "3b1140d54870a080080e84700143f4a342fbd02a410a319b05d9c02e7dcf44cc",
71-
"rust-std-1.86.0-aarch64-apple-darwin.tar.xz": "0fb121fb3b8fa9027d79ff598500a7e5cd086ddbc3557482ed3fdda00832c61b",
72-
"rust-std-1.86.0-x86_64-pc-windows-msvc.tar.xz": "3d5354b7b9cb950b58bff3fce18a652aa374bb30c8f70caebd3bd0b43cb41a33",
56+
"2025-08-01/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "9bbeaf5d3fc7247d31463a9083aa251c995cc50662c8219e7a2254d76a72a9a4",
57+
"2025-08-01/rustc-nightly-x86_64-apple-darwin.tar.xz": "c9ea539a8eff0d5d162701f99f9e1aabe14dd0dfb420d62362817a5d09219de7",
58+
"2025-08-01/rustc-nightly-aarch64-apple-darwin.tar.xz": "ae83feebbc39cfd982e4ecc8297731fe79c185173aee138467b334c5404b3773",
59+
"2025-08-01/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "9f170c30d802a349be60cf52ec46260802093cb1013ad667fc0d528b7b10152f",
60+
"2025-08-01/clippy-nightly-x86_64-unknown-linux-gnu.tar.xz": "9ae5f3cd8f557c4f6df522597c69d14398cf604cfaed2b83e767c4b77a7eaaf6",
61+
"2025-08-01/clippy-nightly-x86_64-apple-darwin.tar.xz": "983cb9ee0b6b968188e04ab2d33743d54764b2681ce565e1b3f2b9135c696a3e",
62+
"2025-08-01/clippy-nightly-aarch64-apple-darwin.tar.xz": "ed2219dbc49d088225e1b7c5c4390fa295066e071fddaa2714018f6bb39ddbf0",
63+
"2025-08-01/clippy-nightly-x86_64-pc-windows-msvc.tar.xz": "911f40ab5cbdd686f40e00965271fe47c4805513a308ed01f30eafb25b448a50",
64+
"2025-08-01/cargo-nightly-x86_64-unknown-linux-gnu.tar.xz": "106463c284e48e4904c717471eeec2be5cc83a9d2cae8d6e948b52438cad2e69",
65+
"2025-08-01/cargo-nightly-x86_64-apple-darwin.tar.xz": "6ad35c40efc41a8c531ea43235058347b6902d98a9693bf0aed7fc16d5590cef",
66+
"2025-08-01/cargo-nightly-aarch64-apple-darwin.tar.xz": "dd28c365e9d298abc3154c797720ad36a0058f131265c9978b4c8e4e37012c8a",
67+
"2025-08-01/cargo-nightly-x86_64-pc-windows-msvc.tar.xz": "7b431286e12d6b3834b038f078389a00cac73f351e8c3152b2504a3c06420b3b",
68+
"2025-08-01/llvm-tools-nightly-x86_64-unknown-linux-gnu.tar.xz": "e342e305d7927cc288d386983b2bc253cfad3776b113386e903d0b302648ef47",
69+
"2025-08-01/llvm-tools-nightly-x86_64-apple-darwin.tar.xz": "e44dd3506524d85c37b3a54bcc91d01378fd2c590b2db5c5974d12f05c1b84d1",
70+
"2025-08-01/llvm-tools-nightly-aarch64-apple-darwin.tar.xz": "0c1b5f46dd81be4a9227b10283a0fcaa39c14fea7e81aea6fd6d9887ff6cdc41",
71+
"2025-08-01/llvm-tools-nightly-x86_64-pc-windows-msvc.tar.xz": "423e5fd11406adccbc31b8456ceb7375ce055cdf45e90d2c3babeb2d7f58383f",
72+
"2025-08-01/rust-std-nightly-x86_64-unknown-linux-gnu.tar.xz": "3c0ceb46a252647a1d4c7116d9ccae684fa5e42aaf3296419febd2c962c3b41d",
73+
"2025-08-01/rust-std-nightly-x86_64-apple-darwin.tar.xz": "3be416003cab10f767390a753d1d16ae4d26c7421c03c98992cf1943e5b0efe8",
74+
"2025-08-01/rust-std-nightly-aarch64-apple-darwin.tar.xz": "4046ac0ef951cb056b5028a399124f60999fa37792eab69d008d8d7965f389b4",
75+
"2025-08-01/rust-std-nightly-x86_64-pc-windows-msvc.tar.xz": "191ed9d8603c3a4fe5a7bbbc2feb72049078dae2df3d3b7d5dedf3abbf823e6e",
7376
},
7477
versions = [RUST_VERSION],
7578
)
@@ -260,7 +263,7 @@ use_repo(
260263
)
261264

262265
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
263-
go_sdk.download(version = "1.24.0")
266+
go_sdk.download(version = "1.25.0")
264267

265268
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
266269
go_deps.from_file(go_mod = "//go/extractor:go.mod")
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The guards libraries (`semmle.code.cpp.controlflow.Guards` and `semmle.code.cpp.controlflow.IRGuards`) have been improved to recognize more guards.

cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

Lines changed: 112 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,77 @@ private module Cached {
936936
ValueNumber getUnary() { result.getAnInstruction() = instr.getUnary() }
937937
}
938938

939+
signature predicate sinkSig(Instruction instr);
940+
941+
private module BooleanInstruction<sinkSig/1 isSink> {
942+
/**
943+
* Holds if `i1` flows to `i2` in a single step and `i2` is not an
944+
* instruction that produces a value of Boolean type.
945+
*/
946+
private predicate stepToNonBoolean(Instruction i1, Instruction i2) {
947+
not i2.getResultIRType() instanceof IRBooleanType and
948+
(
949+
i2.(CopyInstruction).getSourceValue() = i1
950+
or
951+
i2.(ConvertInstruction).getUnary() = i1
952+
or
953+
i2.(BuiltinExpectCallInstruction).getArgument(0) = i1
954+
)
955+
}
956+
957+
private predicate rev(Instruction instr) {
958+
isSink(instr)
959+
or
960+
exists(Instruction instr1 |
961+
rev(instr1) and
962+
stepToNonBoolean(instr, instr1)
963+
)
964+
}
965+
966+
private predicate hasBooleanType(Instruction instr) {
967+
instr.getResultIRType() instanceof IRBooleanType
968+
}
969+
970+
private predicate fwd(Instruction instr) {
971+
rev(instr) and
972+
(
973+
hasBooleanType(instr)
974+
or
975+
exists(Instruction instr0 |
976+
fwd(instr0) and
977+
stepToNonBoolean(instr0, instr)
978+
)
979+
)
980+
}
981+
982+
private predicate prunedStep(Instruction i1, Instruction i2) {
983+
fwd(i1) and
984+
fwd(i2) and
985+
stepToNonBoolean(i1, i2)
986+
}
987+
988+
private predicate stepsPlus(Instruction i1, Instruction i2) =
989+
doublyBoundedFastTC(prunedStep/2, hasBooleanType/1, isSink/1)(i1, i2)
990+
991+
/**
992+
* Gets the Boolean-typed instruction that defines `instr` before any
993+
* integer conversions are applied, if any.
994+
*/
995+
Instruction get(Instruction instr) {
996+
isSink(instr) and
997+
(
998+
result = instr
999+
or
1000+
stepsPlus(result, instr)
1001+
) and
1002+
hasBooleanType(result)
1003+
}
1004+
}
1005+
1006+
private predicate isUnaryComparesEqLeft(Instruction instr) {
1007+
unary_compares_eq(_, instr.getAUse(), 0, _, _)
1008+
}
1009+
9391010
/**
9401011
* Holds if `left == right + k` is `areEqual` given that test is `testIsTrue`.
9411012
*
@@ -966,14 +1037,19 @@ private module Cached {
9661037
)
9671038
or
9681039
compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), left, right, k, areEqual, value)
969-
}
970-
971-
private predicate isConvertedBool(Instruction instr) {
972-
instr.getResultIRType() instanceof IRBooleanType
973-
or
974-
isConvertedBool(instr.(ConvertInstruction).getUnary())
9751040
or
976-
isConvertedBool(instr.(BuiltinExpectCallInstruction).getCondition())
1041+
exists(Operand l, BooleanValue bv |
1042+
// 1. test = value -> int(l) = 0 is !bv
1043+
unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and
1044+
// 2. l = bv -> left + right is areEqual
1045+
compares_eq(valueNumber(BooleanInstruction<isUnaryComparesEqLeft/1>::get(l.getDef())), left,
1046+
right, k, areEqual, bv)
1047+
// We want this to hold:
1048+
// `test = value -> left + right is areEqual`
1049+
// Applying 2 we need to show:
1050+
// `test = value -> l = bv`
1051+
// And `l = bv` holds by `int(l) = 0 is !bv`
1052+
)
9771053
}
9781054

9791055
/**
@@ -1006,19 +1082,11 @@ private module Cached {
10061082
k = k1 + k2
10071083
)
10081084
or
1009-
exists(CompareValueNumber cmp, Operand left, Operand right, AbstractValue v |
1010-
test = cmp and
1011-
pragma[only_bind_into](cmp)
1012-
.hasOperands(pragma[only_bind_into](left), pragma[only_bind_into](right)) and
1013-
isConvertedBool(left.getDef()) and
1014-
int_value(right.getDef()) = 0 and
1015-
unary_compares_eq(valueNumberOfOperand(left), op, k, areEqual, v)
1016-
|
1017-
cmp instanceof CompareNEValueNumber and
1018-
v = value
1019-
or
1020-
cmp instanceof CompareEQValueNumber and
1021-
v.getDualValue() = value
1085+
// See argument for why this is correct in compares_eq
1086+
exists(Operand l, BooleanValue bv |
1087+
unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and
1088+
unary_compares_eq(valueNumber(BooleanInstruction<isUnaryComparesEqLeft/1>::get(l.getDef())),
1089+
op, k, areEqual, bv)
10221090
)
10231091
or
10241092
unary_compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, areEqual, value)
@@ -1116,70 +1184,26 @@ private module Cached {
11161184
)
11171185
}
11181186

1187+
private predicate isBuiltInExpectArg(Instruction instr) {
1188+
instr = any(BuiltinExpectCallInstruction buildinExpect).getArgument(0)
1189+
}
1190+
11191191
/** A call to the builtin operation `__builtin_expect`. */
11201192
private class BuiltinExpectCallInstruction extends CallInstruction {
11211193
BuiltinExpectCallInstruction() { this.getStaticCallTarget().hasName("__builtin_expect") }
11221194

11231195
/** Gets the condition of this call. */
1124-
Instruction getCondition() { result = this.getConditionOperand().getDef() }
1125-
1126-
Operand getConditionOperand() {
1127-
// The first parameter of `__builtin_expect` has type `long`. So we skip
1128-
// the conversion when inferring guards.
1129-
result = this.getArgument(0).(ConvertInstruction).getUnaryOperand()
1196+
Instruction getCondition() {
1197+
result = BooleanInstruction<isBuiltInExpectArg/1>::get(this.getArgument(0))
11301198
}
11311199
}
11321200

1133-
/**
1134-
* Holds if `left == right + k` is `areEqual` if `cmp` evaluates to `value`,
1135-
* and `cmp` is an instruction that compares the value of
1136-
* `__builtin_expect(left == right + k, _)` to `0`.
1137-
*/
1138-
private predicate builtin_expect_eq(
1139-
CompareValueNumber cmp, Operand left, Operand right, int k, boolean areEqual,
1140-
AbstractValue value
1141-
) {
1142-
exists(BuiltinExpectCallValueNumber call, Instruction const, AbstractValue innerValue |
1143-
int_value(const) = 0 and
1144-
cmp.hasOperands(call.getAUse(), const.getAUse()) and
1145-
compares_eq(call.getCondition(), left, right, k, areEqual, innerValue)
1146-
|
1147-
cmp instanceof CompareNEValueNumber and
1148-
value = innerValue
1149-
or
1150-
cmp instanceof CompareEQValueNumber and
1151-
value.getDualValue() = innerValue
1152-
)
1153-
}
1154-
11551201
private predicate complex_eq(
11561202
ValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, AbstractValue value
11571203
) {
11581204
sub_eq(cmp, left, right, k, areEqual, value)
11591205
or
11601206
add_eq(cmp, left, right, k, areEqual, value)
1161-
or
1162-
builtin_expect_eq(cmp, left, right, k, areEqual, value)
1163-
}
1164-
1165-
/**
1166-
* Holds if `op == k` is `areEqual` if `cmp` evaluates to `value`, and `cmp` is
1167-
* an instruction that compares the value of `__builtin_expect(op == k, _)` to `0`.
1168-
*/
1169-
private predicate unary_builtin_expect_eq(
1170-
CompareValueNumber cmp, Operand op, int k, boolean areEqual, AbstractValue value
1171-
) {
1172-
exists(BuiltinExpectCallValueNumber call, Instruction const, AbstractValue innerValue |
1173-
int_value(const) = 0 and
1174-
cmp.hasOperands(call.getAUse(), const.getAUse()) and
1175-
unary_compares_eq(call.getCondition(), op, k, areEqual, innerValue)
1176-
|
1177-
cmp instanceof CompareNEValueNumber and
1178-
value = innerValue
1179-
or
1180-
cmp instanceof CompareEQValueNumber and
1181-
value.getDualValue() = innerValue
1182-
)
11831207
}
11841208

11851209
private predicate unary_complex_eq(
@@ -1188,8 +1212,6 @@ private module Cached {
11881212
unary_sub_eq(test, op, k, areEqual, value)
11891213
or
11901214
unary_add_eq(test, op, k, areEqual, value)
1191-
or
1192-
unary_builtin_expect_eq(test, op, k, areEqual, value)
11931215
}
11941216

11951217
/*
@@ -1215,6 +1237,15 @@ private module Cached {
12151237
exists(AbstractValue dual | value = dual.getDualValue() |
12161238
compares_lt(test.(LogicalNotValueNumber).getUnary(), left, right, k, isLt, dual)
12171239
)
1240+
or
1241+
compares_lt(test.(BuiltinExpectCallValueNumber).getCondition(), left, right, k, isLt, value)
1242+
or
1243+
// See argument for why this is correct in compares_eq
1244+
exists(Operand l, BooleanValue bv |
1245+
unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and
1246+
compares_lt(valueNumber(BooleanInstruction<isUnaryComparesEqLeft/1>::get(l.getDef())), left,
1247+
right, k, isLt, bv)
1248+
)
12181249
}
12191250

12201251
/** Holds if `op < k` evaluates to `isLt` given that `test` evaluates to `value`. */
@@ -1234,6 +1265,15 @@ private module Cached {
12341265
int_value(const) = k1 and
12351266
k = k1 + k2
12361267
)
1268+
or
1269+
compares_lt(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, isLt, value)
1270+
or
1271+
// See argument for why this is correct in compares_eq
1272+
exists(Operand l, BooleanValue bv |
1273+
unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and
1274+
compares_lt(valueNumber(BooleanInstruction<isUnaryComparesEqLeft/1>::get(l.getDef())), op, k,
1275+
isLt, bv)
1276+
)
12371277
}
12381278

12391279
/** `(a < b + k) => (b > a - k) => (b >= a + (1-k))` */

cpp/ql/test/library-tests/controlflow/guards/Guards.expected

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
| test.c:198:8:198:8 | b |
4545
| test.c:206:7:206:8 | ! ... |
4646
| test.c:206:8:206:8 | c |
47+
| test.c:215:6:215:18 | call to __builtin_expect |
48+
| test.c:219:9:219:22 | call to __builtin_expect |
4749
| test.cpp:18:8:18:10 | call to get |
4850
| test.cpp:31:7:31:13 | ... == ... |
4951
| test.cpp:42:13:42:20 | call to getABool |
@@ -92,3 +94,15 @@
9294
| test.cpp:241:9:241:43 | ... && ... |
9395
| test.cpp:241:22:241:30 | ... == ... |
9496
| test.cpp:241:35:241:43 | ... == ... |
97+
| test.cpp:247:6:247:18 | ... == ... |
98+
| test.cpp:253:6:253:18 | ... != ... |
99+
| test.cpp:260:6:260:18 | ... == ... |
100+
| test.cpp:266:6:266:18 | ... != ... |
101+
| test.cpp:273:6:273:17 | ... == ... |
102+
| test.cpp:279:6:279:17 | ... != ... |
103+
| test.cpp:287:6:287:19 | ... == ... |
104+
| test.cpp:293:6:293:19 | ... != ... |
105+
| test.cpp:300:6:300:19 | ... == ... |
106+
| test.cpp:306:6:306:19 | ... != ... |
107+
| test.cpp:312:6:312:18 | ... == ... |
108+
| test.cpp:318:6:318:18 | ... != ... |

0 commit comments

Comments
 (0)