diff --git a/.bazelrc b/.bazelrc index 449345bfb629..54a510f05dc6 100644 --- a/.bazelrc +++ b/.bazelrc @@ -30,6 +30,13 @@ common --registry=https://bcr.bazel.build common --@rules_dotnet//dotnet/settings:strict_deps=false +# we only configure a nightly toolchain +common --@rules_rust//rust/toolchain/channel=nightly + +# rust does not like the gold linker, while bazel does by default, so let's avoid using it +common:linux --linkopt=-fuse-ld=lld +common:macos --linkopt=-fuse-ld=lld + # 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 common --incompatible_autoload_externally="+@rules_java,+@rules_shell" diff --git a/MODULE.bazel b/MODULE.bazel index 474e6df0aba8..52c07a395b5e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -15,7 +15,7 @@ local_path_override( # see https://registry.bazel.build/ for a list of available packages bazel_dep(name = "platforms", version = "0.0.11") -bazel_dep(name = "rules_go", version = "0.50.1") +bazel_dep(name = "rules_go", version = "0.56.1") bazel_dep(name = "rules_pkg", version = "1.0.1") bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1") bazel_dep(name = "rules_python", version = "0.40.0") @@ -28,7 +28,7 @@ bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1") bazel_dep(name = "gazelle", version = "0.40.0") bazel_dep(name = "rules_dotnet", version = "0.17.4") bazel_dep(name = "googletest", version = "1.14.0.bcr.1") -bazel_dep(name = "rules_rust", version = "0.58.0") +bazel_dep(name = "rules_rust", version = "0.63.0") bazel_dep(name = "zstd", version = "1.5.5.bcr.1") 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 RUST_EDITION = "2024" # run buildutils-internal/scripts/fill-rust-sha256s.py when updating (internal repo) -RUST_VERSION = "1.86.0" +# a nightly toolchain is required to enable experimental_use_cc_common_link, which we require internally +# we prefer to run the same version as internally, even if experimental_use_cc_common_link is not really +# required in this repo +RUST_VERSION = "nightly/2025-08-01" rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") rust.toolchain( @@ -50,26 +53,26 @@ rust.toolchain( ], # generated by buildutils-internal/scripts/fill-rust-sha256s.py (internal repo) sha256s = { - "rustc-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "4438b809ce4a083af31ed17aeeedcc8fc60ccffc0625bef1926620751b6989d7", - "rustc-1.86.0-x86_64-apple-darwin.tar.xz": "42b76253626febb7912541a30d3379f463dec89581aad4cb72c6c04fb5a71dc5", - "rustc-1.86.0-aarch64-apple-darwin.tar.xz": "23b8f52102249a47ab5bc859d54c9a3cb588a3259ba3f00f557d50edeca4fde9", - "rustc-1.86.0-x86_64-pc-windows-msvc.tar.xz": "fdde839fea274529a31e51eb85c6df1782cc8479c9d1bc24e2914d66a0de41ab", - "clippy-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "02aaff2c1407d2da8dba19aa4970dd873e311902b120a66cbcdbe51eb8836edf", - "clippy-1.86.0-x86_64-apple-darwin.tar.xz": "bb85efda7bbffaf124867f5ca36d50932b1e8f533c62ee923438afb32ff8fe9a", - "clippy-1.86.0-aarch64-apple-darwin.tar.xz": "239fa3a604b124f0312f2af08537874a1227dba63385484b468cca62e7c4f2f2", - "clippy-1.86.0-x86_64-pc-windows-msvc.tar.xz": "d00498f47d49219f032e2c5eeebdfc3d32317c0dc3d3fd7125327445bc482cb4", - "cargo-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "c5c1590f7e9246ad9f4f97cfe26ffa92707b52a769726596a9ef81565ebd908b", - "cargo-1.86.0-x86_64-apple-darwin.tar.xz": "af163eb02d1a178044d1b4f2375960efd47130f795f6e33d09e345454bb26f4e", - "cargo-1.86.0-aarch64-apple-darwin.tar.xz": "3cb13873d48c3e1e4cc684d42c245226a11fba52af6b047c3346ed654e7a05c0", - "cargo-1.86.0-x86_64-pc-windows-msvc.tar.xz": "e57a9d89619b5604899bac443e68927bdd371e40f2e03e18950b6ceb3eb67966", - "llvm-tools-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "282145ab7a63c98b625856f44b905b4dc726b497246b824632a5790debe95a78", - "llvm-tools-1.86.0-x86_64-apple-darwin.tar.xz": "b55706e92f7da989207c50c13c7add483a9fedd233bc431b106eca2a8f151ec9", - "llvm-tools-1.86.0-aarch64-apple-darwin.tar.xz": "04d3618c686845853585f036e3211eb9e18f2d290f4610a7a78bdc1fcce1ebd9", - "llvm-tools-1.86.0-x86_64-pc-windows-msvc.tar.xz": "721a17cc8dc219177e4277a3592253934ef08daa1e1b12eda669a67d15fad8dd", - "rust-std-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "67be7184ea388d8ce0feaf7fdea46f1775cfc2970930264343b3089898501d37", - "rust-std-1.86.0-x86_64-apple-darwin.tar.xz": "3b1140d54870a080080e84700143f4a342fbd02a410a319b05d9c02e7dcf44cc", - "rust-std-1.86.0-aarch64-apple-darwin.tar.xz": "0fb121fb3b8fa9027d79ff598500a7e5cd086ddbc3557482ed3fdda00832c61b", - "rust-std-1.86.0-x86_64-pc-windows-msvc.tar.xz": "3d5354b7b9cb950b58bff3fce18a652aa374bb30c8f70caebd3bd0b43cb41a33", + "2025-08-01/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "9bbeaf5d3fc7247d31463a9083aa251c995cc50662c8219e7a2254d76a72a9a4", + "2025-08-01/rustc-nightly-x86_64-apple-darwin.tar.xz": "c9ea539a8eff0d5d162701f99f9e1aabe14dd0dfb420d62362817a5d09219de7", + "2025-08-01/rustc-nightly-aarch64-apple-darwin.tar.xz": "ae83feebbc39cfd982e4ecc8297731fe79c185173aee138467b334c5404b3773", + "2025-08-01/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "9f170c30d802a349be60cf52ec46260802093cb1013ad667fc0d528b7b10152f", + "2025-08-01/clippy-nightly-x86_64-unknown-linux-gnu.tar.xz": "9ae5f3cd8f557c4f6df522597c69d14398cf604cfaed2b83e767c4b77a7eaaf6", + "2025-08-01/clippy-nightly-x86_64-apple-darwin.tar.xz": "983cb9ee0b6b968188e04ab2d33743d54764b2681ce565e1b3f2b9135c696a3e", + "2025-08-01/clippy-nightly-aarch64-apple-darwin.tar.xz": "ed2219dbc49d088225e1b7c5c4390fa295066e071fddaa2714018f6bb39ddbf0", + "2025-08-01/clippy-nightly-x86_64-pc-windows-msvc.tar.xz": "911f40ab5cbdd686f40e00965271fe47c4805513a308ed01f30eafb25b448a50", + "2025-08-01/cargo-nightly-x86_64-unknown-linux-gnu.tar.xz": "106463c284e48e4904c717471eeec2be5cc83a9d2cae8d6e948b52438cad2e69", + "2025-08-01/cargo-nightly-x86_64-apple-darwin.tar.xz": "6ad35c40efc41a8c531ea43235058347b6902d98a9693bf0aed7fc16d5590cef", + "2025-08-01/cargo-nightly-aarch64-apple-darwin.tar.xz": "dd28c365e9d298abc3154c797720ad36a0058f131265c9978b4c8e4e37012c8a", + "2025-08-01/cargo-nightly-x86_64-pc-windows-msvc.tar.xz": "7b431286e12d6b3834b038f078389a00cac73f351e8c3152b2504a3c06420b3b", + "2025-08-01/llvm-tools-nightly-x86_64-unknown-linux-gnu.tar.xz": "e342e305d7927cc288d386983b2bc253cfad3776b113386e903d0b302648ef47", + "2025-08-01/llvm-tools-nightly-x86_64-apple-darwin.tar.xz": "e44dd3506524d85c37b3a54bcc91d01378fd2c590b2db5c5974d12f05c1b84d1", + "2025-08-01/llvm-tools-nightly-aarch64-apple-darwin.tar.xz": "0c1b5f46dd81be4a9227b10283a0fcaa39c14fea7e81aea6fd6d9887ff6cdc41", + "2025-08-01/llvm-tools-nightly-x86_64-pc-windows-msvc.tar.xz": "423e5fd11406adccbc31b8456ceb7375ce055cdf45e90d2c3babeb2d7f58383f", + "2025-08-01/rust-std-nightly-x86_64-unknown-linux-gnu.tar.xz": "3c0ceb46a252647a1d4c7116d9ccae684fa5e42aaf3296419febd2c962c3b41d", + "2025-08-01/rust-std-nightly-x86_64-apple-darwin.tar.xz": "3be416003cab10f767390a753d1d16ae4d26c7421c03c98992cf1943e5b0efe8", + "2025-08-01/rust-std-nightly-aarch64-apple-darwin.tar.xz": "4046ac0ef951cb056b5028a399124f60999fa37792eab69d008d8d7965f389b4", + "2025-08-01/rust-std-nightly-x86_64-pc-windows-msvc.tar.xz": "191ed9d8603c3a4fe5a7bbbc2feb72049078dae2df3d3b7d5dedf3abbf823e6e", }, versions = [RUST_VERSION], ) @@ -230,6 +233,7 @@ use_repo( "kotlin-compiler-2.1.0-Beta1", "kotlin-compiler-2.1.20-Beta1", "kotlin-compiler-2.2.0-Beta1", + "kotlin-compiler-2.2.20-Beta2", "kotlin-compiler-embeddable-1.6.0", "kotlin-compiler-embeddable-1.6.20", "kotlin-compiler-embeddable-1.7.0", @@ -242,6 +246,7 @@ use_repo( "kotlin-compiler-embeddable-2.1.0-Beta1", "kotlin-compiler-embeddable-2.1.20-Beta1", "kotlin-compiler-embeddable-2.2.0-Beta1", + "kotlin-compiler-embeddable-2.2.20-Beta2", "kotlin-stdlib-1.6.0", "kotlin-stdlib-1.6.20", "kotlin-stdlib-1.7.0", @@ -254,10 +259,11 @@ use_repo( "kotlin-stdlib-2.1.0-Beta1", "kotlin-stdlib-2.1.20-Beta1", "kotlin-stdlib-2.2.0-Beta1", + "kotlin-stdlib-2.2.20-Beta2", ) go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") -go_sdk.download(version = "1.24.0") +go_sdk.download(version = "1.25.0") go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//go/extractor:go.mod") diff --git a/actions/ql/lib/CHANGELOG.md b/actions/ql/lib/CHANGELOG.md index a3bde634d393..dffad0539b0e 100644 --- a/actions/ql/lib/CHANGELOG.md +++ b/actions/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.14 + +No user-facing changes. + ## 0.4.13 ### Bug Fixes diff --git a/actions/ql/lib/change-notes/released/0.4.14.md b/actions/ql/lib/change-notes/released/0.4.14.md new file mode 100644 index 000000000000..09e581963738 --- /dev/null +++ b/actions/ql/lib/change-notes/released/0.4.14.md @@ -0,0 +1,3 @@ +## 0.4.14 + +No user-facing changes. diff --git a/actions/ql/lib/codeql-pack.release.yml b/actions/ql/lib/codeql-pack.release.yml index 88ad5ab8f224..3841668fe04e 100644 --- a/actions/ql/lib/codeql-pack.release.yml +++ b/actions/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.13 +lastReleaseVersion: 0.4.14 diff --git a/actions/ql/lib/codeql/actions/security/ArgumentInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/ArgumentInjectionQuery.qll index 1d461cca3df2..679b8977cf91 100644 --- a/actions/ql/lib/codeql/actions/security/ArgumentInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/ArgumentInjectionQuery.qll @@ -1,6 +1,7 @@ private import actions private import codeql.actions.TaintTracking private import codeql.actions.dataflow.ExternalFlow +private import codeql.actions.security.ControlChecks import codeql.actions.dataflow.FlowSources import codeql.actions.DataFlow @@ -65,6 +66,16 @@ class ArgumentInjectionFromMaDSink extends ArgumentInjectionSink { override string getCommand() { result = "unknown" } } +/** + * Gets the event that is relevant for the given node in the context of argument injection. + * + * This is used to highlight the event in the query results when an alert is raised. + */ +Event getRelevantEventInPrivilegedContext(DataFlow::Node node) { + inPrivilegedContext(node.asExpr(), result) and + not exists(ControlCheck check | check.protects(node.asExpr(), result, "argument-injection")) +} + /** * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate a code script. @@ -88,6 +99,16 @@ private module ArgumentInjectionConfig implements DataFlow::ConfigSig { run.getScript().getAnEnvReachingArgumentInjectionSink(var, _, _) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + result = getRelevantEventInPrivilegedContext(sink).getLocation() + } } /** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */ diff --git a/actions/ql/lib/codeql/actions/security/ArtifactPoisoningQuery.qll b/actions/ql/lib/codeql/actions/security/ArtifactPoisoningQuery.qll index f0649bb8174e..76025a9ba0db 100644 --- a/actions/ql/lib/codeql/actions/security/ArtifactPoisoningQuery.qll +++ b/actions/ql/lib/codeql/actions/security/ArtifactPoisoningQuery.qll @@ -4,6 +4,7 @@ import codeql.actions.DataFlow import codeql.actions.dataflow.FlowSources import codeql.actions.security.PoisonableSteps import codeql.actions.security.UntrustedCheckoutQuery +import codeql.actions.security.ControlChecks string unzipRegexp() { result = "(unzip|tar)\\s+.*" } @@ -292,6 +293,16 @@ class ArtifactPoisoningSink extends DataFlow::Node { string getPath() { result = download.getPath() } } +/** + * Gets the event that is relevant for the given node in the context of artifact poisoning. + * + * This is used to highlight the event in the query results when an alert is raised. + */ +Event getRelevantEventInPrivilegedContext(DataFlow::Node node) { + inPrivilegedContext(node.asExpr(), result) and + not exists(ControlCheck check | check.protects(node.asExpr(), result, "artifact-poisoning")) +} + /** * A taint-tracking configuration for unsafe artifacts * that is used may lead to artifact poisoning @@ -318,6 +329,16 @@ private module ArtifactPoisoningConfig implements DataFlow::ConfigSig { exists(run.getScript().getAFileReadCommand()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + result = getRelevantEventInPrivilegedContext(sink).getLocation() + } } /** Tracks flow of unsafe artifacts that is used in an insecure way. */ diff --git a/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll index fac498f72dab..c58e3949a024 100644 --- a/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll @@ -3,6 +3,8 @@ private import codeql.actions.TaintTracking private import codeql.actions.dataflow.ExternalFlow import codeql.actions.dataflow.FlowSources import codeql.actions.DataFlow +import codeql.actions.security.ControlChecks +import codeql.actions.security.CachePoisoningQuery class CodeInjectionSink extends DataFlow::Node { CodeInjectionSink() { @@ -11,6 +13,46 @@ class CodeInjectionSink extends DataFlow::Node { } } +/** + * Get the relevant event for the sink in CodeInjectionCritical.ql. + */ +Event getRelevantCriticalEventForSink(DataFlow::Node sink) { + inPrivilegedContext(sink.asExpr(), result) and + not exists(ControlCheck check | check.protects(sink.asExpr(), result, "code-injection")) and + // exclude cases where the sink is a JS script and the expression uses toJson + not exists(UsesStep script | + script.getCallee() = "actions/github-script" and + script.getArgumentExpr("script") = sink.asExpr() and + exists(getAToJsonReferenceExpression(sink.asExpr().(Expression).getExpression(), _)) + ) +} + +/** + * Get the relevant event for the sink in CachePoisoningViaCodeInjection.ql. + */ +Event getRelevantCachePoisoningEventForSink(DataFlow::Node sink) { + exists(LocalJob job | + job = sink.asExpr().getEnclosingJob() and + job.getATriggerEvent() = result and + // job can be triggered by an external user + result.isExternallyTriggerable() and + // excluding privileged workflows since they can be exploited in easier circumstances + // which is covered by `actions/code-injection/critical` + not job.isPrivilegedExternallyTriggerable(result) and + ( + // the workflow runs in the context of the default branch + runsOnDefaultBranch(result) + or + // the workflow caller runs in the context of the default branch + result.getName() = "workflow_call" and + exists(ExternalJob caller | + caller.getCallee() = job.getLocation().getFile().getRelativePath() and + runsOnDefaultBranch(caller.getATriggerEvent()) + ) + ) + ) +} + /** * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate a code script. @@ -35,6 +77,18 @@ private module CodeInjectionConfig implements DataFlow::ConfigSig { exists(run.getScript().getAFileReadCommand()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + result = getRelevantCriticalEventForSink(sink).getLocation() + or + result = getRelevantCachePoisoningEventForSink(sink).getLocation() + } } /** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */ diff --git a/actions/ql/lib/codeql/actions/security/CommandInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/CommandInjectionQuery.qll index 59d523cd5827..ffa16b0f9406 100644 --- a/actions/ql/lib/codeql/actions/security/CommandInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/CommandInjectionQuery.qll @@ -3,11 +3,20 @@ private import codeql.actions.TaintTracking private import codeql.actions.dataflow.ExternalFlow import codeql.actions.dataflow.FlowSources import codeql.actions.DataFlow +import codeql.actions.security.ControlChecks private class CommandInjectionSink extends DataFlow::Node { CommandInjectionSink() { madSink(this, "command-injection") } } +/** Get the relevant event for the sink in CommandInjectionCritical.ql. */ +Event getRelevantEventInPrivilegedContext(DataFlow::Node sink) { + inPrivilegedContext(sink.asExpr(), result) and + not exists(ControlCheck check | + check.protects(sink.asExpr(), result, ["command-injection", "code-injection"]) + ) +} + /** * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate a system command. @@ -16,6 +25,16 @@ private module CommandInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof CommandInjectionSink } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + result = getRelevantEventInPrivilegedContext(sink).getLocation() + } } /** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */ diff --git a/actions/ql/lib/codeql/actions/security/EnvPathInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/EnvPathInjectionQuery.qll index 33efc9b1bc8f..46c1c4d32006 100644 --- a/actions/ql/lib/codeql/actions/security/EnvPathInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/EnvPathInjectionQuery.qll @@ -72,6 +72,25 @@ class EnvPathInjectionFromMaDSink extends EnvPathInjectionSink { EnvPathInjectionFromMaDSink() { madSink(this, "envpath-injection") } } +/** + * Get the relevant event for a sink in EnvPathInjectionCritical.ql where the source type is "artifact". + */ +Event getRelevantArtifactEventInPrivilegedContext(DataFlow::Node sink) { + inPrivilegedContext(sink.asExpr(), result) and + not exists(ControlCheck check | + check.protects(sink.asExpr(), result, ["untrusted-checkout", "artifact-poisoning"]) + ) and + sink instanceof EnvPathInjectionFromFileReadSink +} + +/** + * Get the relevant event for a sink in EnvPathInjectionCritical.ql where the source type is not "artifact". + */ +Event getRelevantNonArtifactEventInPrivilegedContext(DataFlow::Node sink) { + inPrivilegedContext(sink.asExpr(), result) and + not exists(ControlCheck check | check.protects(sink.asExpr(), result, "code-injection")) +} + /** * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate an environment variable. @@ -108,6 +127,18 @@ private module EnvPathInjectionConfig implements DataFlow::ConfigSig { exists(run.getScript().getAFileReadCommand()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + result = getRelevantArtifactEventInPrivilegedContext(sink).getLocation() + or + result = getRelevantNonArtifactEventInPrivilegedContext(sink).getLocation() + } } /** Tracks flow of unsafe user input that is used to construct and evaluate the PATH environment variable. */ diff --git a/actions/ql/lib/codeql/actions/security/EnvVarInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/EnvVarInjectionQuery.qll index 656ea1207b51..2022e3dca998 100644 --- a/actions/ql/lib/codeql/actions/security/EnvVarInjectionQuery.qll +++ b/actions/ql/lib/codeql/actions/security/EnvVarInjectionQuery.qll @@ -126,6 +126,32 @@ class EnvVarInjectionFromMaDSink extends EnvVarInjectionSink { EnvVarInjectionFromMaDSink() { madSink(this, "envvar-injection") } } +/** + * Get the relevant event for a sink in EnvVarInjectionCritical.ql where the source type is "artifact". + */ +Event getRelevantArtifactEventInPrivilegedContext(DataFlow::Node sink) { + inPrivilegedContext(sink.asExpr(), result) and + not exists(ControlCheck check | + check + .protects(sink.asExpr(), result, + ["envvar-injection", "untrusted-checkout", "artifact-poisoning"]) + ) and + ( + sink instanceof EnvVarInjectionFromFileReadSink or + madSink(sink, "envvar-injection") + ) +} + +/** + * Get the relevant event for a sink in EnvVarInjectionCritical.ql where the source type is not "artifact". + */ +Event getRelevantNonArtifactEventInPrivilegedContext(DataFlow::Node sink) { + inPrivilegedContext(sink.asExpr(), result) and + not exists(ControlCheck check | + check.protects(sink.asExpr(), result, ["envvar-injection", "code-injection"]) + ) +} + /** * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate an environment variable. @@ -163,6 +189,18 @@ private module EnvVarInjectionConfig implements DataFlow::ConfigSig { exists(run.getScript().getAFileReadCommand()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + result = getRelevantArtifactEventInPrivilegedContext(sink).getLocation() + or + result = getRelevantNonArtifactEventInPrivilegedContext(sink).getLocation() + } } /** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */ diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml index f67a9ff9142f..dd2723b03157 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.13 +version: 0.4.15-dev library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/CHANGELOG.md b/actions/ql/src/CHANGELOG.md index d0db2aff304d..09fb20778fcf 100644 --- a/actions/ql/src/CHANGELOG.md +++ b/actions/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.6 + +No user-facing changes. + ## 0.6.5 No user-facing changes. diff --git a/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql b/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql index 3e6d63a4604d..30bb0fd366fb 100644 --- a/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql +++ b/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql @@ -21,18 +21,12 @@ import codeql.actions.security.ControlChecks from EnvPathInjectionFlow::PathNode source, EnvPathInjectionFlow::PathNode sink, Event event where EnvPathInjectionFlow::flowPath(source, sink) and - inPrivilegedContext(sink.getNode().asExpr(), event) and ( not source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and - not exists(ControlCheck check | - check.protects(sink.getNode().asExpr(), event, "code-injection") - ) + event = getRelevantNonArtifactEventInPrivilegedContext(sink.getNode()) or source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and - not exists(ControlCheck check | - check.protects(sink.getNode().asExpr(), event, ["untrusted-checkout", "artifact-poisoning"]) - ) and - sink.getNode() instanceof EnvPathInjectionFromFileReadSink + event = getRelevantArtifactEventInPrivilegedContext(sink.getNode()) ) select sink.getNode(), source, sink, "Potential PATH environment variable injection in $@, which may be controlled by an external user ($@).", diff --git a/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql b/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql index 28ad3b5b5d28..6f0d9729d6d3 100644 --- a/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql +++ b/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql @@ -22,26 +22,15 @@ import codeql.actions.security.ControlChecks from EnvVarInjectionFlow::PathNode source, EnvVarInjectionFlow::PathNode sink, Event event where EnvVarInjectionFlow::flowPath(source, sink) and - inPrivilegedContext(sink.getNode().asExpr(), event) and // exclude paths to file read sinks from non-artifact sources ( // source is text not source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and - not exists(ControlCheck check | - check.protects(sink.getNode().asExpr(), event, ["envvar-injection", "code-injection"]) - ) + event = getRelevantNonArtifactEventInPrivilegedContext(sink.getNode()) or // source is an artifact or a file from an untrusted checkout source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and - not exists(ControlCheck check | - check - .protects(sink.getNode().asExpr(), event, - ["envvar-injection", "untrusted-checkout", "artifact-poisoning"]) - ) and - ( - sink.getNode() instanceof EnvVarInjectionFromFileReadSink or - madSink(sink.getNode(), "envvar-injection") - ) + event = getRelevantArtifactEventInPrivilegedContext(sink.getNode()) ) select sink.getNode(), source, sink, "Potential environment variable injection in $@, which may be controlled by an external user ($@).", diff --git a/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql b/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql index c4ab00837ca7..ed30e4da71c8 100644 --- a/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql +++ b/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql @@ -22,15 +22,8 @@ import codeql.actions.security.ControlChecks from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Event event where CodeInjectionFlow::flowPath(source, sink) and - inPrivilegedContext(sink.getNode().asExpr(), event) and - source.getNode().(RemoteFlowSource).getEventName() = event.getName() and - not exists(ControlCheck check | check.protects(sink.getNode().asExpr(), event, "code-injection")) and - // exclude cases where the sink is a JS script and the expression uses toJson - not exists(UsesStep script | - script.getCallee() = "actions/github-script" and - script.getArgumentExpr("script") = sink.getNode().asExpr() and - exists(getAToJsonReferenceExpression(sink.getNode().asExpr().(Expression).getExpression(), _)) - ) + event = getRelevantCriticalEventForSink(sink.getNode()) and + source.getNode().(RemoteFlowSource).getEventName() = event.getName() select sink.getNode(), source, sink, "Potential code injection in $@, which may be controlled by an external user ($@).", sink, sink.getNode().asExpr().(Expression).getRawExpression(), event, event.getName() diff --git a/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql b/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql index 23e1f223073f..2fe792aba1e6 100644 --- a/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql +++ b/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql @@ -18,30 +18,13 @@ import codeql.actions.security.CachePoisoningQuery import CodeInjectionFlow::PathGraph import codeql.actions.security.ControlChecks -from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, LocalJob job, Event event +from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Event event where CodeInjectionFlow::flowPath(source, sink) and - job = sink.getNode().asExpr().getEnclosingJob() and - job.getATriggerEvent() = event and - // job can be triggered by an external user - event.isExternallyTriggerable() and + event = getRelevantCachePoisoningEventForSink(sink.getNode()) and // the checkout is not controlled by an access check not exists(ControlCheck check | check.protects(source.getNode().asExpr(), event, "code-injection") - ) and - // excluding privileged workflows since they can be exploited in easier circumstances - // which is covered by `actions/code-injection/critical` - not job.isPrivilegedExternallyTriggerable(event) and - ( - // the workflow runs in the context of the default branch - runsOnDefaultBranch(event) - or - // the workflow caller runs in the context of the default branch - event.getName() = "workflow_call" and - exists(ExternalJob caller | - caller.getCallee() = job.getLocation().getFile().getRelativePath() and - runsOnDefaultBranch(caller.getATriggerEvent()) - ) ) select sink.getNode(), source, sink, "Unprivileged code injection in $@, which may lead to cache poisoning ($@).", sink, diff --git a/actions/ql/src/Security/CWE-829/ArtifactPoisoningCritical.ql b/actions/ql/src/Security/CWE-829/ArtifactPoisoningCritical.ql index afef7bdd82b2..24ecb4b03397 100644 --- a/actions/ql/src/Security/CWE-829/ArtifactPoisoningCritical.ql +++ b/actions/ql/src/Security/CWE-829/ArtifactPoisoningCritical.ql @@ -19,10 +19,7 @@ import codeql.actions.security.ControlChecks from ArtifactPoisoningFlow::PathNode source, ArtifactPoisoningFlow::PathNode sink, Event event where ArtifactPoisoningFlow::flowPath(source, sink) and - inPrivilegedContext(sink.getNode().asExpr(), event) and - not exists(ControlCheck check | - check.protects(sink.getNode().asExpr(), event, "artifact-poisoning") - ) + event = getRelevantEventInPrivilegedContext(sink.getNode()) select sink.getNode(), source, sink, "Potential artifact poisoning in $@, which may be controlled by an external user ($@).", sink, sink.getNode().toString(), event, event.getName() diff --git a/actions/ql/src/Security/CWE-829/UntrustedCheckoutCritical.md b/actions/ql/src/Security/CWE-829/UntrustedCheckoutCritical.md index 50e81cc240ca..de3307550ad2 100644 --- a/actions/ql/src/Security/CWE-829/UntrustedCheckoutCritical.md +++ b/actions/ql/src/Security/CWE-829/UntrustedCheckoutCritical.md @@ -1,6 +1,6 @@ ## Overview -GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed in a privileged job. +GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job. ## Recommendation @@ -32,7 +32,7 @@ jobs: - uses: actions/setup-node@v1 - run: | - npm install + npm install # scripts in package.json from PR would be executed here npm build - uses: completely/fakeaction@v2 diff --git a/actions/ql/src/Security/CWE-829/UntrustedCheckoutHigh.md b/actions/ql/src/Security/CWE-829/UntrustedCheckoutHigh.md index 50e81cc240ca..de3307550ad2 100644 --- a/actions/ql/src/Security/CWE-829/UntrustedCheckoutHigh.md +++ b/actions/ql/src/Security/CWE-829/UntrustedCheckoutHigh.md @@ -1,6 +1,6 @@ ## Overview -GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed in a privileged job. +GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job. ## Recommendation @@ -32,7 +32,7 @@ jobs: - uses: actions/setup-node@v1 - run: | - npm install + npm install # scripts in package.json from PR would be executed here npm build - uses: completely/fakeaction@v2 diff --git a/actions/ql/src/Security/CWE-829/UntrustedCheckoutMedium.md b/actions/ql/src/Security/CWE-829/UntrustedCheckoutMedium.md index 50e81cc240ca..de3307550ad2 100644 --- a/actions/ql/src/Security/CWE-829/UntrustedCheckoutMedium.md +++ b/actions/ql/src/Security/CWE-829/UntrustedCheckoutMedium.md @@ -1,6 +1,6 @@ ## Overview -GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed in a privileged job. +GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job. ## Recommendation @@ -32,7 +32,7 @@ jobs: - uses: actions/setup-node@v1 - run: | - npm install + npm install # scripts in package.json from PR would be executed here npm build - uses: completely/fakeaction@v2 diff --git a/actions/ql/src/change-notes/released/0.6.6.md b/actions/ql/src/change-notes/released/0.6.6.md new file mode 100644 index 000000000000..ab10d897be1d --- /dev/null +++ b/actions/ql/src/change-notes/released/0.6.6.md @@ -0,0 +1,3 @@ +## 0.6.6 + +No user-facing changes. diff --git a/actions/ql/src/codeql-pack.release.yml b/actions/ql/src/codeql-pack.release.yml index 86780fb61480..f4cae0a77ada 100644 --- a/actions/ql/src/codeql-pack.release.yml +++ b/actions/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.5 +lastReleaseVersion: 0.6.6 diff --git a/actions/ql/src/experimental/Security/CWE-078/CommandInjectionCritical.ql b/actions/ql/src/experimental/Security/CWE-078/CommandInjectionCritical.ql index 7d45b25b1a29..2ed98d714dab 100644 --- a/actions/ql/src/experimental/Security/CWE-078/CommandInjectionCritical.ql +++ b/actions/ql/src/experimental/Security/CWE-078/CommandInjectionCritical.ql @@ -21,10 +21,7 @@ import codeql.actions.security.ControlChecks from CommandInjectionFlow::PathNode source, CommandInjectionFlow::PathNode sink, Event event where CommandInjectionFlow::flowPath(source, sink) and - inPrivilegedContext(sink.getNode().asExpr(), event) and - not exists(ControlCheck check | - check.protects(sink.getNode().asExpr(), event, ["command-injection", "code-injection"]) - ) + event = getRelevantEventInPrivilegedContext(sink.getNode()) select sink.getNode(), source, sink, "Potential command injection in $@, which may be controlled by an external user ($@).", sink, sink.getNode().asExpr().(Expression).getRawExpression(), event, event.getName() diff --git a/actions/ql/src/experimental/Security/CWE-088/ArgumentInjectionCritical.ql b/actions/ql/src/experimental/Security/CWE-088/ArgumentInjectionCritical.ql index 6930e2f684a4..ecab01dd114d 100644 --- a/actions/ql/src/experimental/Security/CWE-088/ArgumentInjectionCritical.ql +++ b/actions/ql/src/experimental/Security/CWE-088/ArgumentInjectionCritical.ql @@ -20,10 +20,7 @@ import codeql.actions.security.ControlChecks from ArgumentInjectionFlow::PathNode source, ArgumentInjectionFlow::PathNode sink, Event event where ArgumentInjectionFlow::flowPath(source, sink) and - inPrivilegedContext(sink.getNode().asExpr(), event) and - not exists(ControlCheck check | - check.protects(sink.getNode().asExpr(), event, "argument-injection") - ) + event = getRelevantEventInPrivilegedContext(sink.getNode()) select sink.getNode(), source, sink, "Potential argument injection in $@ command, which may be controlled by an external user ($@).", sink, sink.getNode().(ArgumentInjectionSink).getCommand(), event, event.getName() diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index 7addbb8de912..911d1e191682 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.5 +version: 0.6.7-dev library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 1b9acfd9e539..def048bdd3c3 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 5.4.0 + +### New Features + +* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory. + +### Minor Analysis Improvements + +* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives. + ## 5.3.0 ### Deprecated APIs diff --git a/cpp/ql/lib/change-notes/2025-08-02-gvn.md b/cpp/ql/lib/change-notes/2025-08-02-gvn.md new file mode 100644 index 000000000000..70c9f7dbb158 --- /dev/null +++ b/cpp/ql/lib/change-notes/2025-08-02-gvn.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The global value numbering library (`semmle.code.cpp.valuenumbering.GlobalValueNumbering` and `semmle.code.cpp.ir.ValueNumbering`) has been improved so more expressions are assigned the same value number. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2025-08-11-global-variable-flow.md b/cpp/ql/lib/change-notes/2025-08-11-global-variable-flow.md new file mode 100644 index 000000000000..c140570df314 --- /dev/null +++ b/cpp/ql/lib/change-notes/2025-08-11-global-variable-flow.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Improved dataflow through global variables in the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`). Queries based on these libraries will produce more results on codebases with many global variables. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2025-08-13-guards.md b/cpp/ql/lib/change-notes/2025-08-13-guards.md new file mode 100644 index 000000000000..4181a6cbeb26 --- /dev/null +++ b/cpp/ql/lib/change-notes/2025-08-13-guards.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The guards libraries (`semmle.code.cpp.controlflow.Guards` and `semmle.code.cpp.controlflow.IRGuards`) have been improved to recognize more guards. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/released/5.4.0.md b/cpp/ql/lib/change-notes/released/5.4.0.md new file mode 100644 index 000000000000..8c8cea5440c6 --- /dev/null +++ b/cpp/ql/lib/change-notes/released/5.4.0.md @@ -0,0 +1,9 @@ +## 5.4.0 + +### New Features + +* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory. + +### Minor Analysis Improvements + +* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index b0a1c83e5bc9..afb2156eaa2b 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.3.0 +lastReleaseVersion: 5.4.0 diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml index 9df7c16850f8..ccebfc9f3401 100644 --- a/cpp/ql/lib/ext/Windows.model.yml +++ b/cpp/ql/lib/ext/Windows.model.yml @@ -36,4 +36,14 @@ extensions: # processthreadsapi.h - ["", "", False, "CreateThread", "", "", "Argument[@3]", "Argument[2].Parameter[@0]", "value", "manual"] - ["", "", False, "CreateRemoteThread", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"] - - ["", "", False, "CreateRemoteThreadEx", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"] \ No newline at end of file + - ["", "", False, "CreateRemoteThreadEx", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"] + # wdm.h + - ["", "", False, "RtlCopyVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"] + - ["", "", False, "RtlCopyDeviceMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"] + - ["", "", False, "RtlCopyMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"] + - ["", "", False, "RtlCopyMemoryNonTemporal", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"] + - ["", "", False, "RtlCopyUnicodeString", "", "", "Argument[*1].Field[*Buffer]", "Argument[*0].Field[*Buffer]", "value", "manual"] + - ["", "", False, "RtlMoveMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"] + - ["", "", False, "RtlMoveVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"] + # winternl.h + - ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"] \ No newline at end of file diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 3d9c75672cb8..7c1fb8aad1cc 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 5.3.0 +version: 5.4.1-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll b/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll index 565c15d0d5c9..675090ad9584 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll @@ -57,6 +57,18 @@ private Class getRootType(FieldAccess fa) { ) } +/** + * Gets the size of `v`. This predicate does not have a result when the + * unspecified type of `v` is a `ReferenceType`. + */ +private int getVariableSize(Variable v) { + exists(Type t | + t = v.getUnspecifiedType() and + not t instanceof ReferenceType and + result = t.getSize() + ) +} + /** * Gets the size of the buffer access at `va`. */ @@ -64,12 +76,8 @@ private int getSize(VariableAccess va) { exists(Variable v | va.getTarget() = v | // If `v` is not a field then the size of the buffer is just // the size of the type of `v`. - exists(Type t | - t = v.getUnspecifiedType() and - not v instanceof Field and - not t instanceof ReferenceType and - result = t.getSize() - ) + not v instanceof Field and + result = getVariableSize(v) or exists(Class c, int trueSize | // Otherwise, we find the "outermost" object and compute the size @@ -92,7 +100,7 @@ private int getSize(VariableAccess va) { // buffer is `12 - 4 = 8`. c = getRootType(va) and // we calculate the size based on the last field, to avoid including any padding after it - trueSize = max(Field f | | f.getOffsetInClass(c) + f.getUnspecifiedType().getSize()) and + trueSize = max(Field f | | f.getOffsetInClass(c) + getVariableSize(f)) and result = trueSize - v.(Field).getOffsetInClass(c) ) ) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 19723d93e905..533df517af5d 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -936,6 +936,77 @@ private module Cached { ValueNumber getUnary() { result.getAnInstruction() = instr.getUnary() } } + signature predicate sinkSig(Instruction instr); + + private module BooleanInstruction { + /** + * Holds if `i1` flows to `i2` in a single step and `i2` is not an + * instruction that produces a value of Boolean type. + */ + private predicate stepToNonBoolean(Instruction i1, Instruction i2) { + not i2.getResultIRType() instanceof IRBooleanType and + ( + i2.(CopyInstruction).getSourceValue() = i1 + or + i2.(ConvertInstruction).getUnary() = i1 + or + i2.(BuiltinExpectCallInstruction).getArgument(0) = i1 + ) + } + + private predicate rev(Instruction instr) { + isSink(instr) + or + exists(Instruction instr1 | + rev(instr1) and + stepToNonBoolean(instr, instr1) + ) + } + + private predicate hasBooleanType(Instruction instr) { + instr.getResultIRType() instanceof IRBooleanType + } + + private predicate fwd(Instruction instr) { + rev(instr) and + ( + hasBooleanType(instr) + or + exists(Instruction instr0 | + fwd(instr0) and + stepToNonBoolean(instr0, instr) + ) + ) + } + + private predicate prunedStep(Instruction i1, Instruction i2) { + fwd(i1) and + fwd(i2) and + stepToNonBoolean(i1, i2) + } + + private predicate stepsPlus(Instruction i1, Instruction i2) = + doublyBoundedFastTC(prunedStep/2, hasBooleanType/1, isSink/1)(i1, i2) + + /** + * Gets the Boolean-typed instruction that defines `instr` before any + * integer conversions are applied, if any. + */ + Instruction get(Instruction instr) { + isSink(instr) and + ( + result = instr + or + stepsPlus(result, instr) + ) and + hasBooleanType(result) + } + } + + private predicate isUnaryComparesEqLeft(Instruction instr) { + unary_compares_eq(_, instr.getAUse(), 0, _, _) + } + /** * Holds if `left == right + k` is `areEqual` given that test is `testIsTrue`. * @@ -966,14 +1037,19 @@ private module Cached { ) or compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), left, right, k, areEqual, value) - } - - private predicate isConvertedBool(Instruction instr) { - instr.getResultIRType() instanceof IRBooleanType - or - isConvertedBool(instr.(ConvertInstruction).getUnary()) or - isConvertedBool(instr.(BuiltinExpectCallInstruction).getCondition()) + exists(Operand l, BooleanValue bv | + // 1. test = value -> int(l) = 0 is !bv + unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and + // 2. l = bv -> left + right is areEqual + compares_eq(valueNumber(BooleanInstruction::get(l.getDef())), left, + right, k, areEqual, bv) + // We want this to hold: + // `test = value -> left + right is areEqual` + // Applying 2 we need to show: + // `test = value -> l = bv` + // And `l = bv` holds by `int(l) = 0 is !bv` + ) } /** @@ -1006,19 +1082,11 @@ private module Cached { k = k1 + k2 ) or - exists(CompareValueNumber cmp, Operand left, Operand right, AbstractValue v | - test = cmp and - pragma[only_bind_into](cmp) - .hasOperands(pragma[only_bind_into](left), pragma[only_bind_into](right)) and - isConvertedBool(left.getDef()) and - int_value(right.getDef()) = 0 and - unary_compares_eq(valueNumberOfOperand(left), op, k, areEqual, v) - | - cmp instanceof CompareNEValueNumber and - v = value - or - cmp instanceof CompareEQValueNumber and - v.getDualValue() = value + // See argument for why this is correct in compares_eq + exists(Operand l, BooleanValue bv | + unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and + unary_compares_eq(valueNumber(BooleanInstruction::get(l.getDef())), + op, k, areEqual, bv) ) or unary_compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, areEqual, value) @@ -1116,70 +1184,26 @@ private module Cached { ) } + private predicate isBuiltInExpectArg(Instruction instr) { + instr = any(BuiltinExpectCallInstruction buildinExpect).getArgument(0) + } + /** A call to the builtin operation `__builtin_expect`. */ private class BuiltinExpectCallInstruction extends CallInstruction { BuiltinExpectCallInstruction() { this.getStaticCallTarget().hasName("__builtin_expect") } /** Gets the condition of this call. */ - Instruction getCondition() { result = this.getConditionOperand().getDef() } - - Operand getConditionOperand() { - // The first parameter of `__builtin_expect` has type `long`. So we skip - // the conversion when inferring guards. - result = this.getArgument(0).(ConvertInstruction).getUnaryOperand() + Instruction getCondition() { + result = BooleanInstruction::get(this.getArgument(0)) } } - /** - * Holds if `left == right + k` is `areEqual` if `cmp` evaluates to `value`, - * and `cmp` is an instruction that compares the value of - * `__builtin_expect(left == right + k, _)` to `0`. - */ - private predicate builtin_expect_eq( - CompareValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, - AbstractValue value - ) { - exists(BuiltinExpectCallValueNumber call, Instruction const, AbstractValue innerValue | - int_value(const) = 0 and - cmp.hasOperands(call.getAUse(), const.getAUse()) and - compares_eq(call.getCondition(), left, right, k, areEqual, innerValue) - | - cmp instanceof CompareNEValueNumber and - value = innerValue - or - cmp instanceof CompareEQValueNumber and - value.getDualValue() = innerValue - ) - } - private predicate complex_eq( ValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, AbstractValue value ) { sub_eq(cmp, left, right, k, areEqual, value) or add_eq(cmp, left, right, k, areEqual, value) - or - builtin_expect_eq(cmp, left, right, k, areEqual, value) - } - - /** - * Holds if `op == k` is `areEqual` if `cmp` evaluates to `value`, and `cmp` is - * an instruction that compares the value of `__builtin_expect(op == k, _)` to `0`. - */ - private predicate unary_builtin_expect_eq( - CompareValueNumber cmp, Operand op, int k, boolean areEqual, AbstractValue value - ) { - exists(BuiltinExpectCallValueNumber call, Instruction const, AbstractValue innerValue | - int_value(const) = 0 and - cmp.hasOperands(call.getAUse(), const.getAUse()) and - unary_compares_eq(call.getCondition(), op, k, areEqual, innerValue) - | - cmp instanceof CompareNEValueNumber and - value = innerValue - or - cmp instanceof CompareEQValueNumber and - value.getDualValue() = innerValue - ) } private predicate unary_complex_eq( @@ -1188,8 +1212,6 @@ private module Cached { unary_sub_eq(test, op, k, areEqual, value) or unary_add_eq(test, op, k, areEqual, value) - or - unary_builtin_expect_eq(test, op, k, areEqual, value) } /* @@ -1215,6 +1237,15 @@ private module Cached { exists(AbstractValue dual | value = dual.getDualValue() | compares_lt(test.(LogicalNotValueNumber).getUnary(), left, right, k, isLt, dual) ) + or + compares_lt(test.(BuiltinExpectCallValueNumber).getCondition(), left, right, k, isLt, value) + or + // See argument for why this is correct in compares_eq + exists(Operand l, BooleanValue bv | + unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and + compares_lt(valueNumber(BooleanInstruction::get(l.getDef())), left, + right, k, isLt, bv) + ) } /** Holds if `op < k` evaluates to `isLt` given that `test` evaluates to `value`. */ @@ -1234,6 +1265,15 @@ private module Cached { int_value(const) = k1 and k = k1 + k2 ) + or + compares_lt(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, isLt, value) + or + // See argument for why this is correct in compares_eq + exists(Operand l, BooleanValue bv | + unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and + compares_lt(valueNumber(BooleanInstruction::get(l.getDef())), op, k, + isLt, bv) + ) } /** `(a < b + k) => (b > a - k) => (b >= a + (1-k))` */ diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll index 1e0b39be1ac7..9c6069d4a0c5 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll @@ -15,6 +15,13 @@ class StandardSsa extends SsaHelper { } /** + * NOTE: If possible, prefer the SSA classes exposed by the new dataflow + * library: + * ``` + * import semmle.code.cpp.dataflow.new.DataFlow + * // use `DataFlow::Ssa::Definition` + * ``` + * * A definition of one or more SSA variables, including phi node definitions. * An _SSA variable_, as defined in the literature, is effectively the pair of * an `SsaDefinition d` and a `StackVariable v`, written `(d, v)` in this diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll index 1a4c777af35b..b5e899bf0aac 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll @@ -1,6 +1,5 @@ private import cpp private import semmle.code.cpp.ir.IR -private import semmle.code.cpp.ir.dataflow.DataFlow private import DataFlowPrivate private import DataFlowUtil private import DataFlowImplCommon as DataFlowImplCommon @@ -60,7 +59,7 @@ private module VirtualDispatch { * `resolve` predicate to stitch that information together and resolve the * call. */ - abstract DataFlow::Node getDispatchValue(); + abstract Node getDispatchValue(); /** Gets a candidate target for this call. */ abstract Function resolve(); @@ -72,17 +71,13 @@ private module VirtualDispatch { * parameter is true when the search is allowed to continue backwards into * a parameter; non-recursive callers should pass `_` for `allowFromArg`. */ - predicate flowsFrom(DataFlow::Node src, boolean allowFromArg) { + predicate flowsFrom(Node src, boolean allowFromArg) { src = this.getDispatchValue() and allowFromArg = true or - exists(DataFlow::Node other, boolean allowOtherFromArg | - this.flowsFrom(other, allowOtherFromArg) - | + exists(Node other, boolean allowOtherFromArg | this.flowsFrom(other, allowOtherFromArg) | // Call argument exists(DataFlowCall call, Position i | - other - .(DataFlow::ParameterNode) - .isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and + other.(ParameterNode).isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and src.(ArgumentNode).argumentOf(call, pragma[only_bind_into](pragma[only_bind_out](i))) ) and allowOtherFromArg = true and @@ -96,7 +91,7 @@ private module VirtualDispatch { allowFromArg = false or // Local flow - DataFlow::localFlowStep(src, other) and + localFlowStep(src, other) and allowFromArg = allowOtherFromArg or // Flow from global variable to load. @@ -159,11 +154,11 @@ private module VirtualDispatch { private class DataSensitiveExprCall extends DataSensitiveCall { DataSensitiveExprCall() { not exists(this.getStaticCallTarget()) } - override DataFlow::Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() } + override Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() } override Function resolve() { exists(FunctionInstruction fi | - this.flowsFrom(DataFlow::instructionNode(fi), _) and + this.flowsFrom(instructionNode(fi), _) and result = fi.getFunctionSymbol() ) and ( @@ -186,7 +181,7 @@ private module VirtualDispatch { ) } - override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) } + override Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) } override MemberFunction resolve() { exists(Class overridingClass | @@ -213,7 +208,7 @@ private module VirtualDispatch { pragma[noinline] private predicate hasFlowFromCastFrom(Class derivedClass) { exists(ConvertToBaseInstruction toBase | - this.flowsFrom(DataFlow::instructionNode(toBase), _) and + this.flowsFrom(instructionNode(toBase), _) and derivedClass = toBase.getDerivedClass() ) } @@ -270,7 +265,7 @@ private predicate mayBenefitFromCallContext( exists(InitializeParameterInstruction init | not exists(call.getStaticCallTarget()) and init.getEnclosingFunction() = f.getUnderlyingCallable() and - call.flowsFrom(DataFlow::instructionNode(init), _) and + call.flowsFrom(instructionNode(init), _) and init.getParameter().getIndex() = arg ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index d7f26dd00513..a03042a77ff0 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -4,7 +4,7 @@ private import semmle.code.cpp.ir.IR private import DataFlowDispatch private import semmle.code.cpp.ir.internal.IRCppLanguage private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -private import SsaInternals as Ssa +private import SsaImpl as Ssa private import DataFlowImplCommon as DataFlowImplCommon private import codeql.util.Unit private import Node0ToString @@ -332,6 +332,13 @@ private module IndirectInstructions { import IndirectInstructions +predicate isPostUpdateNodeImpl(Operand operand, int indirectionIndex) { + operand = any(FieldAddress fa).getObjectAddressOperand() and + indirectionIndex = [0 .. Ssa::countIndirectionsForCppType(Ssa::getLanguageType(operand))] + or + Ssa::isModifiableByCall(operand, indirectionIndex) +} + /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() } @@ -1982,19 +1989,23 @@ module IteratorFlow { predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() } + class GuardValue = Void; + class Guard extends Void { - predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) { + predicate hasValueBranchEdge( + SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val + ) { none() } - predicate controlsBranchEdge( - SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch + predicate valueControlsBranchEdge( + SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val ) { none() } } - predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) { + predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 38a4d827a4da..a0a99711552c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -13,7 +13,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import DataFlowPrivate private import ModelUtil -private import SsaInternals as Ssa +private import SsaImpl as SsaImpl private import DataFlowImplCommon as DataFlowImplCommon private import codeql.util.Unit private import Node0ToString @@ -39,38 +39,35 @@ private newtype TIRDataFlowNode = TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or TGlobalLikeVariableNode(GlobalLikeVariable var, int indirectionIndex) { indirectionIndex = - [getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())] + [getMinIndirectionsForType(var.getUnspecifiedType()) .. SsaImpl::getMaxIndirectionsForType(var.getUnspecifiedType())] } or TPostUpdateNodeImpl(Operand operand, int indirectionIndex) { - operand = any(FieldAddress fa).getObjectAddressOperand() and - indirectionIndex = [0 .. Ssa::countIndirectionsForCppType(Ssa::getLanguageType(operand))] - or - Ssa::isModifiableByCall(operand, indirectionIndex) + isPostUpdateNodeImpl(operand, indirectionIndex) } or - TSsaSynthNode(Ssa::SynthNode n) or + TSsaSynthNode(SsaImpl::SynthNode n) or TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or TRawIndirectOperand0(Node0Impl node, int indirectionIndex) { - Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex) + SsaImpl::hasRawIndirectOperand(node.asOperand(), indirectionIndex) } or TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) { not exists(node.asOperand()) and - Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex) + SsaImpl::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex) } or TFinalParameterNode(Parameter p, int indirectionIndex) { - exists(Ssa::FinalParameterUse use | + exists(SsaImpl::FinalParameterUse use | use.getParameter() = p and use.getIndirectionIndex() = indirectionIndex ) } or - TFinalGlobalValue(Ssa::GlobalUse globalUse) or - TInitialGlobalValue(Ssa::GlobalDef globalUse) or + TFinalGlobalValue(SsaImpl::GlobalUse globalUse) or + TInitialGlobalValue(SsaImpl::GlobalDef globalUse) or TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) { // Rule out parameters of catch blocks. not exists(p.getCatchBlock()) and // We subtract one because `getMaxIndirectionsForType` returns the maximum // indirection for a glvalue of a given type, and this doesn't apply to // parameters. - indirectionIndex = [0 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and + indirectionIndex = [0 .. SsaImpl::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and not any(InitializeParameterInstruction init).getParameter() = p } or TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) @@ -81,7 +78,7 @@ private newtype TIRDataFlowNode = class FieldAddress extends Operand { FieldAddressInstruction fai; - FieldAddress() { fai = this.getDef() and not Ssa::ignoreOperand(this) } + FieldAddress() { fai = this.getDef() and not SsaImpl::ignoreOperand(this) } /** Gets the field associated with this instruction. */ Field getField() { result = fai.getField() } @@ -126,7 +123,7 @@ predicate conversionFlow( ) or additional = true and - Ssa::isAdditionalConversionFlow(opFrom, instrTo) + SsaImpl::isAdditionalConversionFlow(opFrom, instrTo) ) or isPointerArith = true and @@ -183,7 +180,7 @@ class Node extends TIRDataFlowNode { or this.asOperand().getUse() = block.getInstruction(i) or - exists(Ssa::SynthNode ssaNode | + exists(SsaImpl::SynthNode ssaNode | this.(SsaSynthNode).getSynthNode() = ssaNode and ssaNode.getBasicBlock() = block and ssaNode.getIndex() = i @@ -364,10 +361,10 @@ class Node extends TIRDataFlowNode { * pointed to by `p`. */ Expr asDefinition(boolean uncertain) { - exists(StoreInstruction store, Ssa::Definition def | + exists(StoreInstruction store, SsaImpl::Definition def | store = this.asInstruction() and result = asDefinitionImpl(store) and - Ssa::defToNode(this, def, _) and + SsaImpl::defToNode(this, def, _) and if def.isCertain() then uncertain = false else uncertain = true ) } @@ -627,7 +624,7 @@ class OperandNode extends Node, Node0 { * For example, `stripPointers(int*&)` is `int*` and `stripPointers(int*)` is `int`. */ Type stripPointer(Type t) { - result = any(Ssa::Indirection ind | ind.getType() = t).getBaseType() + result = any(SsaImpl::Indirection ind | ind.getType() = t).getBaseType() or result = t.(PointerToMemberType).getBaseType() or @@ -694,12 +691,12 @@ class PostFieldUpdateNode extends PostUpdateNodeImpl { * in a data flow graph. */ class SsaSynthNode extends Node, TSsaSynthNode { - Ssa::SynthNode node; + SsaImpl::SynthNode node; SsaSynthNode() { this = TSsaSynthNode(node) } /** Gets the synthesized SSA node associated with this node. */ - Ssa::SynthNode getSynthNode() { result = node } + SsaImpl::SynthNode getSynthNode() { result = node } override DataFlowCallable getEnclosingCallable() { result.asSourceCallable() = this.getFunction() @@ -782,12 +779,12 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand { * from a function body. */ class FinalGlobalValue extends Node, TFinalGlobalValue { - Ssa::GlobalUse globalUse; + SsaImpl::GlobalUse globalUse; FinalGlobalValue() { this = TFinalGlobalValue(globalUse) } /** Gets the underlying SSA use. */ - Ssa::GlobalUse getGlobalUse() { result = globalUse } + SsaImpl::GlobalUse getGlobalUse() { result = globalUse } override DataFlowCallable getEnclosingCallable() { result.asSourceCallable() = this.getFunction() @@ -814,12 +811,12 @@ class FinalGlobalValue extends Node, TFinalGlobalValue { * a function body. */ class InitialGlobalValue extends Node, TInitialGlobalValue { - Ssa::GlobalDef globalDef; + SsaImpl::GlobalDef globalDef; InitialGlobalValue() { this = TInitialGlobalValue(globalDef) } /** Gets the underlying SSA definition. */ - Ssa::GlobalDef getGlobalDef() { result = globalDef } + SsaImpl::GlobalDef getGlobalDef() { result = globalDef } override DataFlowCallable getEnclosingCallable() { result.asSourceCallable() = this.getFunction() @@ -1288,11 +1285,11 @@ class UninitializedNode extends Node { LocalVariable v; UninitializedNode() { - exists(Ssa::Definition def, Ssa::SourceVariable sv | + exists(SsaImpl::Definition def, SsaImpl::SourceVariable sv | def.getIndirectionIndex() = 0 and def.getValue().asInstruction() instanceof UninitializedInstruction and - Ssa::defToNode(this, def, sv) and - v = sv.getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() + SsaImpl::defToNode(this, def, sv) and + v = sv.getBaseVariable().(SsaImpl::BaseIRVariable).getIRVariable().getAst() ) } @@ -1722,7 +1719,7 @@ private module Cached { cached predicate flowsToBackEdge(Node n) { exists(Node succ, IRBlock bb1, IRBlock bb2 | - Ssa::ssaFlow(n, succ) and + SsaImpl::ssaFlow(n, succ) and bb1 = n.getBasicBlock() and bb2 = succ.getBasicBlock() and bb1 != bb2 and @@ -1820,7 +1817,7 @@ private module Cached { predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) { ( // Def-use/Use-use flow - Ssa::ssaFlow(nodeFrom, nodeTo) + SsaImpl::ssaFlow(nodeFrom, nodeTo) or IteratorFlow::localFlowStep(nodeFrom, nodeTo) or @@ -1833,7 +1830,7 @@ private module Cached { | simpleOperandLocalFlowStep(iFrom, opTo) and // Omit when the instruction node also represents the operand. - not iFrom = Ssa::getIRRepresentationOfOperand(opTo) + not iFrom = SsaImpl::getIRRepresentationOfOperand(opTo) ) or // Indirect operand -> (indirect) instruction flow @@ -1906,7 +1903,7 @@ private module Cached { // We also want a write coming out of an `OutNode` to flow `nodeTo`. // This is different from `reverseFlowInstruction` since `nodeFrom` can never // be an `OutNode` when it's defined by an instruction. - Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex) + SsaImpl::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex) ) } @@ -2099,7 +2096,7 @@ private newtype TContent = TFieldContent(Field f, int indirectionIndex) { // the indirection index for field content starts at 1 (because `TFieldContent` is thought of as // the address of the field, `FieldAddress` in the IR). - indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(f.getUnspecifiedType())] and + indirectionIndex = [1 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and // Reads and writes of union fields are tracked using `UnionContent`. not f.getDeclaringType() instanceof Union } or @@ -2111,7 +2108,9 @@ private newtype TContent = // field can be read by any read of the union's fields. Again, the indirection index // is 1-based (because 0 is considered the address). indirectionIndex = - [1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))] + [1 .. max(SsaImpl::getMaxIndirectionsForType(getAFieldWithSize(u, bytes) + .getUnspecifiedType()) + )] ) } or TElementContent(int indirectionIndex) { @@ -2354,7 +2353,7 @@ module BarrierGuard { controls(g, result, edge) ) or - result = Ssa::BarrierGuard::getABarrierNode() + result = SsaImpl::BarrierGuard::getABarrierNode() } /** @@ -2453,7 +2452,7 @@ module BarrierGuard { ) or result = - Ssa::BarrierGuardWithIntParam::getABarrierNode(indirectionIndex) + SsaImpl::BarrierGuardWithIntParam::getABarrierNode(indirectionIndex) } } @@ -2490,7 +2489,7 @@ module InstructionBarrierGuard::getABarrierNode() + result = SsaImpl::BarrierGuard::getABarrierNode() } bindingset[value, n] @@ -2520,7 +2519,7 @@ module InstructionBarrierGuard::getABarrierNode(indirectionIndex) + SsaImpl::BarrierGuardWithIntParam::getABarrierNode(indirectionIndex) } } @@ -2576,3 +2575,16 @@ Function getARuntimeTarget(Call call) { result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable() ) } + +/** A module that provides static single assignment (SSA) information. */ +module Ssa { + class Definition = SsaImpl::Definition; + + class ExplicitDefinition = SsaImpl::ExplicitDefinition; + + class DirectExplicitDefinition = SsaImpl::DirectExplicitDefinition; + + class IndirectExplicitDefinition = SsaImpl::IndirectExplicitDefinition; + + class PhiNode = SsaImpl::PhiNode; +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll index 055f48c80ec8..f880bee1c1c4 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll @@ -4,15 +4,15 @@ */ private import semmle.code.cpp.ir.IR -private import semmle.code.cpp.ir.dataflow.DataFlow +private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs private import DataFlowUtil private import DataFlowPrivate -private import SsaInternals as Ssa +private import SsaImpl as Ssa /** * Gets the instruction that goes into `input` for `call`. */ -DataFlow::Node callInput(CallInstruction call, FunctionInput input) { +Node callInput(CallInstruction call, FunctionInput input) { // An argument or qualifier exists(int index | result.asOperand() = call.getArgumentOperand(index) and @@ -62,8 +62,8 @@ Node callOutput(CallInstruction call, FunctionOutput output) { result = callOutputWithIndirectionIndex(call, output, _) } -DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) { - exists(DataFlow::Node n | n = callInput(call, input) and d > 0 | +Node callInput(CallInstruction call, FunctionInput input, int d) { + exists(Node n | n = callInput(call, input) and d > 0 | // An argument or qualifier hasOperandAndIndex(result, n.asOperand(), d) or @@ -85,7 +85,7 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int */ bindingset[d] Node callOutput(CallInstruction call, FunctionOutput output, int d) { - exists(DataFlow::Node n, int indirectionIndex | + exists(Node n, int indirectionIndex | n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0 | // The return value diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintDataFlowRelevantIR.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintDataFlowRelevantIR.qll index 2a654828ee54..22550e187ace 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintDataFlowRelevantIR.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintDataFlowRelevantIR.qll @@ -1,6 +1,6 @@ private import cpp private import semmle.code.cpp.ir.IR -private import SsaInternals as Ssa +private import SsaImpl as Ssa /** * A property provider that hides all instructions and operands that are not relevant for IR dataflow. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll index cf612ce73687..e310db319319 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll @@ -2,7 +2,7 @@ private import cpp private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate -private import SsaInternals as Ssa +private import SsaImpl as Ssa private import PrintIRUtilities /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll similarity index 90% rename from cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll rename to cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll index fd9ba967a13d..b9f320e57b23 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll @@ -1,4 +1,4 @@ -private import codeql.ssa.Ssa as SsaImplCommon +private import codeql.ssa.Ssa as Ssa private import semmle.code.cpp.ir.IR private import DataFlowUtil private import DataFlowImplCommon as DataFlowImplCommon @@ -12,7 +12,7 @@ private import semmle.code.cpp.ir.internal.IRCppLanguage private import semmle.code.cpp.ir.dataflow.internal.ModelUtil private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedInitialization private import DataFlowPrivate -import SsaInternalsCommon +import SsaImplCommon private module SourceVariables { cached @@ -143,7 +143,14 @@ private predicate isGlobalUse( min(int cand, VariableAddressInstruction vai | vai.getEnclosingIRFunction() = f and vai.getAstVariable() = v and - isDef(_, _, _, vai, cand, indirectionIndex) + ( + isDef(_, _, _, vai, cand, indirectionIndex) + or + exists(Operand operand | + isUse(_, operand, vai, cand, indirectionIndex) and + isPostUpdateNodeImpl(operand, indirectionIndex) + ) + ) | cand ) @@ -884,7 +891,7 @@ private predicate baseSourceVariableIsGlobal( ) } -private module SsaInput implements SsaImplCommon::InputSig { +private module SsaInput implements Ssa::InputSig { import InputSigCommon import SourceVariables @@ -958,9 +965,11 @@ class GlobalDef extends Definition { GlobalLikeVariable getVariable() { result = impl.getVariable() } } -private module SsaImpl = SsaImplCommon::Make; +private module SsaImpl = Ssa::Make; private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig { + private import codeql.util.Boolean + class Expr extends Instruction { Expr() { exists(IRBlock bb, int i | @@ -992,10 +1001,14 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI result instanceof FalseEdge } + class GuardValue = Boolean; + class Guard instanceof IRGuards::IRGuardCondition { string toString() { result = super.toString() } - predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) { + predicate hasValueBranchEdge( + SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch + ) { exists(EdgeKind kind | super.getBlock() = bb1 and kind = getConditionalEdge(branch) and @@ -1003,12 +1016,14 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI ) } - predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) { - this.hasBranchEdge(bb1, bb2, branch) + predicate valueControlsBranchEdge( + SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch + ) { + this.hasValueBranchEdge(bb1, bb2, branch) } } - predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) { + predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) { guard.(IRGuards::IRGuardCondition).controls(bb, branch) } @@ -1037,7 +1052,8 @@ module BarrierGuardWithIntParam { } private predicate guardChecks( - DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, boolean branch, int indirectionIndex + DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, + DataFlowIntegrationInput::GuardValue branch, int indirectionIndex ) { exists(UseImpl use | guardChecksNode(g, use.getNode(), branch, indirectionIndex) and @@ -1116,9 +1132,11 @@ class PhiNode extends Definition instanceof SsaImpl::PhiNode { /** An static single assignment (SSA) definition. */ class Definition extends SsaImpl::Definition { - // TODO: Include prior definitions of uncertain writes or rename predicate - // i.e. the disjunct `SsaImpl::uncertainWriteDefinitionInput(this, result)` - private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() } + private Definition getAPhiInputOrPriorDefinition() { + result = this.(PhiNode).getAnInput() + or + SsaImpl::uncertainWriteDefinitionInput(this, result) + } /** * Gets a definition that ultimately defines this SSA definition and is @@ -1129,6 +1147,36 @@ class Definition extends SsaImpl::Definition { not result instanceof PhiNode } + /** Gets an `Operand` that represents a use of this definition. */ + Operand getAUse() { + exists(SourceVariable sv, IRBlock bb, int i, UseImpl use | + ssaDefReachesRead(sv, this, bb, i) and + use.hasIndexInBlock(bb, i, sv) and + result = use.getNode().asOperand() + ) + } + + /** + * Gets an `Operand` that represents an indirect use of this definition. + * + * The use is indirect because the operand represents a pointer that points + * to the value written by this definition. For example in: + * ```cpp + * 1. int x = 42; + * 2. int* p = &x; + * ``` + * There is an `ExplicitDefinition` corresponding to `x = 42` on line 1 and + * the definition has an indirect use on line 2 because `&x` points to the + * value that was defined by the definition. + */ + Operand getAnIndirectUse(int indirectionIndex) { + exists(SourceVariable sv, IRBlock bb, int i, UseImpl use | + ssaDefReachesRead(sv, this, bb, i) and + use.hasIndexInBlock(bb, i, sv) and + result = use.getNode().asIndirectOperand(indirectionIndex) + ) + } + /** * INTERNAL: Do not use. */ @@ -1161,4 +1209,63 @@ class Definition extends SsaImpl::Definition { Type getUnspecifiedType() { result = this.getUnderlyingType().getUnspecifiedType() } } +/** + * An SSA definition that corresponds to an explicit definition. + */ +class ExplicitDefinition extends Definition, SsaImpl::WriteDefinition { + DefImpl def; + + ExplicitDefinition() { + exists(IRBlock bb, int i, SourceVariable sv | + this.definesAt(sv, bb, i) and + def.hasIndexInBlock(sv, bb, i) + ) + } + + /** + * Gets the `Instruction` computing the value that is written to the + * associated SSA variable by this SSA definition. + * + * If `this.getIndirectionIndex() = 0` (i.e., if `this` is an instance of + * `DirectExplicitDefinition`) then the SSA variable is present in the source + * code. + * However, if `this.getIndirectionIndex() > 0` (i.e., if `this` is an + * instance of `IndirectExplicitDefinition`) then the SSA variable associated + * with this definition represents the memory pointed to by a variable in the + * source code. + */ + Instruction getAssignedInstruction() { result = def.getValue().asInstruction() } +} + +/** + * An explicit SSA definition that writes an indirect value to a pointer. + * + * For example in: + * ```cpp + * int x = 42; // (1) + * int* p = &x; // (2) + * ``` + * There are three `ExplicitDefinition`: + * 1. A `DirectExplicitDefinition` at (1) which writes `42` to the SSA variable + * corresponding to `x`. + * 2. A `DirectExplicitDefinition` at (2) which writes `&x` to the SSA variable + * corresponding to `p`. + * 3. A `IndirectExplicitDefinition` at (2) which writes `*&x` (i.e., `x`) to + * the SSA variable corresponding to `*p`. + */ +class IndirectExplicitDefinition extends ExplicitDefinition { + IndirectExplicitDefinition() { this.getIndirectionIndex() > 0 } +} + +/** + * An SSA definition that corresponds to an explicit definition. + * + * Unlike `ExplicitDefinition` this class does not include indirect + * explicit definition. See `IndirectExplicitDefinition` if you want to include + * those. + */ +class DirectExplicitDefinition extends ExplicitDefinition { + DirectExplicitDefinition() { this.getIndirectionIndex() = 0 } +} + import SsaCached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll similarity index 100% rename from cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll rename to cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index 83fac3ebb49a..f190569330f5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -5,7 +5,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow private import semmle.code.cpp.models.interfaces.SideEffect private import DataFlowUtil private import DataFlowPrivate -private import SsaInternals as Ssa +private import SsaImpl as Ssa private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl private import semmle.code.cpp.ir.dataflow.FlowSteps diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll index ec0038917743..66d499112b81 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -43,6 +43,23 @@ newtype TValueNumber = } or TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) } +/** + * A `ConvertInstruction` which converts data of type `T` to data of type `U` + * where `T` and `U` only differ in specifiers. For example, if `T` is `int` + * and `U` is `const T` this is a conversion from a non-const integer to a + * const integer. + * + * Generally, the value number of a converted value is different from the value + * number of an unconverted value, but conversions which only modify specifiers + * leave the resulting value bitwise identical to the old value. + */ +class TypePreservingConvertInstruction extends ConvertInstruction { + TypePreservingConvertInstruction() { + pragma[only_bind_out](this.getResultType().getUnspecifiedType()) = + pragma[only_bind_out](this.getUnary().getResultType().getUnspecifiedType()) + } +} + /** * A `CopyInstruction` whose source operand's value is congruent to the definition of that source * operand. @@ -216,6 +233,7 @@ private predicate unaryValueNumber( not instr instanceof InheritanceConversionInstruction and not instr instanceof CopyInstruction and not instr instanceof FieldAddressInstruction and + not instr instanceof TypePreservingConvertInstruction and instr.getOpcode() = opcode and tvalueNumber(instr.getUnary()) = operand } @@ -351,6 +369,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) { or // The value number of a copy is just the value number of its source value. result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue()) + or + // The value number of a type-preserving conversion is just the value + // number of the unconverted value. + result = tvalueNumber(instr.(TypePreservingConvertInstruction).getUnary()) ) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll index ec0038917743..66d499112b81 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll @@ -43,6 +43,23 @@ newtype TValueNumber = } or TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) } +/** + * A `ConvertInstruction` which converts data of type `T` to data of type `U` + * where `T` and `U` only differ in specifiers. For example, if `T` is `int` + * and `U` is `const T` this is a conversion from a non-const integer to a + * const integer. + * + * Generally, the value number of a converted value is different from the value + * number of an unconverted value, but conversions which only modify specifiers + * leave the resulting value bitwise identical to the old value. + */ +class TypePreservingConvertInstruction extends ConvertInstruction { + TypePreservingConvertInstruction() { + pragma[only_bind_out](this.getResultType().getUnspecifiedType()) = + pragma[only_bind_out](this.getUnary().getResultType().getUnspecifiedType()) + } +} + /** * A `CopyInstruction` whose source operand's value is congruent to the definition of that source * operand. @@ -216,6 +233,7 @@ private predicate unaryValueNumber( not instr instanceof InheritanceConversionInstruction and not instr instanceof CopyInstruction and not instr instanceof FieldAddressInstruction and + not instr instanceof TypePreservingConvertInstruction and instr.getOpcode() = opcode and tvalueNumber(instr.getUnary()) = operand } @@ -351,6 +369,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) { or // The value number of a copy is just the value number of its source value. result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue()) + or + // The value number of a type-preserving conversion is just the value + // number of the unconverted value. + result = tvalueNumber(instr.(TypePreservingConvertInstruction).getUnary()) ) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll index 35e08e5920c4..d864e86aa040 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll @@ -96,7 +96,8 @@ newtype TInstructionTag = exists(Expr e | exists(e.getImplicitDestructorCall(index))) or exists(Stmt s | exists(s.getImplicitDestructorCall(index))) } or - CoAwaitBranchTag() + CoAwaitBranchTag() or + BoolToIntConversionTag() class InstructionTag extends TInstructionTag { final string toString() { result = getInstructionTagId(this) } @@ -286,4 +287,6 @@ string getInstructionTagId(TInstructionTag tag) { ) or tag = CoAwaitBranchTag() and result = "CoAwaitBranch" + or + tag = BoolToIntConversionTag() and result = "BoolToIntConversion" } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index e22aa33f3605..e1314035437e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -509,6 +509,41 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) { not expr.hasLValueToRValueConversion() } +Opcode comparisonOpcode(ComparisonOperation expr) { + expr instanceof EQExpr and result instanceof Opcode::CompareEQ + or + expr instanceof NEExpr and result instanceof Opcode::CompareNE + or + expr instanceof LTExpr and result instanceof Opcode::CompareLT + or + expr instanceof GTExpr and result instanceof Opcode::CompareGT + or + expr instanceof LEExpr and result instanceof Opcode::CompareLE + or + expr instanceof GEExpr and result instanceof Opcode::CompareGE +} + +private predicate parentExpectsBool(Expr child) { + any(NotExpr notExpr).getOperand() = child + or + usedAsCondition(child) +} + +/** + * Holds if `expr` should have a `TranslatedSyntheticBoolToIntConversion` on it. + */ +predicate hasTranslatedSyntheticBoolToIntConversion(Expr expr) { + not ignoreExpr(expr) and + not isIRConstant(expr) and + not parentExpectsBool(expr) and + expr.getUnspecifiedType() instanceof IntType and + ( + expr instanceof NotExpr + or + exists(comparisonOpcode(expr)) + ) +} + class StaticInitializedStaticLocalVariable extends StaticLocalVariable { StaticInitializedStaticLocalVariable() { this.hasInitializer() and @@ -647,6 +682,9 @@ newtype TTranslatedElement = // A temporary object that we had to synthesize ourselves, so that we could do a field access or // method call on a prvalue. TTranslatedSyntheticTemporaryObject(Expr expr) { hasTranslatedSyntheticTemporaryObject(expr) } or + TTranslatedSyntheticBoolToIntConversion(Expr expr) { + hasTranslatedSyntheticBoolToIntConversion(expr) + } or // For expressions that would not otherwise generate an instruction. TTranslatedResultCopy(Expr expr) { not ignoreExpr(expr) and diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index a7e85fe9b1a5..f7786fcf290a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -216,7 +216,8 @@ abstract class TranslatedCoreExpr extends TranslatedExpr { not hasTranslatedLoad(expr) and not hasTranslatedSyntheticTemporaryObject(expr) and // If there's a result copy, then this expression's result is the copy. - not exprNeedsCopyIfNotLoaded(expr) + not exprNeedsCopyIfNotLoaded(expr) and + not hasTranslatedSyntheticBoolToIntConversion(expr) } } @@ -358,11 +359,12 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext, } /** - * The IR translation of a node synthesized to adjust the value category of its operand. + * The IR translation of a node synthesized to adjust the value category or type of its operand. * One of: * - `TranslatedLoad` - Convert from glvalue to prvalue by loading from the location. * - `TranslatedSyntheticTemporaryObject` - Convert from prvalue to glvalue by storing to a * temporary variable. + * - `TranslatedSyntheticBoolToIntConversion` - Convert a prvalue Boolean to a prvalue integer. */ abstract class TranslatedValueCategoryAdjustment extends TranslatedExpr { final override Instruction getFirstInstruction(EdgeKind kind) { @@ -513,6 +515,45 @@ class TranslatedSyntheticTemporaryObject extends TranslatedValueCategoryAdjustme } } +class TranslatedSyntheticBoolToIntConversion extends TranslatedValueCategoryAdjustment, + TTranslatedSyntheticBoolToIntConversion +{ + TranslatedSyntheticBoolToIntConversion() { this = TTranslatedSyntheticBoolToIntConversion(expr) } + + override string toString() { result = "Bool-to-int conversion of " + expr.toString() } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { + opcode instanceof Opcode::Convert and + tag = BoolToIntConversionTag() and + resultType = getIntType() + } + + override predicate isResultGLValue() { none() } + + override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { + tag = BoolToIntConversionTag() and + result = this.getParent().getChildSuccessor(this, kind) + } + + override Instruction getALastInstructionInternal() { + result = this.getInstruction(BoolToIntConversionTag()) + } + + override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { + child = this.getOperand() and + result = this.getInstruction(BoolToIntConversionTag()) and + kind instanceof GotoEdge + } + + override Instruction getResult() { result = this.getInstruction(BoolToIntConversionTag()) } + + override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { + tag = BoolToIntConversionTag() and + operandTag instanceof UnaryOperandTag and + result = this.getOperand().getResult() + } +} + /** * IR translation of an expression that simply returns its result. We generate an otherwise useless * `CopyValue` instruction for these expressions so that there is at least one instruction @@ -1794,20 +1835,6 @@ private Opcode binaryArithmeticOpcode(BinaryArithmeticOperation expr) { expr instanceof PointerDiffExpr and result instanceof Opcode::PointerDiff } -private Opcode comparisonOpcode(ComparisonOperation expr) { - expr instanceof EQExpr and result instanceof Opcode::CompareEQ - or - expr instanceof NEExpr and result instanceof Opcode::CompareNE - or - expr instanceof LTExpr and result instanceof Opcode::CompareLT - or - expr instanceof GTExpr and result instanceof Opcode::CompareGT - or - expr instanceof LEExpr and result instanceof Opcode::CompareLE - or - expr instanceof GEExpr and result instanceof Opcode::CompareGE -} - private Opcode spaceShipOpcode(SpaceshipExpr expr) { exists(expr) and result instanceof Opcode::Spaceship diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll index ec0038917743..66d499112b81 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -43,6 +43,23 @@ newtype TValueNumber = } or TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) } +/** + * A `ConvertInstruction` which converts data of type `T` to data of type `U` + * where `T` and `U` only differ in specifiers. For example, if `T` is `int` + * and `U` is `const T` this is a conversion from a non-const integer to a + * const integer. + * + * Generally, the value number of a converted value is different from the value + * number of an unconverted value, but conversions which only modify specifiers + * leave the resulting value bitwise identical to the old value. + */ +class TypePreservingConvertInstruction extends ConvertInstruction { + TypePreservingConvertInstruction() { + pragma[only_bind_out](this.getResultType().getUnspecifiedType()) = + pragma[only_bind_out](this.getUnary().getResultType().getUnspecifiedType()) + } +} + /** * A `CopyInstruction` whose source operand's value is congruent to the definition of that source * operand. @@ -216,6 +233,7 @@ private predicate unaryValueNumber( not instr instanceof InheritanceConversionInstruction and not instr instanceof CopyInstruction and not instr instanceof FieldAddressInstruction and + not instr instanceof TypePreservingConvertInstruction and instr.getOpcode() = opcode and tvalueNumber(instr.getUnary()) = operand } @@ -351,6 +369,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) { or // The value number of a copy is just the value number of its source value. result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue()) + or + // The value number of a type-preserving conversion is just the value + // number of the unconverted value. + result = tvalueNumber(instr.(TypePreservingConvertInstruction).getUnary()) ) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll b/cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll index 223d0abf1d4e..2fea5327720a 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll @@ -53,44 +53,12 @@ private import cpp private import semmle.code.cpp.ir.dataflow.internal.ProductFlow +private import semmle.code.cpp.security.ProductFlowUtils.ProductFlowUtils private import semmle.code.cpp.ir.ValueNumbering private import semmle.code.cpp.controlflow.IRGuards private import codeql.util.Unit private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil -private VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result } - -/** - * Gets a (sub)expression that may be the result of evaluating `size`. - * - * For example, `getASizeCandidate(a ? b : c)` gives `a ? b : c`, `b` and `c`. - */ -bindingset[size] -pragma[inline_late] -private Expr getASizeCandidate(Expr size) { - result = size - or - result = [size.(ConditionalExpr).getThen(), size.(ConditionalExpr).getElse()] -} - -/** - * Holds if the `(n, state)` pair represents the source of flow for the size - * expression associated with `alloc`. - */ -predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) { - exists(VariableAccess va, Expr size, int delta, Expr s | - size = alloc.getSizeExpr() and - s = getASizeCandidate(size) and - // Get the unique variable in a size expression like `x` in `malloc(x + 1)`. - va = unique( | | getAVariableAccess(s)) and - // Compute `delta` as the constant difference between `x` and `x + 1`. - bounded1(any(Instruction instr | instr.getUnconvertedResultExpression() = s), - any(LoadInstruction load | load.getUnconvertedResultExpression() = va), delta) and - n.asExpr() = va and - state = delta - ) -} - /** * Gets the virtual dispatch branching limit when calculating field flow while searching * for flow from an allocation to the construction of an out-of-bounds pointer. @@ -100,125 +68,6 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) { */ int allocationToInvalidPointerFieldFlowBranchLimit() { result = 0 } -/** - * A module that encapsulates a barrier guard to remove false positives from flow like: - * ```cpp - * char *p = new char[size]; - * // ... - * unsigned n = size; - * // ... - * if(n < size) { - * use(*p[n]); - * } - * ``` - * In this case, the sink pair identified by the product flow library (without any additional barriers) - * would be `(p, n)` (where `n` is the `n` in `p[n]`), because there exists a pointer-arithmetic - * instruction `pai = a + b` such that: - * 1. the allocation flows to `a`, and - * 2. `b <= n` where `n` is the `n` in `p[n]` - * but because there's a strict comparison that compares `n` against the size of the allocation this - * snippet is fine. - */ -private module SizeBarrier { - private module SizeBarrierConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - // The sources is the same as in the sources for the second - // projection in the `AllocToInvalidPointerConfig` module. - hasSize(_, source, _) and - InterestingPointerAddInstruction::isInterestingSize(source) - } - - int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() } - - /** - * Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`. - */ - additional predicate isSink( - DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue - ) { - // The sink is any "large" side of a relational comparison. i.e., the `large` expression - // in a guard such as `small <= large + k`. - g.comparesLt(small.asOperand(), large.asOperand(), k + 1, true, testIsTrue) - } - - predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) } - } - - module SizeBarrierFlow = DataFlow::Global; - - private int getASizeAddend(DataFlow::Node node) { - exists(DataFlow::Node source | - SizeBarrierFlow::flow(source, node) and - hasSize(_, source, result) - ) - } - - /** - * Holds if `small <= large + k` holds if `g` evaluates to `edge`. - */ - private predicate operandGuardChecks( - IRGuardCondition g, Operand small, DataFlow::Node large, int k, boolean edge - ) { - SizeBarrierFlow::flowTo(large) and - SizeBarrierConfig::isSink(DataFlow::operandNode(small), large, g, k, edge) - } - - /** - * Gets an instruction `instr` that is guarded by a check such as `instr <= small + delta` where - * `small <= _ + k` and `small` is the "small side" of of a relational comparison that checks - * whether `small <= size` where `size` is the size of an allocation. - */ - Instruction getABarrierInstruction0(int delta, int k) { - exists( - IRGuardCondition g, ValueNumber value, Operand small, boolean edge, DataFlow::Node large - | - // We know: - // 1. result <= value + delta (by `bounded`) - // 2. value <= large + k (by `operandGuardChecks`). - // So: - // result <= value + delta (by 1.) - // <= large + k + delta (by 2.) - small = value.getAUse() and - operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](small), large, - pragma[only_bind_into](k), pragma[only_bind_into](edge)) and - bounded(result, value.getAnInstruction(), delta) and - g.controls(result.getBlock(), edge) and - k < getASizeAddend(large) - ) - } - - /** - * Gets an instruction that is guarded by a guard condition which ensures that - * the value of the instruction is upper-bounded by size of some allocation. - */ - bindingset[state] - pragma[inline_late] - Instruction getABarrierInstruction(int state) { - exists(int delta, int k | - state > k + delta and - // result <= "size of allocation" + delta + k - // < "size of allocation" + state - result = getABarrierInstruction0(delta, k) - ) - } - - /** - * Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that - * the value of the node is upper-bounded by size of some allocation. - */ - DataFlow::Node getABarrierNode(int state) { - exists(DataFlow::Node source, int delta, int k | - SizeBarrierFlow::flow(source, result) and - hasSize(_, source, state) and - result.asInstruction() = SizeBarrier::getABarrierInstruction0(delta, k) and - state > k + delta - // so now we have: - // result <= "size of allocation" + delta + k - // < "size of allocation" + state - ) - } -} - private module InterestingPointerAddInstruction { private module PointerAddInstructionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { @@ -227,7 +76,7 @@ private module InterestingPointerAddInstruction { hasSize(source.asExpr(), _, _) } - int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() } + predicate fieldFlowBranchLimit = allocationToInvalidPointerFieldFlowBranchLimit/0; predicate isSink(DataFlow::Node sink) { sink.asInstruction() = any(PointerAddInstruction pai).getLeft() @@ -263,6 +112,17 @@ private module InterestingPointerAddInstruction { } } +private module SizeBarrierInput implements SizeBarrierInputSig { + predicate fieldFlowBranchLimit = allocationToInvalidPointerFieldFlowBranchLimit/0; + + predicate isSource(DataFlow::Node source) { + // The sources is the same as in the sources for the second + // projection in the `AllocToInvalidPointerConfig` module. + hasSize(_, source, _) and + InterestingPointerAddInstruction::isInterestingSize(source) + } +} + /** * A product-flow configuration for flow from an `(allocation, size)` pair to a * pointer-arithmetic operation `pai` such that `pai <= allocation + size`. @@ -301,7 +161,7 @@ private module Config implements ProductFlow::StateConfigSig { private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate predicate isBarrier2(DataFlow::Node node, FlowState2 state) { - node = SizeBarrier::getABarrierNode(state) + node = SizeBarrier::getABarrierNode(state) } predicate isBarrier2(DataFlow::Node node) { @@ -357,8 +217,8 @@ private predicate pointerAddInstructionHasBounds0( sizeInstr = sizeSink.asInstruction() and // pai.getRight() <= sizeSink + delta bounded1(right, sizeInstr, delta) and - not right = SizeBarrier::getABarrierInstruction(delta) and - not sizeInstr = SizeBarrier::getABarrierInstruction(delta) + not right = SizeBarrier::getABarrierInstruction(delta) and + not sizeInstr = SizeBarrier::getABarrierInstruction(delta) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/security/ProductFlowUtils/ProductFlowUtils.qll b/cpp/ql/lib/semmle/code/cpp/security/ProductFlowUtils/ProductFlowUtils.qll new file mode 100644 index 000000000000..151c5d1ae22a --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/security/ProductFlowUtils/ProductFlowUtils.qll @@ -0,0 +1,167 @@ +/** + * This file provides the `SizeBarrier` module which provides barriers for + * both the `cpp/invalid-pointer-deref` query and the `cpp/overrun-write` + * query. + */ + +private import cpp +private import semmle.code.cpp.dataflow.new.DataFlow +private import semmle.code.cpp.ir.ValueNumbering +private import semmle.code.cpp.controlflow.IRGuards +private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil + +private VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result } + +/** + * Gets a (sub)expression that may be the result of evaluating `size`. + * + * For example, `getASizeCandidate(a ? b : c)` gives `a ? b : c`, `b` and `c`. + */ +bindingset[size] +pragma[inline_late] +private Expr getASizeCandidate(Expr size) { + result = size + or + result = [size.(ConditionalExpr).getThen(), size.(ConditionalExpr).getElse()] +} + +/** + * Holds if the `(n, state)` pair represents the source of flow for the size + * expression associated with `alloc`. + */ +predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) { + exists(VariableAccess va, Expr size, int delta, Expr s | + size = alloc.getSizeExpr() and + s = getASizeCandidate(size) and + // Get the unique variable in a size expression like `x` in `malloc(x + 1)`. + va = unique( | | getAVariableAccess(s)) and + // Compute `delta` as the constant difference between `x` and `x + 1`. + bounded1(any(Instruction instr | instr.getUnconvertedResultExpression() = s), + any(LoadInstruction load | load.getUnconvertedResultExpression() = va), delta) and + n.asExpr() = va and + state = delta + ) +} + +/** Provides the input specification of the `SizeBarrier` module. */ +signature module SizeBarrierInputSig { + /** Gets the virtual dispatch branching limit when calculating field flow. */ + int fieldFlowBranchLimit(); + + /** Holds if `source` is a relevant data flow source. */ + predicate isSource(DataFlow::Node source); +} + +/** + * A module that encapsulates a barrier guard to remove false positives from flow like: + * ```cpp + * char *p = new char[size]; + * // ... + * unsigned n = size; + * // ... + * if(n < size) { + * use(*p[n]); + * } + * ``` + * In this case, the sink pair identified by the product flow library (without any additional barriers) + * would be `(p, n)` (where `n` is the `n` in `p[n]`), because there exists a pointer-arithmetic + * instruction `pai = a + b` such that: + * 1. the allocation flows to `a`, and + * 2. `b <= n` where `n` is the `n` in `p[n]` + * but because there's a strict comparison that compares `n` against the size of the allocation this + * snippet is fine. + */ +module SizeBarrier { + private module SizeBarrierConfig implements DataFlow::ConfigSig { + predicate isSource = Input::isSource/1; + + predicate fieldFlowBranchLimit = Input::fieldFlowBranchLimit/0; + + /** + * Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`. + */ + additional predicate isSink( + DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue + ) { + // The sink is any "large" side of a relational comparison. i.e., the `large` expression + // in a guard such as `small <= large + k`. + g.comparesLt(small.asOperand(), large.asOperand(), k + 1, true, testIsTrue) + } + + predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) } + } + + private module SizeBarrierFlow = DataFlow::Global; + + private int getASizeAddend(DataFlow::Node node) { + exists(DataFlow::Node source | + SizeBarrierFlow::flow(source, node) and + hasSize(_, source, result) + ) + } + + /** + * Holds if `small <= large + k` holds if `g` evaluates to `edge`. + */ + private predicate operandGuardChecks( + IRGuardCondition g, Operand small, DataFlow::Node large, int k, boolean edge + ) { + SizeBarrierFlow::flowTo(large) and + SizeBarrierConfig::isSink(DataFlow::operandNode(small), large, g, k, edge) + } + + /** + * Gets an instruction `instr` that is guarded by a check such as `instr <= small + delta` where + * `small <= _ + k` and `small` is the "small side" of a relational comparison that checks + * whether `small <= size` where `size` is the size of an allocation. + */ + private Instruction getABarrierInstruction0(int delta, int k) { + exists( + IRGuardCondition g, ValueNumber value, Operand small, boolean edge, DataFlow::Node large + | + // We know: + // 1. result <= value + delta (by `bounded`) + // 2. value <= large + k (by `operandGuardChecks`). + // So: + // result <= value + delta (by 1.) + // <= large + k + delta (by 2.) + small = value.getAUse() and + operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](small), large, + pragma[only_bind_into](k), pragma[only_bind_into](edge)) and + bounded(result, value.getAnInstruction(), delta) and + g.controls(result.getBlock(), edge) and + k < getASizeAddend(large) + ) + } + + /** + * Gets an instruction that is guarded by a guard condition which ensures that + * the value of the instruction is upper-bounded by size of some allocation. + */ + bindingset[state] + pragma[inline_late] + Instruction getABarrierInstruction(int state) { + exists(int delta, int k | + state > k + delta and + // result <= "size of allocation" + delta + k + // < "size of allocation" + state + result = getABarrierInstruction0(delta, k) + ) + } + + /** + * Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that + * the value of the node is upper-bounded by size of some allocation. + */ + DataFlow::Node getABarrierNode(int state) { + exists(DataFlow::Node source, int delta, int k | + SizeBarrierFlow::flow(source, result) and + hasSize(_, source, state) and + result.asInstruction() = getABarrierInstruction0(delta, k) and + state > k + delta + // so now we have: + // result <= "size of allocation" + delta + k + // < "size of allocation" + state + ) + } +} diff --git a/cpp/ql/src/Best Practices/SloppyGlobal.ql b/cpp/ql/src/Best Practices/SloppyGlobal.ql index 4c1935627d52..b20e0271db87 100644 --- a/cpp/ql/src/Best Practices/SloppyGlobal.ql +++ b/cpp/ql/src/Best Practices/SloppyGlobal.ql @@ -14,6 +14,9 @@ import semmle.code.cpp.ConfigurationTestFile from GlobalVariable gv where gv.getName().length() <= 3 and + // We will give an alert for the TemplateVariable, so we don't + // need to also give one for each instantiation + not gv instanceof VariableTemplateInstantiation and not gv.isStatic() and not gv.getFile() instanceof ConfigurationTestFile // variables in files generated during configuration are likely false positives select gv, diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 7750db55e66e..589dfb68e1ef 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.5 + +### Minor Analysis Improvements + +* The "Initialization code not run" query (`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference. + ## 1.4.4 ### Minor Analysis Improvements diff --git a/cpp/ql/src/Critical/InitialisationNotRun.ql b/cpp/ql/src/Critical/InitialisationNotRun.ql index ba575c55921b..0b97b30fbd69 100644 --- a/cpp/ql/src/Critical/InitialisationNotRun.ql +++ b/cpp/ql/src/Critical/InitialisationNotRun.ql @@ -32,9 +32,18 @@ predicate called(Function f) { exists(FunctionAccess fa | fa.getTarget() = f) } +predicate staticWithoutDereference(GlobalVariable v) { + v.isStatic() and + not exists(VariableAccess va | + va = v.getAnAccess() and + dereferenced(va) + ) +} + from GlobalVariable v where global(v) and + not staticWithoutDereference(v) and not exists(VariableAccess lval | v.getAnAccess() = lval and lval.isUsedAsLValue() and diff --git a/cpp/ql/src/Critical/OverflowDestination.ql b/cpp/ql/src/Critical/OverflowDestination.ql index 4cfaaf8981b3..df14cafd1527 100644 --- a/cpp/ql/src/Critical/OverflowDestination.ql +++ b/cpp/ql/src/Critical/OverflowDestination.ql @@ -82,6 +82,16 @@ module OverflowDestinationConfig implements DataFlow::ConfigSig { nodeIsBarrierEqualityCandidate(node, access, checkedVar) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(FunctionCall fc | result = fc.getLocation() | + sourceSized(fc, sink.asIndirectConvertedExpr()) + ) + } } module OverflowDestination = TaintTracking::Global; diff --git a/cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql b/cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql index 62c3c98e197c..34817ff92295 100644 --- a/cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql +++ b/cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql @@ -168,6 +168,19 @@ module NonConstFlowConfig implements DataFlow::ConfigSig { cannotContainString(t) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + exists(FormattingFunctionCall call, Expr formatString | result = call.getLocation() | + isSinkImpl(sink, formatString) and + call.getArgument(call.getFormatParameterIndex()) = formatString + ) + } } module NonConstFlow = TaintTracking::Global; diff --git a/cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll b/cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll index 3cff86412e49..863fd1e61203 100644 --- a/cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll +++ b/cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll @@ -215,6 +215,10 @@ private module LeapYearCheckConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { exists(ChecksForLeapYearFunctionCall fc | sink.asExpr() = fc.getAnArgument()) } + + predicate observeDiffInformedIncrementalMode() { + none() // only used negatively in UncheckedLeapYearAfterYearModification.ql + } } module LeapYearCheckFlow = DataFlow::Global; @@ -285,6 +289,14 @@ private module PossibleYearArithmeticOperationCheckConfig implements DataFlow::C aexpr.getLValue() = fa ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { + result = source.asExpr().getLocation() + } + + Location getASelectedSinkLocation(DataFlow::Node sink) { result = sink.asExpr().getLocation() } } module PossibleYearArithmeticOperationCheckFlow = diff --git a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 94a9cacf9f49..1a15f6c3a152 100644 --- a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -93,6 +93,12 @@ module TaintedPathConfig implements DataFlow::ConfigSig { // make sinks barriers so that we only report the closest instance isSink(node) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.asIndirectArgument().getLocation() + } } module TaintedPath = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql index a609724937aa..1098656f7a20 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -150,6 +150,17 @@ module ExecTaintConfig implements DataFlow::StateConfigSig { predicate isBarrierOut(DataFlow::Node node) { isSink(node, _) // Prevent duplicates along a call chain, since `shellCommand` will include wrappers } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(DataFlow::Node concatResult, Expr command, ExecState state | + result = [concatResult.getLocation(), command.getLocation()] and + isSink(sink, state) and + isSinkImpl(sink, command, _) and + concatResult = state.getOutgoingNode() + ) + } } module ExecTaint = TaintTracking::GlobalWithState; diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql index 9b27e95fd658..994aba733d23 100644 --- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql +++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql @@ -39,6 +39,12 @@ module Config implements DataFlow::ConfigSig { or node.asCertainDefinition().getUnspecifiedType() instanceof ArithmeticType } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { + exists(QueryString query | result = query.getLocation() | query = source.asIndirectExpr()) + } } module Flow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql index 0ea4ce2e95f4..5a823b8672c5 100644 --- a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -54,6 +54,12 @@ module SqlTaintedConfig implements DataFlow::ConfigSig { sql.barrierSqlArgument(input, _) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(Expr taintedArg | result = taintedArg.getLocation() | taintedArg = asSinkExpr(sink)) + } } module SqlTainted = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql index b193b846b5a8..c2ebb4879a99 100644 --- a/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql +++ b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql @@ -20,6 +20,7 @@ import semmle.code.cpp.models.interfaces.Allocation import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific +import semmle.code.cpp.security.ProductFlowUtils.ProductFlowUtils import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil import StringSizeFlow::PathGraph1 import codeql.util.Unit @@ -43,20 +44,28 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) { ) } -predicate isSinkPairImpl( - CallInstruction c, DataFlow::Node bufSink, DataFlow::Node sizeSink, int delta, Expr eBuf +/** + * Holds if `c` a call to an `ArrayFunction` with buffer argument `bufSink`, + * and a size argument `sizeInstr` which satisfies `sizeInstr <= sizeBound + delta`. + * + * Furthermore, the `sizeSink` node is the dataflow node corresponding to + * `sizeBound`, and the expression `eBuf` is the expression corresponding + * to `bufInstr`. + */ +predicate isSinkPairImpl0( + CallInstruction c, DataFlow::Node bufSink, DataFlow::Node sizeSink, int delta, Expr eBuf, + Instruction sizeBound, Instruction sizeInstr ) { - exists( - int bufIndex, int sizeIndex, Instruction sizeInstr, Instruction bufInstr, ArrayFunction func - | + exists(int bufIndex, int sizeIndex, Instruction bufInstr, ArrayFunction func | bufInstr = bufSink.asInstruction() and c.getArgument(bufIndex) = bufInstr and - sizeInstr = sizeSink.asInstruction() and + sizeBound = sizeSink.asInstruction() and + c.getArgument(sizeIndex) = sizeInstr and c.getStaticCallTarget() = func and pragma[only_bind_into](func) .hasArrayWithVariableSize(pragma[only_bind_into](bufIndex), pragma[only_bind_into](sizeIndex)) and - bounded(c.getArgument(sizeIndex), sizeInstr, delta) and + bounded(sizeInstr, sizeBound, delta) and eBuf = bufInstr.getUnconvertedResultExpression() ) } @@ -86,99 +95,39 @@ module ValidState { private module ValidStateConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { hasSize(_, source, _) } - predicate isSink(DataFlow::Node sink) { isSinkPairImpl(_, _, sink, _, _) } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - isAdditionalFlowStep2(node1, node2, _) - } + predicate isSink(DataFlow::Node sink) { isSinkPairImpl0(_, _, sink, _, _, _, _) } - predicate includeHiddenNodes() { any() } + predicate isBarrierOut(DataFlow::Node node) { DataFlow::flowsToBackEdge(node) } } private import DataFlow::Global - private predicate inLoop(PathNode n) { n.getASuccessor+() = n } - - /** - * Holds if `value` is a possible offset for `n`. - * - * To ensure termination, we limit `value` to be in the - * range `[-2, 2]` if the node is part of a loop. Without - * this restriction we wouldn't terminate on an example like: - * ```cpp - * while(unknown()) { size++; } - * ``` - */ - private predicate validStateImpl(PathNode n, int value) { - // If the dataflow node depends recursively on itself we restrict the range. - (inLoop(n) implies value = [-2 .. 2]) and - ( - // For the dataflow source we have an allocation such as `malloc(size + k)`, - // and the value of the flow-state is then `k`. - hasSize(_, n.getNode(), value) - or - // For a dataflow sink any `value` that is strictly smaller than the delta - // needs to be a valid flow-state. That is, for a snippet like: - // ``` - // p = b ? new char[size] : new char[size + 1]; - // memset(p, 0, size + 2); - // ``` - // the valid flow-states at the `memset` must include the set `{0, 1}` since the - // flow-state at `new char[size]` is `0`, and the flow-state at `new char[size + 1]` - // is `1`. - // - // So we find a valid flow-state at the sink's predecessor, and use the definition - // of our sink predicate to compute the valid flow-states at the sink. - exists(int delta, PathNode n0 | - n0.getASuccessor() = n and - validStateImpl(n0, value) and - isSinkPairImpl(_, _, n.getNode(), delta, _) and - delta > value - ) - or - // For a non-source and non-sink node there is two cases to consider. - // 1. A node where we have to update the flow-state, or - // 2. A node that doesn't update the flow-state. - // - // For case 1, we compute the new flow-state by adding the constant operand of the - // `AddInstruction` to the flow-state of any predecessor node. - // For case 2 we simply propagate the valid flow-states from the predecessor node to - // the next one. - exists(PathNode n0, DataFlow::Node node0, DataFlow::Node node, int value0 | - n0.getASuccessor() = n and - validStateImpl(n0, value0) and - node = n.getNode() and - node0 = n0.getNode() - | - exists(int delta | - isAdditionalFlowStep2(node0, node, delta) and - value0 = value + delta - ) - or - not isAdditionalFlowStep2(node0, node, _) and - value = value0 - ) - ) - } - - predicate validState(DataFlow::Node n, int value) { - validStateImpl(any(PathNode pn | pn.getNode() = n), value) + predicate validState(DataFlow::Node source, DataFlow::Node sink, int value) { + hasSize(_, source, value) and + flow(source, sink) } } import ValidState -/** - * Holds if `node2` is a dataflow node that represents an addition of two operands `op1` - * and `op2` such that: - * 1. `node1` is the dataflow node that represents `op1`, and - * 2. the value of `op2` can be upper bounded by `delta.` - */ -predicate isAdditionalFlowStep2(DataFlow::Node node1, DataFlow::Node node2, int delta) { - exists(AddInstruction add, Operand op | - add.hasOperands(node1.asOperand(), op) and - semBounded(getSemanticExpr(op.getDef()), any(SemZeroBound zero), delta, true, _) and - node2.asInstruction() = add +module SizeBarrierInput implements SizeBarrierInputSig { + int fieldFlowBranchLimit() { result = 2 } + + predicate isSource(DataFlow::Node source) { + exists(int state | + hasSize(_, source, state) and + validState(source, _, state) + ) + } +} + +predicate isSinkPairImpl( + CallInstruction c, DataFlow::Node bufSink, DataFlow::Node sizeSink, int delta, Expr eBuf +) { + exists(Instruction sizeBound, Instruction sizeInstr | + isSinkPairImpl0(c, bufSink, sizeSink, delta, eBuf, sizeBound, sizeInstr) and + not sizeBound = SizeBarrier::getABarrierInstruction(delta) and + not sizeInstr = SizeBarrier::getABarrierInstruction(delta) ) } @@ -198,14 +147,14 @@ module StringSizeConfig implements ProductFlow::StateConfigSig { // to the size of the allocation. This state is then checked in `isSinkPair`. exists(state1) and hasSize(bufSource.asExpr(), sizeSource, state2) and - validState(sizeSource, state2) + validState(sizeSource, _, state2) } predicate isSinkPair( DataFlow::Node bufSink, FlowState1 state1, DataFlow::Node sizeSink, FlowState2 state2 ) { exists(state1) and - validState(sizeSink, state2) and + validState(_, sizeSink, state2) and exists(int delta | isSinkPairImpl(_, bufSink, sizeSink, delta, _) and delta > state2 @@ -214,14 +163,8 @@ module StringSizeConfig implements ProductFlow::StateConfigSig { predicate isBarrierOut2(DataFlow::Node node) { DataFlow::flowsToBackEdge(node) } - predicate isAdditionalFlowStep2( - DataFlow::Node node1, FlowState2 state1, DataFlow::Node node2, FlowState2 state2 - ) { - validState(node2, state2) and - exists(int delta | - isAdditionalFlowStep2(node1, node2, delta) and - state1 = state2 + delta - ) + predicate isBarrier2(DataFlow::Node node, FlowState2 state) { + node = SizeBarrier::getABarrierNode(state) } } diff --git a/cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql b/cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql index ec3543c19928..2cce72bc2ae8 100644 --- a/cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql @@ -124,6 +124,12 @@ module Config implements DataFlow::ConfigSig { // Block flow if the node is guarded by any <, <= or = operations. node = DataFlow::BarrierGuard::getABarrierNode() } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(BufferWrite bw | result = bw.getLocation() | isSink(sink, bw, _)) + } } module Flow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql b/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql index 9b595657fce9..2f051776dbe2 100644 --- a/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql @@ -43,6 +43,12 @@ private module Config implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node sink) { isSink(sink, _) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(VariableAccess va | result = va.getLocation() | isSink(sink, va)) + } } module Flow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql index c9efaf9f6952..86806c0b7762 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql @@ -106,6 +106,12 @@ module Config implements DataFlow::ConfigSig { not iTo instanceof PointerArithmeticInstruction ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(Expr e | result = e.getLocation() | isSink(sink, _, e)) + } } module Flow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql index 54c3b013471a..64705f078c69 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql @@ -120,6 +120,12 @@ module UncontrolledArithConfig implements DataFlow::ConfigSig { // block unintended flow to pointers node.asExpr().getUnspecifiedType() instanceof PointerType } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { + result = getExpr(source).getLocation() + } } module UncontrolledArith = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql index 15fd2cbca15f..50cef092600b 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql @@ -113,6 +113,12 @@ module Config implements DataFlow::ConfigSig { not iTo instanceof PointerArithmeticInstruction ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(VariableAccess va | result = va.getLocation() | isSink(sink, va, _)) + } } module Flow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql b/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql index 6307ddf5fe63..0149f483cc12 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql @@ -91,6 +91,12 @@ module TaintedAllocationSizeConfig implements DataFlow::ConfigSig { // to duplicate results) any(HeuristicAllocationFunction f).getAParameter() = node.asParameter() } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(Expr alloc | result = alloc.getLocation() | allocSink(alloc, sink)) + } } module TaintedAllocationSize = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql b/cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql index ada0180668e0..74386b30bbab 100644 --- a/cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql +++ b/cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql @@ -72,6 +72,12 @@ module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { isSource(source, _) } predicate isSink(DataFlow::Node sink) { isSink(sink, _) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(Expr condition | result = condition.getLocation() | isSink(sink, condition)) + } } module Flow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql b/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql index 8a3c2f3664d6..379c20f51baf 100644 --- a/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql +++ b/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql @@ -31,6 +31,14 @@ module VerifyResultConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { exists(GuardCondition guard | guard.getAChild*() = sink.asExpr()) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(GuardCondition guard | result = guard.getLocation() | + guard.comparesEq(sink.asExpr(), _, 0, false, _) + ) + } } module VerifyResult = DataFlow::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql index f2754c5811f0..c671ad5af7f2 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql @@ -47,6 +47,12 @@ module ToBufferConfig implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(SensitiveBufferWrite w | result = w.getLocation() | isSinkImpl(sink, w)) + } } module ToBufferFlow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql index c04ceae7adad..6aff19ceb4af 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql @@ -31,6 +31,16 @@ module FromSensitiveConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node.asExpr().getUnspecifiedType() instanceof IntegralType } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node sourceNode) { + exists(SensitiveExpr source | result = source.getLocation() | isSourceImpl(sourceNode, source)) + } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(FileWrite w | result = w.getLocation() | isSinkImpl(sink, w, _)) + } } module FromSensitiveFlow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql index 09db3f216029..10bb10d6a2bb 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql @@ -245,6 +245,14 @@ module FromSensitiveConfig implements DataFlow::ConfigSig { // sources to not get path duplication. isSource(node) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(NetworkSendRecv networkSendRecv | result = networkSendRecv.getLocation() | + isSinkSendRecv(sink, networkSendRecv) + ) + } } module FromSensitiveFlow = TaintTracking::Global; @@ -266,6 +274,10 @@ module ToEncryptionConfig implements DataFlow::ConfigSig { // sources to not get path duplication. isSource(node) } + + predicate observeDiffInformedIncrementalMode() { + none() // only used negatively + } } module ToEncryptionFlow = TaintTracking::Global; @@ -281,6 +293,10 @@ module FromEncryptionConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node.asExpr().getUnspecifiedType() instanceof IntegralType } + + predicate observeDiffInformedIncrementalMode() { + none() // only used negatively + } } module FromEncryptionFlow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql b/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql index 0c060befeff5..a6f567600f9d 100644 --- a/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql +++ b/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql @@ -123,6 +123,20 @@ module FromSensitiveConfig implements DataFlow::ConfigSig { content.(DataFlow::FieldContent).getField() = getRecField(t.stripType()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { + exists(SensitiveExpr sensitive | result = sensitive.getLocation() | + isSourceImpl(source, sensitive) + ) + } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(SqliteFunctionCall sqliteCall | result = sqliteCall.getLocation() | + isSinkImpl(sink, sqliteCall, _) + ) + } } module FromSensitiveFlow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql b/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql index 423ed57dd98f..d12340035bde 100644 --- a/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql +++ b/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql @@ -87,6 +87,14 @@ module HttpStringToUrlOpenConfig implements DataFlow::ConfigSig { sink.asIndirectExpr() = fc.getArgument(3) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { + result = source.asIndirectExpr().getLocation() + } + + Location getASelectedSinkLocation(DataFlow::Node sink) { none() } } module HttpStringToUrlOpen = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql index 3cc10b7ad19c..9f75475854dc 100644 --- a/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql +++ b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql @@ -44,6 +44,12 @@ module KeyStrengthFlowConfig implements DataFlow::ConfigSig { exists(getMinimumKeyStrength(name, param)) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(FunctionCall fc | result = fc.getLocation() | sink.asExpr() = fc.getArgument(_)) + } } module KeyStrengthFlow = DataFlow::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql index 11d628c1affa..c386cb1da4d8 100644 --- a/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql +++ b/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql @@ -145,6 +145,18 @@ module Config implements DataFlow::StateConfigSig { // ``` result instanceof DataFlow::FeatureHasSinkCallContext } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(DataFlow::Node mid, FlowState state | result = mid.getLocation() | + destroyedToBeginSink(sink) and + isSink(sink, state) and + state = Config::DestroyedToBegin(mid) + ) + } } module Flow = DataFlow::GlobalWithState; diff --git a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql index 2703f819b546..f0851b7d8075 100644 --- a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql +++ b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql @@ -62,6 +62,16 @@ module NullAppNameCreateProcessFunctionConfig implements DataFlow::ConfigSig { val = call.getArgument(call.getApplicationNameArgumentId()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(CreateProcessFunctionCall call | result = call.getLocation() | + sink.asExpr() = call.getArgument(call.getApplicationNameArgumentId()) + ) + } } module NullAppNameCreateProcessFunction = DataFlow::Global; @@ -82,6 +92,16 @@ module QuotedCommandInCreateProcessFunctionConfig implements DataFlow::ConfigSig val = call.getArgument(call.getCommandLineArgumentId()) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(CreateProcessFunctionCall call | result = call.getLocation() | + sink.asExpr() = call.getArgument(call.getCommandLineArgumentId()) + ) + } } module QuotedCommandInCreateProcessFunction = diff --git a/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql b/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql index 5ed30e19bb32..a0096f410c51 100644 --- a/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql +++ b/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql @@ -37,6 +37,16 @@ module NullDaclConfig implements DataFlow::ConfigSig { val = call.getArgument(2) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(SetSecurityDescriptorDaclFunctionCall call | result = call.getLocation() | + sink.asExpr() = call.getArgument(2) + ) + } } module NullDaclFlow = DataFlow::Global; @@ -68,6 +78,10 @@ module NonNullDaclConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { exists(SetSecurityDescriptorDaclFunctionCall call | sink.asExpr() = call.getArgument(2)) } + + predicate observeDiffInformedIncrementalMode() { + none() // only used negatively + } } module NonNullDaclFlow = DataFlow::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-807/TaintedCondition.ql b/cpp/ql/src/Security/CWE/CWE-807/TaintedCondition.ql index 7eaa5df849d4..171fbd26dd93 100644 --- a/cpp/ql/src/Security/CWE/CWE-807/TaintedCondition.ql +++ b/cpp/ql/src/Security/CWE/CWE-807/TaintedCondition.ql @@ -65,6 +65,16 @@ module Config implements DataFlow::ConfigSig { iFrom1 != iFrom2 ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + exists(Expr raise | result = raise.getLocation() | + sensitiveCondition([sink.asExpr(), sink.asIndirectExpr()], raise) + ) + } } module Flow = TaintTracking::Global; diff --git a/cpp/ql/src/Security/CWE/CWE-843/TypeConfusion.ql b/cpp/ql/src/Security/CWE/CWE-843/TypeConfusion.ql index acfd27cc45ba..4ca30c3e916a 100644 --- a/cpp/ql/src/Security/CWE/CWE-843/TypeConfusion.ql +++ b/cpp/ql/src/Security/CWE/CWE-843/TypeConfusion.ql @@ -178,6 +178,10 @@ module Config implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(UnsafeCast cast).getUnconverted() } int fieldFlowBranchLimit() { result = 0 } + + predicate observeDiffInformedIncrementalMode() { + none() // used both positively and negatively + } } module Flow = DataFlow::Global; diff --git a/cpp/ql/src/change-notes/2025-08-08-overflow-buffer.md b/cpp/ql/src/change-notes/2025-08-08-overflow-buffer.md new file mode 100644 index 000000000000..02c73804c9f0 --- /dev/null +++ b/cpp/ql/src/change-notes/2025-08-08-overflow-buffer.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Fixed a false positive in `cpp/overflow-buffer` when the type of the destination buffer is a reference to a class/struct type. \ No newline at end of file diff --git a/cpp/ql/src/change-notes/2025-08-15-short-global-name-template-instantiations.md b/cpp/ql/src/change-notes/2025-08-15-short-global-name-template-instantiations.md new file mode 100644 index 000000000000..8a8f54c73372 --- /dev/null +++ b/cpp/ql/src/change-notes/2025-08-15-short-global-name-template-instantiations.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `cpp/short-global-name` query will no longer give alerts for instantiations of template variables, only for the template itself. diff --git a/cpp/ql/src/change-notes/released/1.4.5.md b/cpp/ql/src/change-notes/released/1.4.5.md new file mode 100644 index 000000000000..2b606677eba6 --- /dev/null +++ b/cpp/ql/src/change-notes/released/1.4.5.md @@ -0,0 +1,5 @@ +## 1.4.5 + +### Minor Analysis Improvements + +* The "Initialization code not run" query (`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 1dfca6daa3b1..a74b6b08d860 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.4.4 +lastReleaseVersion: 1.4.5 diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql index c38a012b27bf..b7b2de6000ae 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -183,6 +183,20 @@ module ArrayAddressToDerefConfig implements DataFlow::StateConfigSig { pointerArithOverflow(pai, _) ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { + exists(Variable v | result = v.getLocation() | isSourceImpl(source, v)) + } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(PointerArithmeticInstruction pai, Instruction deref | + result = [pai, deref].getLocation() and + isInvalidPointerDerefSink2(sink, deref, _) and + isSink(sink, ArrayAddressToDerefConfig::TOverflowArithmetic(pai)) + ) + } } module ArrayAddressToDerefFlow = DataFlow::GlobalWithState; diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409/DecompressionBombs.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409/DecompressionBombs.ql index bfa11e65b067..fbeb4cde5fd1 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409/DecompressionBombs.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409/DecompressionBombs.ql @@ -28,6 +28,14 @@ module DecompressionTaintConfig implements DataFlow::ConfigSig { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { any(DecompressionFlowStep s).isAdditionalFlowStep(node1, node2) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(FunctionCall fc | result = [sink.getLocation(), fc.getLocation()] | isSink(fc, sink)) + } } module DecompressionTaint = TaintTracking::Global; diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index c77f630faad6..ad3dc6c91f9e 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.4.4 +version: 1.4.6-dev groups: - cpp - queries diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected index e848b76946f3..70290c7e2260 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected @@ -44,6 +44,8 @@ | test.c:198:8:198:8 | b | | test.c:206:7:206:8 | ! ... | | test.c:206:8:206:8 | c | +| test.c:215:6:215:18 | call to __builtin_expect | +| test.c:219:9:219:22 | call to __builtin_expect | | test.cpp:18:8:18:10 | call to get | | test.cpp:31:7:31:13 | ... == ... | | test.cpp:42:13:42:20 | call to getABool | @@ -92,3 +94,15 @@ | test.cpp:241:9:241:43 | ... && ... | | test.cpp:241:22:241:30 | ... == ... | | test.cpp:241:35:241:43 | ... == ... | +| test.cpp:247:6:247:18 | ... == ... | +| test.cpp:253:6:253:18 | ... != ... | +| test.cpp:260:6:260:18 | ... == ... | +| test.cpp:266:6:266:18 | ... != ... | +| test.cpp:273:6:273:17 | ... == ... | +| test.cpp:279:6:279:17 | ... != ... | +| test.cpp:287:6:287:19 | ... == ... | +| test.cpp:293:6:293:19 | ... != ... | +| test.cpp:300:6:300:19 | ... == ... | +| test.cpp:306:6:306:19 | ... != ... | +| test.cpp:312:6:312:18 | ... == ... | +| test.cpp:318:6:318:18 | ... != ... | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index 1ae797bfe1eb..5d3232d50faa 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -1,768 +1,1039 @@ -| 7 | 0 < x+0 when ... > ... is true | -| 7 | 0 >= x+0 when ... > ... is false | -| 7 | ... > ... != 0 when ... > ... is true | -| 7 | ... > ... != 1 when ... > ... is false | -| 7 | ... > ... == 0 when ... > ... is false | -| 7 | ... > ... == 1 when ... > ... is true | -| 7 | x < 0+1 when ... > ... is false | -| 7 | x < 1 when ... > ... is false | -| 7 | x >= 0+1 when ... > ... is true | -| 7 | x >= 1 when ... > ... is true | -| 17 | 0 < x+1 when ... < ... is false | -| 17 | 0 >= x+1 when ... && ... is true | -| 17 | 0 >= x+1 when ... < ... is true | -| 17 | 1 < y+0 when ... && ... is true | -| 17 | 1 < y+0 when ... > ... is true | -| 17 | 1 >= y+0 when ... > ... is false | -| 17 | ... < ... != 0 when ... && ... is true | -| 17 | ... < ... != 0 when ... < ... is true | -| 17 | ... < ... != 1 when ... < ... is false | -| 17 | ... < ... == 0 when ... < ... is false | -| 17 | ... < ... == 1 when ... && ... is true | -| 17 | ... < ... == 1 when ... < ... is true | -| 17 | ... > ... != 0 when ... && ... is true | -| 17 | ... > ... != 0 when ... > ... is true | -| 17 | ... > ... != 1 when ... > ... is false | -| 17 | ... > ... == 0 when ... > ... is false | -| 17 | ... > ... == 1 when ... && ... is true | -| 17 | ... > ... == 1 when ... > ... is true | -| 17 | x < 0 when ... && ... is true | -| 17 | x < 0 when ... < ... is true | -| 17 | x < 0+0 when ... && ... is true | -| 17 | x < 0+0 when ... < ... is true | -| 17 | x >= 0 when ... < ... is false | -| 17 | x >= 0+0 when ... < ... is false | -| 17 | y < 1+1 when ... > ... is false | -| 17 | y < 2 when ... > ... is false | -| 17 | y >= 1+1 when ... && ... is true | -| 17 | y >= 1+1 when ... > ... is true | -| 17 | y >= 2 when ... && ... is true | -| 17 | y >= 2 when ... > ... is true | -| 18 | call to get != 0 when call to get is true | -| 18 | call to get != 1 when call to get is false | -| 18 | call to get == 0 when call to get is false | -| 18 | call to get == 1 when call to get is true | -| 26 | 0 < x+0 when ... > ... is true | -| 26 | 0 >= x+0 when ... > ... is false | -| 26 | ... > ... != 0 when ... > ... is true | -| 26 | ... > ... != 1 when ... > ... is false | -| 26 | ... > ... == 0 when ... > ... is false | -| 26 | ... > ... == 1 when ... > ... is true | -| 26 | x < 0+1 when ... > ... is false | -| 26 | x < 1 when ... > ... is false | -| 26 | x >= 0+1 when ... > ... is true | -| 26 | x >= 1 when ... > ... is true | -| 31 | - ... != x+0 when ... == ... is false | -| 31 | - ... == x+0 when ... == ... is true | -| 31 | ... == ... != 0 when ... == ... is true | -| 31 | ... == ... != 1 when ... == ... is false | -| 31 | ... == ... == 0 when ... == ... is false | -| 31 | ... == ... == 1 when ... == ... is true | -| 31 | x != -1 when ... == ... is false | -| 31 | x != - ...+0 when ... == ... is false | -| 31 | x == -1 when ... == ... is true | -| 31 | x == - ...+0 when ... == ... is true | -| 34 | 10 < j+1 when ... < ... is false | -| 34 | 10 >= j+1 when ... < ... is true | -| 34 | ... < ... != 0 when ... < ... is true | -| 34 | ... < ... != 1 when ... < ... is false | -| 34 | ... < ... == 0 when ... < ... is false | -| 34 | ... < ... == 1 when ... < ... is true | -| 34 | j < 10 when ... < ... is true | -| 34 | j < 10+0 when ... < ... is true | -| 34 | j >= 10 when ... < ... is false | -| 34 | j >= 10+0 when ... < ... is false | -| 42 | 10 < j+1 when ... < ... is false | -| 42 | 10 >= j+1 when ... < ... is true | -| 42 | ... < ... != 0 when ... < ... is true | -| 42 | ... < ... != 1 when ... < ... is false | -| 42 | ... < ... == 0 when ... < ... is false | -| 42 | ... < ... == 1 when ... < ... is true | -| 42 | call to getABool != 0 when call to getABool is true | -| 42 | call to getABool != 1 when call to getABool is false | -| 42 | call to getABool == 0 when call to getABool is false | -| 42 | call to getABool == 1 when call to getABool is true | -| 42 | j < 10 when ... < ... is true | -| 42 | j < 10+0 when ... < ... is true | -| 42 | j >= 10 when ... < ... is false | -| 42 | j >= 10+0 when ... < ... is false | -| 44 | 0 < z+0 when ... > ... is true | -| 44 | 0 >= z+0 when ... > ... is false | -| 44 | ... > ... != 0 when ... > ... is true | -| 44 | ... > ... != 1 when ... > ... is false | -| 44 | ... > ... == 0 when ... > ... is false | -| 44 | ... > ... == 1 when ... > ... is true | -| 44 | z < 0+1 when ... > ... is false | -| 44 | z < 1 when ... > ... is false | -| 44 | z >= 0+1 when ... > ... is true | -| 44 | z >= 1 when ... > ... is true | -| 45 | 0 < y+0 when ... > ... is true | -| 45 | 0 >= y+0 when ... > ... is false | -| 45 | ... > ... != 0 when ... > ... is true | -| 45 | ... > ... != 1 when ... > ... is false | -| 45 | ... > ... == 0 when ... > ... is false | -| 45 | ... > ... == 1 when ... > ... is true | -| 45 | y < 0+1 when ... > ... is false | -| 45 | y < 1 when ... > ... is false | -| 45 | y >= 0+1 when ... > ... is true | -| 45 | y >= 1 when ... > ... is true | -| 58 | 0 != x+0 when ... == ... is false | -| 58 | 0 != x+0 when ... \|\| ... is false | -| 58 | 0 < y+1 when ... < ... is false | -| 58 | 0 < y+1 when ... \|\| ... is false | -| 58 | 0 == x+0 when ... == ... is true | -| 58 | 0 >= y+1 when ... < ... is true | -| 58 | ... < ... != 0 when ... < ... is true | -| 58 | ... < ... != 1 when ... < ... is false | -| 58 | ... < ... != 1 when ... \|\| ... is false | -| 58 | ... < ... == 0 when ... < ... is false | -| 58 | ... < ... == 0 when ... \|\| ... is false | -| 58 | ... < ... == 1 when ... < ... is true | -| 58 | ... == ... != 0 when ... == ... is true | -| 58 | ... == ... != 1 when ... == ... is false | -| 58 | ... == ... != 1 when ... \|\| ... is false | -| 58 | ... == ... == 0 when ... == ... is false | -| 58 | ... == ... == 0 when ... \|\| ... is false | -| 58 | ... == ... == 1 when ... == ... is true | -| 58 | x != 0 when ... == ... is false | -| 58 | x != 0 when ... \|\| ... is false | -| 58 | x != 0+0 when ... == ... is false | -| 58 | x != 0+0 when ... \|\| ... is false | -| 58 | x == 0 when ... == ... is true | -| 58 | x == 0+0 when ... == ... is true | -| 58 | y < 0 when ... < ... is true | -| 58 | y < 0+0 when ... < ... is true | -| 58 | y >= 0 when ... < ... is false | -| 58 | y >= 0 when ... \|\| ... is false | -| 58 | y >= 0+0 when ... < ... is false | -| 58 | y >= 0+0 when ... \|\| ... is false | -| 61 | i == 0 when i is Case[0] | -| 61 | i == 1 when i is Case[1] | -| 61 | i == 2 when i is Case[2] | -| 74 | i < 11 when i is Case[0..10] | -| 74 | i < 21 when i is Case[11..20] | -| 74 | i >= 0 when i is Case[0..10] | -| 74 | i >= 11 when i is Case[11..20] | -| 75 | 0 != x+0 when ... == ... is false | -| 75 | 0 == x+0 when ... == ... is true | -| 75 | ... == ... != 0 when ... == ... is true | -| 75 | ... == ... != 1 when ... == ... is false | -| 75 | ... == ... == 0 when ... == ... is false | -| 75 | ... == ... == 1 when ... == ... is true | -| 75 | x != 0 when ... == ... is false | -| 75 | x != 0+0 when ... == ... is false | -| 75 | x == 0 when ... == ... is true | -| 75 | x == 0+0 when ... == ... is true | -| 85 | 0 != x+0 when ... == ... is false | -| 85 | 0 != y+0 when ... != ... is true | -| 85 | 0 != y+0 when ... && ... is true | -| 85 | 0 == x+0 when ... && ... is true | -| 85 | 0 == x+0 when ... == ... is true | -| 85 | 0 == y+0 when ... != ... is false | -| 85 | ... != ... != 0 when ... != ... is true | -| 85 | ... != ... != 0 when ... && ... is true | -| 85 | ... != ... != 1 when ... != ... is false | -| 85 | ... != ... == 0 when ... != ... is false | -| 85 | ... != ... == 1 when ... != ... is true | -| 85 | ... != ... == 1 when ... && ... is true | -| 85 | ... == ... != 0 when ... && ... is true | -| 85 | ... == ... != 0 when ... == ... is true | -| 85 | ... == ... != 1 when ... == ... is false | -| 85 | ... == ... == 0 when ... == ... is false | -| 85 | ... == ... == 1 when ... && ... is true | -| 85 | ... == ... == 1 when ... == ... is true | -| 85 | x != 0 when ... == ... is false | -| 85 | x != 0+0 when ... == ... is false | -| 85 | x == 0 when ... && ... is true | -| 85 | x == 0 when ... == ... is true | -| 85 | x == 0+0 when ... && ... is true | -| 85 | x == 0+0 when ... == ... is true | -| 85 | y != 0 when ... != ... is true | -| 85 | y != 0 when ... && ... is true | -| 85 | y != 0+0 when ... != ... is true | -| 85 | y != 0+0 when ... && ... is true | -| 85 | y == 0 when ... != ... is false | -| 85 | y == 0+0 when ... != ... is false | -| 93 | c != 0 when c is true | -| 93 | c != 1 when c is false | -| 93 | c == 0 when c is false | -| 93 | c == 1 when c is true | -| 94 | 0 != x+0 when ... != ... is true | -| 94 | 0 == x+0 when ... != ... is false | -| 94 | ... != ... != 0 when ... != ... is true | -| 94 | ... != ... != 1 when ... != ... is false | -| 94 | ... != ... == 0 when ... != ... is false | -| 94 | ... != ... == 1 when ... != ... is true | -| 94 | x != 0 when ... != ... is true | -| 94 | x != 0+0 when ... != ... is true | -| 94 | x == 0 when ... != ... is false | -| 94 | x == 0+0 when ... != ... is false | -| 99 | f != 0 when f is true | -| 99 | f != 1 when f is false | -| 99 | f == 0 when f is false | -| 99 | f == 1 when f is true | -| 102 | 10 < j+1 when ... < ... is false | -| 102 | 10 >= j+1 when ... < ... is true | -| 102 | ... < ... != 0 when ... < ... is true | -| 102 | ... < ... != 1 when ... < ... is false | -| 102 | ... < ... == 0 when ... < ... is false | -| 102 | ... < ... == 1 when ... < ... is true | -| 102 | j < 10 when ... < ... is true | -| 102 | j < 10+0 when ... < ... is true | -| 102 | j >= 10 when ... < ... is false | -| 102 | j >= 10+0 when ... < ... is false | -| 105 | 0.0 != f+0 when ... != ... is true | -| 105 | 0.0 == f+0 when ... != ... is false | -| 105 | ... != ... != 0 when ... != ... is true | -| 105 | ... != ... != 1 when ... != ... is false | -| 105 | ... != ... == 0 when ... != ... is false | -| 105 | ... != ... == 1 when ... != ... is true | -| 105 | f != 0.0+0 when ... != ... is true | -| 105 | f == 0.0+0 when ... != ... is false | -| 109 | 0 != x+0 when ... == ... is false | -| 109 | 0 != x+0 when ... \|\| ... is false | -| 109 | 0 < y+1 when ... < ... is false | -| 109 | 0 < y+1 when ... \|\| ... is false | -| 109 | 0 == x+0 when ... == ... is true | -| 109 | 0 >= y+1 when ... < ... is true | -| 109 | ... < ... != 0 when ... < ... is true | -| 109 | ... < ... != 1 when ... < ... is false | -| 109 | ... < ... != 1 when ... \|\| ... is false | -| 109 | ... < ... == 0 when ... < ... is false | -| 109 | ... < ... == 0 when ... \|\| ... is false | -| 109 | ... < ... == 1 when ... < ... is true | -| 109 | ... == ... != 0 when ... == ... is true | -| 109 | ... == ... != 1 when ... == ... is false | -| 109 | ... == ... != 1 when ... \|\| ... is false | -| 109 | ... == ... == 0 when ... == ... is false | -| 109 | ... == ... == 0 when ... \|\| ... is false | -| 109 | ... == ... == 1 when ... == ... is true | -| 109 | x != 0 when ... == ... is false | -| 109 | x != 0 when ... \|\| ... is false | -| 109 | x != 0+0 when ... == ... is false | -| 109 | x != 0+0 when ... \|\| ... is false | -| 109 | x == 0 when ... == ... is true | -| 109 | x == 0+0 when ... == ... is true | -| 109 | y < 0 when ... < ... is true | -| 109 | y < 0+0 when ... < ... is true | -| 109 | y >= 0 when ... < ... is false | -| 109 | y >= 0 when ... \|\| ... is false | -| 109 | y >= 0+0 when ... < ... is false | -| 109 | y >= 0+0 when ... \|\| ... is false | -| 111 | 0.0 != i+0 when ... != ... is true | -| 111 | 0.0 == i+0 when ... != ... is false | -| 111 | ... != ... != 0 when ... != ... is true | -| 111 | ... != ... != 1 when ... != ... is false | -| 111 | ... != ... == 0 when ... != ... is false | -| 111 | ... != ... == 1 when ... != ... is true | -| 111 | i != 0.0+0 when ... != ... is true | -| 111 | i == 0.0+0 when ... != ... is false | -| 122 | b != 0 when b is true | -| 122 | b != 1 when b is false | -| 122 | b == 0 when b is false | -| 122 | b == 1 when b is true | -| 125 | ! ... != 0 when ! ... is true | -| 125 | ! ... != 0 when call to safe is false | -| 125 | ! ... != 1 when ! ... is false | -| 125 | ! ... != 1 when call to safe is true | -| 125 | ! ... == 0 when ! ... is false | -| 125 | ! ... == 0 when call to safe is true | -| 125 | ! ... == 1 when ! ... is true | -| 125 | ! ... == 1 when call to safe is false | -| 125 | call to safe != 0 when ! ... is false | -| 125 | call to safe != 0 when call to safe is true | -| 125 | call to safe != 1 when ! ... is true | -| 125 | call to safe != 1 when call to safe is false | -| 125 | call to safe == 0 when ! ... is true | -| 125 | call to safe == 0 when call to safe is false | -| 125 | call to safe == 1 when ! ... is false | -| 125 | call to safe == 1 when call to safe is true | -| 126 | 1 != 0 when 1 is true | -| 126 | 1 != 0 when ... && ... is true | -| 126 | 1 != 1 when 1 is false | -| 126 | 1 == 0 when 1 is false | -| 126 | 1 == 1 when 1 is true | -| 126 | 1 == 1 when ... && ... is true | -| 126 | call to test3_condition != 0 when ... && ... is true | -| 126 | call to test3_condition != 0 when call to test3_condition is true | -| 126 | call to test3_condition != 1 when call to test3_condition is false | -| 126 | call to test3_condition == 0 when call to test3_condition is false | -| 126 | call to test3_condition == 1 when ... && ... is true | -| 126 | call to test3_condition == 1 when call to test3_condition is true | -| 131 | ... + ... != a+0 when call to __builtin_expect is false | -| 131 | ... + ... == a+0 when call to __builtin_expect is true | -| 131 | a != ... + ...+0 when call to __builtin_expect is false | -| 131 | a != b+42 when call to __builtin_expect is false | -| 131 | a == ... + ...+0 when call to __builtin_expect is true | -| 131 | a == b+42 when call to __builtin_expect is true | -| 131 | b != 0 when b is true | -| 131 | b != 1 when b is false | -| 131 | b != a+-42 when call to __builtin_expect is false | -| 131 | b == 0 when b is false | -| 131 | b == 1 when b is true | -| 131 | b == a+-42 when call to __builtin_expect is true | -| 131 | call to __builtin_expect != 0 when call to __builtin_expect is true | -| 131 | call to __builtin_expect != 1 when call to __builtin_expect is false | -| 131 | call to __builtin_expect == 0 when call to __builtin_expect is false | -| 131 | call to __builtin_expect == 1 when call to __builtin_expect is true | -| 135 | ... + ... != a+0 when call to __builtin_expect is true | -| 135 | ... + ... == a+0 when call to __builtin_expect is false | -| 135 | a != ... + ...+0 when call to __builtin_expect is true | -| 135 | a != b+42 when call to __builtin_expect is true | -| 135 | a == ... + ...+0 when call to __builtin_expect is false | -| 135 | a == b+42 when call to __builtin_expect is false | -| 135 | b != a+-42 when call to __builtin_expect is true | -| 135 | b == a+-42 when call to __builtin_expect is false | -| 135 | call to __builtin_expect != 0 when call to __builtin_expect is true | -| 135 | call to __builtin_expect != 1 when call to __builtin_expect is false | -| 135 | call to __builtin_expect == 0 when call to __builtin_expect is false | -| 135 | call to __builtin_expect == 1 when call to __builtin_expect is true | -| 137 | 0 != 0 when 0 is true | -| 137 | 0 != 1 when 0 is false | -| 137 | 0 == 0 when 0 is false | -| 137 | 0 == 1 when 0 is true | -| 141 | 42 != a+0 when call to __builtin_expect is false | -| 141 | 42 == a+0 when call to __builtin_expect is true | -| 141 | a != 42 when call to __builtin_expect is false | -| 141 | a != 42+0 when call to __builtin_expect is false | -| 141 | a == 42 when call to __builtin_expect is true | -| 141 | a == 42+0 when call to __builtin_expect is true | -| 141 | call to __builtin_expect != 0 when call to __builtin_expect is true | -| 141 | call to __builtin_expect != 1 when call to __builtin_expect is false | -| 141 | call to __builtin_expect == 0 when call to __builtin_expect is false | -| 141 | call to __builtin_expect == 1 when call to __builtin_expect is true | -| 145 | 42 != a+0 when call to __builtin_expect is true | -| 145 | 42 == a+0 when call to __builtin_expect is false | -| 145 | a != 42 when call to __builtin_expect is true | -| 145 | a != 42+0 when call to __builtin_expect is true | -| 145 | a == 42 when call to __builtin_expect is false | -| 145 | a == 42+0 when call to __builtin_expect is false | -| 145 | call to __builtin_expect != 0 when call to __builtin_expect is true | -| 145 | call to __builtin_expect != 1 when call to __builtin_expect is false | -| 145 | call to __builtin_expect == 0 when call to __builtin_expect is false | -| 145 | call to __builtin_expect == 1 when call to __builtin_expect is true | -| 146 | ! ... != 0 when ! ... is true | -| 146 | ! ... != 0 when x is false | -| 146 | ! ... != 1 when ! ... is false | -| 146 | ! ... != 1 when x is true | -| 146 | ! ... == 0 when ! ... is false | -| 146 | ! ... == 0 when x is true | -| 146 | ! ... == 1 when ! ... is true | -| 146 | ! ... == 1 when x is false | -| 146 | x != 0 when ! ... is false | -| 146 | x != 0 when x is true | -| 146 | x == 0 when ! ... is true | -| 146 | x == 0 when x is false | -| 152 | 10 < a+1 when ! ... is true | -| 152 | 10 < a+1 when b is false | -| 152 | 10 >= a+1 when ! ... is false | -| 152 | 10 >= a+1 when b is true | -| 152 | ! ... != 0 when ! ... is true | -| 152 | ! ... != 0 when b is false | -| 152 | ! ... != 1 when ! ... is false | -| 152 | ! ... != 1 when b is true | -| 152 | ! ... == 0 when ! ... is false | -| 152 | ! ... == 0 when b is true | -| 152 | ! ... == 1 when ! ... is true | -| 152 | ! ... == 1 when b is false | -| 152 | ... < ... != 0 when ! ... is false | -| 152 | ... < ... != 0 when b is true | -| 152 | ... < ... != 1 when ! ... is true | -| 152 | ... < ... != 1 when b is false | -| 152 | ... < ... == 0 when ! ... is true | -| 152 | ... < ... == 0 when b is false | -| 152 | ... < ... == 1 when ! ... is false | -| 152 | ... < ... == 1 when b is true | -| 152 | a < 10 when ! ... is false | -| 152 | a < 10 when b is true | -| 152 | a < 10+0 when ! ... is false | -| 152 | a < 10+0 when b is true | -| 152 | a >= 10 when ! ... is true | -| 152 | a >= 10 when b is false | -| 152 | a >= 10+0 when ! ... is true | -| 152 | a >= 10+0 when b is false | -| 152 | b != 0 when ! ... is false | -| 152 | b != 0 when b is true | -| 152 | b != 1 when ! ... is true | -| 152 | b != 1 when b is false | -| 152 | b == 0 when ! ... is true | -| 152 | b == 0 when b is false | -| 152 | b == 1 when ! ... is false | -| 152 | b == 1 when b is true | -| 152 | p != 0 when p is true | -| 152 | p != 1 when p is false | -| 152 | p == 0 when p is false | -| 152 | p == 1 when p is true | -| 158 | ! ... != 0 when ! ... is true | -| 158 | ! ... != 0 when p is false | -| 158 | ! ... != 1 when ! ... is false | -| 158 | ! ... != 1 when p is true | -| 158 | ! ... == 0 when ! ... is false | -| 158 | ! ... == 0 when p is true | -| 158 | ! ... == 1 when ! ... is true | -| 158 | ! ... == 1 when p is false | -| 158 | p != 0 when ! ... is false | -| 158 | p != 0 when p is true | -| 158 | p == 0 when ! ... is true | -| 158 | p == 0 when p is false | -| 160 | ! ... != 0 when ! ... is true | -| 160 | ! ... != 0 when c is false | -| 160 | ! ... != 1 when ! ... is false | -| 160 | ! ... != 1 when c is true | -| 160 | ! ... == 0 when ! ... is false | -| 160 | ! ... == 0 when c is true | -| 160 | ! ... == 1 when ! ... is true | -| 160 | ! ... == 1 when c is false | -| 160 | ... != ... != 0 when ! ... is false | -| 160 | ... != ... != 0 when c is true | -| 160 | ... != ... != 1 when ! ... is true | -| 160 | ... != ... != 1 when c is false | -| 160 | ... != ... == 0 when ! ... is true | -| 160 | ... != ... == 0 when c is false | -| 160 | ... != ... == 1 when ! ... is false | -| 160 | ... != ... == 1 when c is true | -| 160 | a != b+0 when ! ... is false | -| 160 | a != b+0 when c is true | -| 160 | a == b+0 when ! ... is true | -| 160 | a == b+0 when c is false | -| 160 | b != a+0 when ! ... is false | -| 160 | b != a+0 when c is true | -| 160 | b == a+0 when ! ... is true | -| 160 | b == a+0 when c is false | -| 160 | c != 0 when ! ... is false | -| 160 | c != 0 when c is true | -| 160 | c != 1 when ! ... is true | -| 160 | c != 1 when c is false | -| 160 | c == 0 when ! ... is true | -| 160 | c == 0 when c is false | -| 160 | c == 1 when ! ... is false | -| 160 | c == 1 when c is true | -| 164 | s != 0 when s is true | -| 164 | s != 1 when s is false | -| 164 | s == 0 when s is false | -| 164 | s == 1 when s is true | -| 168 | 10 < a+0 when ! ... is false | -| 168 | 10 < a+0 when b is true | -| 168 | 10 >= a+0 when ! ... is true | -| 168 | 10 >= a+0 when b is false | -| 168 | ! ... != 0 when ! ... is true | -| 168 | ! ... != 0 when b is false | -| 168 | ! ... != 1 when ! ... is false | -| 168 | ! ... != 1 when b is true | -| 168 | ! ... == 0 when ! ... is false | -| 168 | ! ... == 0 when b is true | -| 168 | ! ... == 1 when ! ... is true | -| 168 | ! ... == 1 when b is false | -| 168 | ... > ... != 0 when ! ... is false | -| 168 | ... > ... != 0 when b is true | -| 168 | ... > ... != 1 when ! ... is true | -| 168 | ... > ... != 1 when b is false | -| 168 | ... > ... == 0 when ! ... is true | -| 168 | ... > ... == 0 when b is false | -| 168 | ... > ... == 1 when ! ... is false | -| 168 | ... > ... == 1 when b is true | -| 168 | a < 10+1 when ! ... is true | -| 168 | a < 10+1 when b is false | -| 168 | a < 11 when ! ... is true | -| 168 | a < 11 when b is false | -| 168 | a >= 10+1 when ! ... is false | -| 168 | a >= 10+1 when b is true | -| 168 | a >= 11 when ! ... is false | -| 168 | a >= 11 when b is true | -| 168 | b != 0 when ! ... is false | -| 168 | b != 0 when b is true | -| 168 | b != 1 when ! ... is true | -| 168 | b != 1 when b is false | -| 168 | b == 0 when ! ... is true | -| 168 | b == 0 when b is false | -| 168 | b == 1 when ! ... is false | -| 168 | b == 1 when b is true | -| 170 | ! ... != 0 when ! ... is true | -| 170 | ! ... != 0 when s is false | -| 170 | ! ... != 1 when ! ... is false | -| 170 | ! ... != 1 when s is true | -| 170 | ! ... == 0 when ! ... is false | -| 170 | ! ... == 0 when s is true | -| 170 | ! ... == 1 when ! ... is true | -| 170 | ! ... == 1 when s is false | -| 170 | s != 0 when ! ... is false | -| 170 | s != 0 when s is true | -| 170 | s == 0 when ! ... is true | -| 170 | s == 0 when s is false | -| 176 | ! ... != 0 when ! ... is true | -| 176 | ! ... != 0 when ... < ... is false | -| 176 | ! ... != 0 when c is false | -| 176 | ! ... != 1 when ! ... is false | -| 176 | ! ... != 1 when ... < ... is true | -| 176 | ! ... != 1 when c is true | -| 176 | ! ... == 0 when ! ... is false | -| 176 | ! ... == 0 when ... < ... is true | -| 176 | ! ... == 0 when c is true | -| 176 | ! ... == 1 when ! ... is true | -| 176 | ! ... == 1 when ... < ... is false | -| 176 | ! ... == 1 when c is false | -| 176 | ... < ... != 0 when ! ... is false | -| 176 | ... < ... != 0 when ... < ... is true | -| 176 | ... < ... == 0 when ! ... is true | -| 176 | ... < ... == 0 when ... < ... is false | -| 176 | ... > ... != 0 when ! ... is false | -| 176 | ... > ... != 0 when c is true | -| 176 | ... > ... != 1 when ! ... is true | -| 176 | ... > ... != 1 when c is false | -| 176 | ... > ... == 0 when ! ... is true | -| 176 | ... > ... == 0 when c is false | -| 176 | ... > ... == 1 when ! ... is false | -| 176 | ... > ... == 1 when c is true | -| 176 | a < b+1 when ! ... is true | -| 176 | a < b+1 when c is false | -| 176 | a >= b+1 when ! ... is false | -| 176 | a >= b+1 when c is true | -| 176 | b < a+0 when ! ... is false | -| 176 | b < a+0 when c is true | -| 176 | b >= a+0 when ! ... is true | -| 176 | b >= a+0 when c is false | -| 176 | c != 0 when ! ... is false | -| 176 | c != 0 when c is true | -| 176 | c != 1 when ! ... is true | -| 176 | c != 1 when c is false | -| 176 | c == 0 when ! ... is true | -| 176 | c == 0 when c is false | -| 176 | c == 1 when ! ... is false | -| 176 | c == 1 when c is true | -| 182 | 1.0 < foo+1 when ... < ... is false | -| 182 | 1.0 >= foo+1 when ... && ... is true | -| 182 | 1.0 >= foo+1 when ... < ... is true | -| 182 | 9.999999999999999547e-07 < foo+1 when ... && ... is true | -| 182 | 9.999999999999999547e-07 < foo+1 when ... >= ... is true | -| 182 | 9.999999999999999547e-07 >= foo+1 when ... >= ... is false | -| 182 | ! ... != 0 when ! ... is true | -| 182 | ! ... != 0 when ... && ... is false | -| 182 | ! ... != 1 when ! ... is false | -| 182 | ! ... != 1 when ... && ... is true | -| 182 | ! ... == 0 when ! ... is false | -| 182 | ! ... == 0 when ... && ... is true | -| 182 | ! ... == 1 when ! ... is true | -| 182 | ! ... == 1 when ... && ... is false | -| 182 | ... && ... != 0 when ! ... is false | -| 182 | ... && ... != 0 when ... && ... is true | -| 182 | ... && ... != 1 when ! ... is true | -| 182 | ... && ... != 1 when ... && ... is false | -| 182 | ... && ... == 0 when ! ... is true | -| 182 | ... && ... == 0 when ... && ... is false | -| 182 | ... && ... == 1 when ! ... is false | -| 182 | ... && ... == 1 when ... && ... is true | -| 182 | ... < ... != 0 when ... && ... is true | -| 182 | ... < ... != 0 when ... < ... is true | -| 182 | ... < ... != 1 when ... < ... is false | -| 182 | ... < ... == 0 when ... < ... is false | -| 182 | ... < ... == 1 when ... && ... is true | -| 182 | ... < ... == 1 when ... < ... is true | -| 182 | ... >= ... != 0 when ... && ... is true | -| 182 | ... >= ... != 0 when ... >= ... is true | -| 182 | ... >= ... != 1 when ... >= ... is false | -| 182 | ... >= ... == 0 when ... >= ... is false | -| 182 | ... >= ... == 1 when ... && ... is true | -| 182 | ... >= ... == 1 when ... >= ... is true | -| 182 | b1 != 0 when ! ... is false | -| 182 | b1 != 0 when ... && ... is true | -| 182 | b1 != 0 when b1 is true | -| 182 | b1 != 1 when b1 is false | -| 182 | b1 == 0 when b1 is false | -| 182 | b1 == 1 when ! ... is false | -| 182 | b1 == 1 when ... && ... is true | -| 182 | b1 == 1 when b1 is true | -| 182 | b2 != 0 when ! ... is false | -| 182 | b2 != 0 when ... && ... is true | -| 182 | b2 != 0 when b2 is true | -| 182 | b2 != 1 when b2 is false | -| 182 | b2 == 0 when b2 is false | -| 182 | b2 == 1 when ! ... is false | -| 182 | b2 == 1 when ... && ... is true | -| 182 | b2 == 1 when b2 is true | -| 182 | foo < 1.0+0 when ... && ... is true | -| 182 | foo < 1.0+0 when ... < ... is true | -| 182 | foo < 9.999999999999999547e-07+0 when ... >= ... is false | -| 182 | foo >= 1.0+0 when ... < ... is false | -| 182 | foo >= 9.999999999999999547e-07+0 when ... && ... is true | -| 182 | foo >= 9.999999999999999547e-07+0 when ... >= ... is true | -| 190 | ! ... != 0 when ! ... is true | -| 190 | ! ... != 0 when c is false | -| 190 | ! ... != 1 when ! ... is false | -| 190 | ! ... != 1 when c is true | -| 190 | ! ... == 0 when ! ... is false | -| 190 | ! ... == 0 when c is true | -| 190 | ! ... == 1 when ! ... is true | -| 190 | ! ... == 1 when c is false | -| 190 | c != 0 when ! ... is false | -| 190 | c != 0 when c is true | -| 190 | c == 0 when ! ... is true | -| 190 | c == 0 when c is false | -| 193 | ! ... != 0 when ! ... is true | -| 193 | ! ... != 0 when ... \|\| ... is false | -| 193 | ! ... != 1 when ! ... is false | -| 193 | ! ... != 1 when ... \|\| ... is true | -| 193 | ! ... == 0 when ! ... is false | -| 193 | ! ... == 0 when ... \|\| ... is true | -| 193 | ! ... == 1 when ! ... is true | -| 193 | ! ... == 1 when ... \|\| ... is false | -| 193 | ... \|\| ... != 0 when ! ... is false | -| 193 | ... \|\| ... != 0 when ... \|\| ... is true | -| 193 | ... \|\| ... != 1 when ! ... is true | -| 193 | ... \|\| ... != 1 when ... \|\| ... is false | -| 193 | ... \|\| ... == 0 when ! ... is true | -| 193 | ... \|\| ... == 0 when ... \|\| ... is false | -| 193 | ... \|\| ... == 1 when ! ... is false | -| 193 | ... \|\| ... == 1 when ... \|\| ... is true | -| 193 | b1 != 0 when b1 is true | -| 193 | b1 != 1 when ! ... is true | -| 193 | b1 != 1 when ... \|\| ... is false | -| 193 | b1 != 1 when b1 is false | -| 193 | b1 == 0 when ! ... is true | -| 193 | b1 == 0 when ... \|\| ... is false | -| 193 | b1 == 0 when b1 is false | -| 193 | b1 == 1 when b1 is true | -| 193 | b2 != 0 when b2 is true | -| 193 | b2 != 1 when ! ... is true | -| 193 | b2 != 1 when ... \|\| ... is false | -| 193 | b2 != 1 when b2 is false | -| 193 | b2 == 0 when ! ... is true | -| 193 | b2 == 0 when ... \|\| ... is false | -| 193 | b2 == 0 when b2 is false | -| 193 | b2 == 1 when b2 is true | -| 198 | ! ... != 0 when ! ... is true | -| 198 | ! ... != 0 when b is false | -| 198 | ! ... != 1 when ! ... is false | -| 198 | ! ... != 1 when b is true | -| 198 | ! ... == 0 when ! ... is false | -| 198 | ! ... == 0 when b is true | -| 198 | ! ... == 1 when ! ... is true | -| 198 | ! ... == 1 when b is false | -| 198 | b != 0 when ! ... is false | -| 198 | b != 0 when b is true | -| 198 | b == 0 when ! ... is true | -| 198 | b == 0 when b is false | -| 206 | ! ... != 0 when ! ... is true | -| 206 | ! ... != 0 when c is false | -| 206 | ! ... != 1 when ! ... is false | -| 206 | ! ... != 1 when c is true | -| 206 | ! ... == 0 when ! ... is false | -| 206 | ! ... == 0 when c is true | -| 206 | ! ... == 1 when ! ... is true | -| 206 | ! ... == 1 when c is false | -| 206 | c != 0 when ! ... is false | -| 206 | c != 0 when c is true | -| 206 | c == 0 when ! ... is true | -| 206 | c == 0 when c is false | -| 211 | 0 != sc+0 when ... == ... is false | -| 211 | 0 == sc+0 when ... == ... is true | -| 211 | ... == ... != 0 when ... == ... is true | -| 211 | ... == ... != 1 when ... == ... is false | -| 211 | ... == ... == 0 when ... == ... is false | -| 211 | ... == ... == 1 when ... == ... is true | -| 211 | sc != 0 when ... == ... is false | -| 211 | sc != 0+0 when ... == ... is false | -| 211 | sc == 0 when ... == ... is true | -| 211 | sc == 0+0 when ... == ... is true | -| 214 | 0 != sc+0 when ... == ... is false | -| 214 | 0 == sc+0 when ... == ... is true | -| 214 | ... == ... != 0 when ... == ... is true | -| 214 | ... == ... != 1 when ... == ... is false | -| 214 | ... == ... == 0 when ... == ... is false | -| 214 | ... == ... == 1 when ... == ... is true | -| 214 | sc != 0 when ... == ... is false | -| 214 | sc != 0+0 when ... == ... is false | -| 214 | sc == 0 when ... == ... is true | -| 214 | sc == 0+0 when ... == ... is true | -| 217 | 0 != ul+0 when ... == ... is false | -| 217 | 0 == ul+0 when ... == ... is true | -| 217 | ... == ... != 0 when ... == ... is true | -| 217 | ... == ... != 1 when ... == ... is false | -| 217 | ... == ... == 0 when ... == ... is false | -| 217 | ... == ... == 1 when ... == ... is true | -| 217 | ul != 0 when ... == ... is false | -| 217 | ul != 0+0 when ... == ... is false | -| 217 | ul == 0 when ... == ... is true | -| 217 | ul == 0+0 when ... == ... is true | -| 220 | 0 != f+0 when ... == ... is false | -| 220 | 0 == f+0 when ... == ... is true | -| 220 | ... == ... != 0 when ... == ... is true | -| 220 | ... == ... != 1 when ... == ... is false | -| 220 | ... == ... == 0 when ... == ... is false | -| 220 | ... == ... == 1 when ... == ... is true | -| 220 | f != 0+0 when ... == ... is false | -| 220 | f == 0+0 when ... == ... is true | -| 223 | 0.0 != f+0 when ... == ... is false | -| 223 | 0.0 == f+0 when ... == ... is true | -| 223 | ... == ... != 0 when ... == ... is true | -| 223 | ... == ... != 1 when ... == ... is false | -| 223 | ... == ... == 0 when ... == ... is false | -| 223 | ... == ... == 1 when ... == ... is true | -| 223 | f != 0.0+0 when ... == ... is false | -| 223 | f == 0.0+0 when ... == ... is true | -| 226 | 0 != d+0 when ... == ... is false | -| 226 | 0 == d+0 when ... == ... is true | -| 226 | ... == ... != 0 when ... == ... is true | -| 226 | ... == ... != 1 when ... == ... is false | -| 226 | ... == ... == 0 when ... == ... is false | -| 226 | ... == ... == 1 when ... == ... is true | -| 226 | d != 0+0 when ... == ... is false | -| 226 | d == 0+0 when ... == ... is true | -| 229 | 0 != b+0 when ... == ... is false | -| 229 | 0 == b+0 when ... == ... is true | -| 229 | ... == ... != 0 when ... == ... is true | -| 229 | ... == ... != 1 when ... == ... is false | -| 229 | ... == ... == 0 when ... == ... is false | -| 229 | ... == ... == 1 when ... == ... is true | -| 229 | b != 0 when ... == ... is false | -| 229 | b != 0+0 when ... == ... is false | -| 229 | b == 0 when ... == ... is true | -| 229 | b == 0+0 when ... == ... is true | -| 232 | 0 != b+0 when ... == ... is false | -| 232 | 0 == b+0 when ... == ... is true | -| 232 | ... == ... != 0 when ... == ... is true | -| 232 | ... == ... != 1 when ... == ... is false | -| 232 | ... == ... == 0 when ... == ... is false | -| 232 | ... == ... == 1 when ... == ... is true | -| 232 | b != 0 when ... == ... is false | -| 232 | b != 0+0 when ... == ... is false | -| 232 | b == 0 when ... == ... is true | -| 232 | b == 0+0 when ... == ... is true | -| 235 | 0 != i+0 when ... == ... is false | -| 235 | 0 == i+0 when ... == ... is true | -| 235 | ... == ... != 0 when ... == ... is true | -| 235 | ... == ... != 1 when ... == ... is false | -| 235 | ... == ... == 0 when ... == ... is false | -| 235 | ... == ... == 1 when ... == ... is true | -| 235 | i != 0 when ... == ... is false | -| 235 | i != 0+0 when ... == ... is false | -| 235 | i == 0 when ... == ... is true | -| 235 | i == 0+0 when ... == ... is true | -| 238 | 0 != f+0 when ... == ... is false | -| 238 | 0 == f+0 when ... == ... is true | -| 238 | ... == ... != 0 when ... == ... is true | -| 238 | ... == ... != 1 when ... == ... is false | -| 238 | ... == ... == 0 when ... == ... is false | -| 238 | ... == ... == 1 when ... == ... is true | -| 238 | f != 0+0 when ... == ... is false | -| 238 | f == 0+0 when ... == ... is true | -| 241 | 0 != f+0 when ... == ... is false | -| 241 | 0 != i+0 when ... == ... is false | -| 241 | 0 == f+0 when ... && ... is true | -| 241 | 0 == f+0 when ... == ... is true | -| 241 | 0 == i+0 when ... && ... is true | -| 241 | 0 == i+0 when ... == ... is true | -| 241 | ... == ... != 0 when ... && ... is true | -| 241 | ... == ... != 0 when ... == ... is true | -| 241 | ... == ... != 1 when ... == ... is false | -| 241 | ... == ... == 0 when ... == ... is false | -| 241 | ... == ... == 1 when ... && ... is true | -| 241 | ... == ... == 1 when ... == ... is true | -| 241 | f != 0+0 when ... == ... is false | -| 241 | f == 0+0 when ... && ... is true | -| 241 | f == 0+0 when ... == ... is true | -| 241 | i != 0 when ... == ... is false | -| 241 | i != 0+0 when ... == ... is false | -| 241 | i == 0 when ... && ... is true | -| 241 | i == 0 when ... == ... is true | -| 241 | i == 0+0 when ... && ... is true | -| 241 | i == 0+0 when ... == ... is true | +| test.c:7:9:7:13 | ... > ... | 0 < x+0 when ... > ... is true | +| test.c:7:9:7:13 | ... > ... | 0 >= x+0 when ... > ... is false | +| test.c:7:9:7:13 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.c:7:9:7:13 | ... > ... | ... > ... != 1 when ... > ... is false | +| test.c:7:9:7:13 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.c:7:9:7:13 | ... > ... | ... > ... == 1 when ... > ... is true | +| test.c:7:9:7:13 | ... > ... | x < 0+1 when ... > ... is false | +| test.c:7:9:7:13 | ... > ... | x < 1 when ... > ... is false | +| test.c:7:9:7:13 | ... > ... | x >= 0+1 when ... > ... is true | +| test.c:7:9:7:13 | ... > ... | x >= 1 when ... > ... is true | +| test.c:17:8:17:12 | ... < ... | 0 < x+1 when ... < ... is false | +| test.c:17:8:17:12 | ... < ... | 0 >= x+1 when ... < ... is true | +| test.c:17:8:17:12 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.c:17:8:17:12 | ... < ... | ... < ... != 1 when ... < ... is false | +| test.c:17:8:17:12 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.c:17:8:17:12 | ... < ... | ... < ... == 1 when ... < ... is true | +| test.c:17:8:17:12 | ... < ... | x < 0 when ... < ... is true | +| test.c:17:8:17:12 | ... < ... | x < 0+0 when ... < ... is true | +| test.c:17:8:17:12 | ... < ... | x >= 0 when ... < ... is false | +| test.c:17:8:17:12 | ... < ... | x >= 0+0 when ... < ... is false | +| test.c:17:8:17:21 | ... && ... | 0 >= x+1 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | 1 < y+0 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | ... < ... != 0 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | ... < ... == 1 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | ... > ... != 0 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | ... > ... == 1 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | x < 0 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | x < 0+0 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | y >= 1+1 when ... && ... is true | +| test.c:17:8:17:21 | ... && ... | y >= 2 when ... && ... is true | +| test.c:17:17:17:21 | ... > ... | 1 < y+0 when ... > ... is true | +| test.c:17:17:17:21 | ... > ... | 1 >= y+0 when ... > ... is false | +| test.c:17:17:17:21 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.c:17:17:17:21 | ... > ... | ... > ... != 1 when ... > ... is false | +| test.c:17:17:17:21 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.c:17:17:17:21 | ... > ... | ... > ... == 1 when ... > ... is true | +| test.c:17:17:17:21 | ... > ... | y < 1+1 when ... > ... is false | +| test.c:17:17:17:21 | ... > ... | y < 2 when ... > ... is false | +| test.c:17:17:17:21 | ... > ... | y >= 1+1 when ... > ... is true | +| test.c:17:17:17:21 | ... > ... | y >= 2 when ... > ... is true | +| test.c:26:11:26:15 | ... > ... | 0 < x+0 when ... > ... is true | +| test.c:26:11:26:15 | ... > ... | 0 >= x+0 when ... > ... is false | +| test.c:26:11:26:15 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.c:26:11:26:15 | ... > ... | ... > ... != 1 when ... > ... is false | +| test.c:26:11:26:15 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.c:26:11:26:15 | ... > ... | ... > ... == 1 when ... > ... is true | +| test.c:26:11:26:15 | ... > ... | x < 0+1 when ... > ... is false | +| test.c:26:11:26:15 | ... > ... | x < 1 when ... > ... is false | +| test.c:26:11:26:15 | ... > ... | x >= 0+1 when ... > ... is true | +| test.c:26:11:26:15 | ... > ... | x >= 1 when ... > ... is true | +| test.c:34:16:34:21 | ... < ... | 10 < j+1 when ... < ... is false | +| test.c:34:16:34:21 | ... < ... | 10 >= j+1 when ... < ... is true | +| test.c:34:16:34:21 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.c:34:16:34:21 | ... < ... | ... < ... != 1 when ... < ... is false | +| test.c:34:16:34:21 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.c:34:16:34:21 | ... < ... | ... < ... == 1 when ... < ... is true | +| test.c:34:16:34:21 | ... < ... | j < 10 when ... < ... is true | +| test.c:34:16:34:21 | ... < ... | j < 10+0 when ... < ... is true | +| test.c:34:16:34:21 | ... < ... | j >= 10 when ... < ... is false | +| test.c:34:16:34:21 | ... < ... | j >= 10+0 when ... < ... is false | +| test.c:42:16:42:21 | ... < ... | 10 < j+1 when ... < ... is false | +| test.c:42:16:42:21 | ... < ... | 10 >= j+1 when ... < ... is true | +| test.c:42:16:42:21 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.c:42:16:42:21 | ... < ... | ... < ... != 1 when ... < ... is false | +| test.c:42:16:42:21 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.c:42:16:42:21 | ... < ... | ... < ... == 1 when ... < ... is true | +| test.c:42:16:42:21 | ... < ... | j < 10 when ... < ... is true | +| test.c:42:16:42:21 | ... < ... | j < 10+0 when ... < ... is true | +| test.c:42:16:42:21 | ... < ... | j >= 10 when ... < ... is false | +| test.c:42:16:42:21 | ... < ... | j >= 10+0 when ... < ... is false | +| test.c:44:12:44:16 | ... > ... | 0 < z+0 when ... > ... is true | +| test.c:44:12:44:16 | ... > ... | 0 >= z+0 when ... > ... is false | +| test.c:44:12:44:16 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.c:44:12:44:16 | ... > ... | ... > ... != 1 when ... > ... is false | +| test.c:44:12:44:16 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.c:44:12:44:16 | ... > ... | ... > ... == 1 when ... > ... is true | +| test.c:44:12:44:16 | ... > ... | z < 0+1 when ... > ... is false | +| test.c:44:12:44:16 | ... > ... | z < 1 when ... > ... is false | +| test.c:44:12:44:16 | ... > ... | z >= 0+1 when ... > ... is true | +| test.c:44:12:44:16 | ... > ... | z >= 1 when ... > ... is true | +| test.c:45:16:45:20 | ... > ... | 0 < y+0 when ... > ... is true | +| test.c:45:16:45:20 | ... > ... | 0 >= y+0 when ... > ... is false | +| test.c:45:16:45:20 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.c:45:16:45:20 | ... > ... | ... > ... != 1 when ... > ... is false | +| test.c:45:16:45:20 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.c:45:16:45:20 | ... > ... | ... > ... == 1 when ... > ... is true | +| test.c:45:16:45:20 | ... > ... | y < 0+1 when ... > ... is false | +| test.c:45:16:45:20 | ... > ... | y < 1 when ... > ... is false | +| test.c:45:16:45:20 | ... > ... | y >= 0+1 when ... > ... is true | +| test.c:45:16:45:20 | ... > ... | y >= 1 when ... > ... is true | +| test.c:58:9:58:14 | ... == ... | 0 != x+0 when ... == ... is false | +| test.c:58:9:58:14 | ... == ... | 0 == x+0 when ... == ... is true | +| test.c:58:9:58:14 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.c:58:9:58:14 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.c:58:9:58:14 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.c:58:9:58:14 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.c:58:9:58:14 | ... == ... | x != 0 when ... == ... is false | +| test.c:58:9:58:14 | ... == ... | x != 0+0 when ... == ... is false | +| test.c:58:9:58:14 | ... == ... | x == 0 when ... == ... is true | +| test.c:58:9:58:14 | ... == ... | x == 0+0 when ... == ... is true | +| test.c:58:9:58:23 | ... \|\| ... | 0 != x+0 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | 0 < y+1 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | ... < ... != 1 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | ... < ... == 0 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | ... == ... != 1 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | ... == ... == 0 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | x != 0 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | x != 0+0 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | y >= 0 when ... \|\| ... is false | +| test.c:58:9:58:23 | ... \|\| ... | y >= 0+0 when ... \|\| ... is false | +| test.c:58:19:58:23 | ... < ... | 0 < y+1 when ... < ... is false | +| test.c:58:19:58:23 | ... < ... | 0 >= y+1 when ... < ... is true | +| test.c:58:19:58:23 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.c:58:19:58:23 | ... < ... | ... < ... != 1 when ... < ... is false | +| test.c:58:19:58:23 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.c:58:19:58:23 | ... < ... | ... < ... == 1 when ... < ... is true | +| test.c:58:19:58:23 | ... < ... | y < 0 when ... < ... is true | +| test.c:58:19:58:23 | ... < ... | y < 0+0 when ... < ... is true | +| test.c:58:19:58:23 | ... < ... | y >= 0 when ... < ... is false | +| test.c:58:19:58:23 | ... < ... | y >= 0+0 when ... < ... is false | +| test.c:75:9:75:14 | ... == ... | 0 != x+0 when ... == ... is false | +| test.c:75:9:75:14 | ... == ... | 0 == x+0 when ... == ... is true | +| test.c:75:9:75:14 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.c:75:9:75:14 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.c:75:9:75:14 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.c:75:9:75:14 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.c:75:9:75:14 | ... == ... | x != 0 when ... == ... is false | +| test.c:75:9:75:14 | ... == ... | x != 0+0 when ... == ... is false | +| test.c:75:9:75:14 | ... == ... | x == 0 when ... == ... is true | +| test.c:75:9:75:14 | ... == ... | x == 0+0 when ... == ... is true | +| test.c:85:8:85:13 | ... == ... | 0 != x+0 when ... == ... is false | +| test.c:85:8:85:13 | ... == ... | 0 == x+0 when ... == ... is true | +| test.c:85:8:85:13 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.c:85:8:85:13 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.c:85:8:85:13 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.c:85:8:85:13 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.c:85:8:85:13 | ... == ... | x != 0 when ... == ... is false | +| test.c:85:8:85:13 | ... == ... | x != 0+0 when ... == ... is false | +| test.c:85:8:85:13 | ... == ... | x == 0 when ... == ... is true | +| test.c:85:8:85:13 | ... == ... | x == 0+0 when ... == ... is true | +| test.c:85:8:85:23 | ... && ... | 0 != y+0 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | 0 == x+0 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | ... != ... != 0 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | ... != ... == 1 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | ... == ... != 0 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | ... == ... == 1 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | x == 0 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | x == 0+0 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | y != 0 when ... && ... is true | +| test.c:85:8:85:23 | ... && ... | y != 0+0 when ... && ... is true | +| test.c:85:18:85:23 | ... != ... | 0 != y+0 when ... != ... is true | +| test.c:85:18:85:23 | ... != ... | 0 == y+0 when ... != ... is false | +| test.c:85:18:85:23 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.c:85:18:85:23 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.c:85:18:85:23 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.c:85:18:85:23 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.c:85:18:85:23 | ... != ... | y != 0 when ... != ... is true | +| test.c:85:18:85:23 | ... != ... | y != 0+0 when ... != ... is true | +| test.c:85:18:85:23 | ... != ... | y == 0 when ... != ... is false | +| test.c:85:18:85:23 | ... != ... | y == 0+0 when ... != ... is false | +| test.c:94:11:94:16 | ... != ... | 0 != x+0 when ... != ... is true | +| test.c:94:11:94:16 | ... != ... | 0 == x+0 when ... != ... is false | +| test.c:94:11:94:16 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.c:94:11:94:16 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.c:94:11:94:16 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.c:94:11:94:16 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.c:94:11:94:16 | ... != ... | x != 0 when ... != ... is true | +| test.c:94:11:94:16 | ... != ... | x != 0+0 when ... != ... is true | +| test.c:94:11:94:16 | ... != ... | x == 0 when ... != ... is false | +| test.c:94:11:94:16 | ... != ... | x == 0+0 when ... != ... is false | +| test.c:102:16:102:21 | ... < ... | 10 < j+1 when ... < ... is false | +| test.c:102:16:102:21 | ... < ... | 10 >= j+1 when ... < ... is true | +| test.c:102:16:102:21 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.c:102:16:102:21 | ... < ... | ... < ... != 1 when ... < ... is false | +| test.c:102:16:102:21 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.c:102:16:102:21 | ... < ... | ... < ... == 1 when ... < ... is true | +| test.c:102:16:102:21 | ... < ... | j < 10 when ... < ... is true | +| test.c:102:16:102:21 | ... < ... | j < 10+0 when ... < ... is true | +| test.c:102:16:102:21 | ... < ... | j >= 10 when ... < ... is false | +| test.c:102:16:102:21 | ... < ... | j >= 10+0 when ... < ... is false | +| test.c:109:9:109:14 | ... == ... | 0 != x+0 when ... == ... is false | +| test.c:109:9:109:14 | ... == ... | 0 == x+0 when ... == ... is true | +| test.c:109:9:109:14 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.c:109:9:109:14 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.c:109:9:109:14 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.c:109:9:109:14 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.c:109:9:109:14 | ... == ... | x != 0 when ... == ... is false | +| test.c:109:9:109:14 | ... == ... | x != 0+0 when ... == ... is false | +| test.c:109:9:109:14 | ... == ... | x == 0 when ... == ... is true | +| test.c:109:9:109:14 | ... == ... | x == 0+0 when ... == ... is true | +| test.c:109:9:109:23 | ... \|\| ... | 0 != x+0 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | 0 < y+1 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | ... < ... != 1 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | ... < ... == 0 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | ... == ... != 1 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | ... == ... == 0 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | x != 0 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | x != 0+0 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | y >= 0 when ... \|\| ... is false | +| test.c:109:9:109:23 | ... \|\| ... | y >= 0+0 when ... \|\| ... is false | +| test.c:109:19:109:23 | ... < ... | 0 < y+1 when ... < ... is false | +| test.c:109:19:109:23 | ... < ... | 0 >= y+1 when ... < ... is true | +| test.c:109:19:109:23 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.c:109:19:109:23 | ... < ... | ... < ... != 1 when ... < ... is false | +| test.c:109:19:109:23 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.c:109:19:109:23 | ... < ... | ... < ... == 1 when ... < ... is true | +| test.c:109:19:109:23 | ... < ... | y < 0 when ... < ... is true | +| test.c:109:19:109:23 | ... < ... | y < 0+0 when ... < ... is true | +| test.c:109:19:109:23 | ... < ... | y >= 0 when ... < ... is false | +| test.c:109:19:109:23 | ... < ... | y >= 0+0 when ... < ... is false | +| test.c:126:7:126:7 | 1 | 1 != 0 when 1 is true | +| test.c:126:7:126:7 | 1 | 1 != 1 when 1 is false | +| test.c:126:7:126:7 | 1 | 1 == 0 when 1 is false | +| test.c:126:7:126:7 | 1 | 1 == 1 when 1 is true | +| test.c:126:7:126:28 | ... && ... | 1 != 0 when ... && ... is true | +| test.c:126:7:126:28 | ... && ... | 1 == 1 when ... && ... is true | +| test.c:126:7:126:28 | ... && ... | call to test3_condition != 0 when ... && ... is true | +| test.c:126:7:126:28 | ... && ... | call to test3_condition == 1 when ... && ... is true | +| test.c:126:12:126:26 | call to test3_condition | call to test3_condition != 0 when call to test3_condition is true | +| test.c:126:12:126:26 | call to test3_condition | call to test3_condition != 1 when call to test3_condition is false | +| test.c:126:12:126:26 | call to test3_condition | call to test3_condition == 0 when call to test3_condition is false | +| test.c:126:12:126:26 | call to test3_condition | call to test3_condition == 1 when call to test3_condition is true | +| test.c:131:7:131:7 | b | b != 0 when b is true | +| test.c:131:7:131:7 | b | b != 1 when b is false | +| test.c:131:7:131:7 | b | b == 0 when b is false | +| test.c:131:7:131:7 | b | b == 1 when b is true | +| test.c:137:7:137:7 | 0 | 0 != 0 when 0 is true | +| test.c:137:7:137:7 | 0 | 0 != 1 when 0 is false | +| test.c:137:7:137:7 | 0 | 0 == 0 when 0 is false | +| test.c:137:7:137:7 | 0 | 0 == 1 when 0 is true | +| test.c:146:7:146:8 | ! ... | ! ... != 0 when ! ... is true | +| test.c:146:7:146:8 | ! ... | ! ... != 1 when ! ... is false | +| test.c:146:7:146:8 | ! ... | ! ... == 0 when ! ... is false | +| test.c:146:7:146:8 | ! ... | ! ... == 1 when ! ... is true | +| test.c:146:7:146:8 | ! ... | x != 0 when ! ... is false | +| test.c:146:7:146:8 | ! ... | x == 0 when ! ... is true | +| test.c:146:8:146:8 | x | ! ... != 0 when x is false | +| test.c:146:8:146:8 | x | ! ... != 1 when x is true | +| test.c:146:8:146:8 | x | ! ... == 0 when x is true | +| test.c:146:8:146:8 | x | ! ... == 1 when x is false | +| test.c:146:8:146:8 | x | x != 0 when x is true | +| test.c:146:8:146:8 | x | x == 0 when x is false | +| test.c:152:8:152:8 | p | p != 0 when p is true | +| test.c:152:8:152:8 | p | p != 1 when p is false | +| test.c:152:8:152:8 | p | p == 0 when p is false | +| test.c:152:8:152:8 | p | p == 1 when p is true | +| test.c:158:8:158:9 | ! ... | ! ... != 0 when ! ... is true | +| test.c:158:8:158:9 | ! ... | ! ... != 1 when ! ... is false | +| test.c:158:8:158:9 | ! ... | ! ... == 0 when ! ... is false | +| test.c:158:8:158:9 | ! ... | ! ... == 1 when ! ... is true | +| test.c:158:8:158:9 | ! ... | p != 0 when ! ... is false | +| test.c:158:8:158:9 | ! ... | p == 0 when ! ... is true | +| test.c:158:9:158:9 | p | ! ... != 0 when p is false | +| test.c:158:9:158:9 | p | ! ... != 1 when p is true | +| test.c:158:9:158:9 | p | ! ... == 0 when p is true | +| test.c:158:9:158:9 | p | ! ... == 1 when p is false | +| test.c:158:9:158:9 | p | p != 0 when p is true | +| test.c:158:9:158:9 | p | p == 0 when p is false | +| test.c:164:8:164:8 | s | s != 0 when s is true | +| test.c:164:8:164:8 | s | s != 1 when s is false | +| test.c:164:8:164:8 | s | s == 0 when s is false | +| test.c:164:8:164:8 | s | s == 1 when s is true | +| test.c:170:8:170:9 | ! ... | ! ... != 0 when ! ... is true | +| test.c:170:8:170:9 | ! ... | ! ... != 1 when ! ... is false | +| test.c:170:8:170:9 | ! ... | ! ... == 0 when ! ... is false | +| test.c:170:8:170:9 | ! ... | ! ... == 1 when ! ... is true | +| test.c:170:8:170:9 | ! ... | s != 0 when ! ... is false | +| test.c:170:8:170:9 | ! ... | s == 0 when ! ... is true | +| test.c:170:9:170:9 | s | ! ... != 0 when s is false | +| test.c:170:9:170:9 | s | ! ... != 1 when s is true | +| test.c:170:9:170:9 | s | ! ... == 0 when s is true | +| test.c:170:9:170:9 | s | ! ... == 1 when s is false | +| test.c:170:9:170:9 | s | s != 0 when s is true | +| test.c:170:9:170:9 | s | s == 0 when s is false | +| test.c:176:8:176:15 | ! ... | ! ... != 0 when ! ... is true | +| test.c:176:8:176:15 | ! ... | ! ... != 1 when ! ... is false | +| test.c:176:8:176:15 | ! ... | ! ... == 0 when ! ... is false | +| test.c:176:8:176:15 | ! ... | ! ... == 1 when ! ... is true | +| test.c:176:8:176:15 | ! ... | ... < ... != 0 when ! ... is false | +| test.c:176:8:176:15 | ! ... | ... < ... == 0 when ! ... is true | +| test.c:176:8:176:15 | ! ... | a < b+0 when ! ... is false | +| test.c:176:8:176:15 | ! ... | a >= b+0 when ! ... is true | +| test.c:176:8:176:15 | ! ... | b < a+1 when ! ... is true | +| test.c:176:8:176:15 | ! ... | b >= a+1 when ! ... is false | +| test.c:176:10:176:14 | ... < ... | ! ... != 0 when ... < ... is false | +| test.c:176:10:176:14 | ... < ... | ! ... != 1 when ... < ... is true | +| test.c:176:10:176:14 | ... < ... | ! ... == 0 when ... < ... is true | +| test.c:176:10:176:14 | ... < ... | ! ... == 1 when ... < ... is false | +| test.c:176:10:176:14 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.c:176:10:176:14 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.c:176:10:176:14 | ... < ... | a < b+0 when ... < ... is true | +| test.c:176:10:176:14 | ... < ... | a >= b+0 when ... < ... is false | +| test.c:176:10:176:14 | ... < ... | b < a+1 when ... < ... is false | +| test.c:176:10:176:14 | ... < ... | b >= a+1 when ... < ... is true | +| test.c:182:8:182:34 | ! ... | ! ... != 0 when ! ... is true | +| test.c:182:8:182:34 | ! ... | ! ... != 1 when ! ... is false | +| test.c:182:8:182:34 | ! ... | ! ... == 0 when ! ... is false | +| test.c:182:8:182:34 | ! ... | ! ... == 1 when ! ... is true | +| test.c:182:8:182:34 | ! ... | ... && ... != 0 when ! ... is false | +| test.c:182:8:182:34 | ! ... | ... && ... == 0 when ! ... is true | +| test.c:182:10:182:20 | ... >= ... | 9.999999999999999547e-07 < foo+1 when ... >= ... is true | +| test.c:182:10:182:20 | ... >= ... | 9.999999999999999547e-07 >= foo+1 when ... >= ... is false | +| test.c:182:10:182:20 | ... >= ... | ... >= ... != 0 when ... >= ... is true | +| test.c:182:10:182:20 | ... >= ... | ... >= ... != 1 when ... >= ... is false | +| test.c:182:10:182:20 | ... >= ... | ... >= ... == 0 when ... >= ... is false | +| test.c:182:10:182:20 | ... >= ... | ... >= ... == 1 when ... >= ... is true | +| test.c:182:10:182:20 | ... >= ... | foo < 9.999999999999999547e-07+0 when ... >= ... is false | +| test.c:182:10:182:20 | ... >= ... | foo >= 9.999999999999999547e-07+0 when ... >= ... is true | +| test.c:182:10:182:33 | ... && ... | 1.0 >= foo+1 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | 9.999999999999999547e-07 < foo+1 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | ! ... != 0 when ... && ... is false | +| test.c:182:10:182:33 | ... && ... | ! ... != 1 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | ! ... == 0 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | ! ... == 1 when ... && ... is false | +| test.c:182:10:182:33 | ... && ... | ... && ... != 0 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | ... && ... == 0 when ... && ... is false | +| test.c:182:10:182:33 | ... && ... | ... < ... != 0 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | ... < ... == 1 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | ... >= ... != 0 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | ... >= ... == 1 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | foo < 1.0+0 when ... && ... is true | +| test.c:182:10:182:33 | ... && ... | foo >= 9.999999999999999547e-07+0 when ... && ... is true | +| test.c:182:25:182:33 | ... < ... | 1.0 < foo+1 when ... < ... is false | +| test.c:182:25:182:33 | ... < ... | 1.0 >= foo+1 when ... < ... is true | +| test.c:182:25:182:33 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.c:182:25:182:33 | ... < ... | ... < ... != 1 when ... < ... is false | +| test.c:182:25:182:33 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.c:182:25:182:33 | ... < ... | ... < ... == 1 when ... < ... is true | +| test.c:182:25:182:33 | ... < ... | foo < 1.0+0 when ... < ... is true | +| test.c:182:25:182:33 | ... < ... | foo >= 1.0+0 when ... < ... is false | +| test.c:190:7:190:8 | ! ... | ! ... != 0 when ! ... is true | +| test.c:190:7:190:8 | ! ... | ! ... != 1 when ! ... is false | +| test.c:190:7:190:8 | ! ... | ! ... == 0 when ! ... is false | +| test.c:190:7:190:8 | ! ... | ! ... == 1 when ! ... is true | +| test.c:190:7:190:8 | ! ... | a != b+0 when ! ... is false | +| test.c:190:7:190:8 | ! ... | a == b+0 when ! ... is true | +| test.c:190:7:190:8 | ! ... | b != a+0 when ! ... is false | +| test.c:190:7:190:8 | ! ... | b == a+0 when ! ... is true | +| test.c:190:7:190:8 | ! ... | c != 0 when ! ... is false | +| test.c:190:7:190:8 | ! ... | c == 0 when ! ... is true | +| test.c:190:8:190:8 | c | ! ... != 0 when c is false | +| test.c:190:8:190:8 | c | ! ... != 1 when c is true | +| test.c:190:8:190:8 | c | ! ... == 0 when c is true | +| test.c:190:8:190:8 | c | ! ... == 1 when c is false | +| test.c:190:8:190:8 | c | a != b+0 when c is true | +| test.c:190:8:190:8 | c | a == b+0 when c is false | +| test.c:190:8:190:8 | c | b != a+0 when c is true | +| test.c:190:8:190:8 | c | b == a+0 when c is false | +| test.c:190:8:190:8 | c | c != 0 when c is true | +| test.c:190:8:190:8 | c | c == 0 when c is false | +| test.c:198:7:198:8 | ! ... | 10 < a+0 when ! ... is false | +| test.c:198:7:198:8 | ! ... | 10 >= a+0 when ! ... is true | +| test.c:198:7:198:8 | ! ... | ! ... != 0 when ! ... is true | +| test.c:198:7:198:8 | ! ... | ! ... != 1 when ! ... is false | +| test.c:198:7:198:8 | ! ... | ! ... == 0 when ! ... is false | +| test.c:198:7:198:8 | ! ... | ! ... == 1 when ! ... is true | +| test.c:198:7:198:8 | ! ... | a < 10+1 when ! ... is true | +| test.c:198:7:198:8 | ! ... | a < 11 when ! ... is true | +| test.c:198:7:198:8 | ! ... | a >= 10+1 when ! ... is false | +| test.c:198:7:198:8 | ! ... | a >= 11 when ! ... is false | +| test.c:198:7:198:8 | ! ... | b != 0 when ! ... is false | +| test.c:198:7:198:8 | ! ... | b == 0 when ! ... is true | +| test.c:198:8:198:8 | b | 10 < a+0 when b is true | +| test.c:198:8:198:8 | b | 10 >= a+0 when b is false | +| test.c:198:8:198:8 | b | ! ... != 0 when b is false | +| test.c:198:8:198:8 | b | ! ... != 1 when b is true | +| test.c:198:8:198:8 | b | ! ... == 0 when b is true | +| test.c:198:8:198:8 | b | ! ... == 1 when b is false | +| test.c:198:8:198:8 | b | a < 10+1 when b is false | +| test.c:198:8:198:8 | b | a < 11 when b is false | +| test.c:198:8:198:8 | b | a >= 10+1 when b is true | +| test.c:198:8:198:8 | b | a >= 11 when b is true | +| test.c:198:8:198:8 | b | b != 0 when b is true | +| test.c:198:8:198:8 | b | b == 0 when b is false | +| test.c:206:7:206:8 | ! ... | ! ... != 0 when ! ... is true | +| test.c:206:7:206:8 | ! ... | ! ... != 1 when ! ... is false | +| test.c:206:7:206:8 | ! ... | ! ... == 0 when ! ... is false | +| test.c:206:7:206:8 | ! ... | ! ... == 1 when ! ... is true | +| test.c:206:7:206:8 | ! ... | a < b+1 when ! ... is true | +| test.c:206:7:206:8 | ! ... | a >= b+1 when ! ... is false | +| test.c:206:7:206:8 | ! ... | b < a+0 when ! ... is false | +| test.c:206:7:206:8 | ! ... | b >= a+0 when ! ... is true | +| test.c:206:7:206:8 | ! ... | c != 0 when ! ... is false | +| test.c:206:7:206:8 | ! ... | c == 0 when ! ... is true | +| test.c:206:8:206:8 | c | ! ... != 0 when c is false | +| test.c:206:8:206:8 | c | ! ... != 1 when c is true | +| test.c:206:8:206:8 | c | ! ... == 0 when c is true | +| test.c:206:8:206:8 | c | ! ... == 1 when c is false | +| test.c:206:8:206:8 | c | a < b+1 when c is false | +| test.c:206:8:206:8 | c | a >= b+1 when c is true | +| test.c:206:8:206:8 | c | b < a+0 when c is true | +| test.c:206:8:206:8 | c | b >= a+0 when c is false | +| test.c:206:8:206:8 | c | c != 0 when c is true | +| test.c:206:8:206:8 | c | c == 0 when c is false | +| test.c:215:6:215:18 | call to __builtin_expect | ... > ... != 0 when call to __builtin_expect is true | +| test.c:215:6:215:18 | call to __builtin_expect | ... > ... == 0 when call to __builtin_expect is false | +| test.c:215:6:215:18 | call to __builtin_expect | a < b+1 when call to __builtin_expect is false | +| test.c:215:6:215:18 | call to __builtin_expect | a >= b+1 when call to __builtin_expect is true | +| test.c:215:6:215:18 | call to __builtin_expect | b < a+0 when call to __builtin_expect is true | +| test.c:215:6:215:18 | call to __builtin_expect | b >= a+0 when call to __builtin_expect is false | +| test.c:215:6:215:18 | call to __builtin_expect | call to __builtin_expect != 0 when call to __builtin_expect is true | +| test.c:215:6:215:18 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | +| test.c:215:6:215:18 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | +| test.c:215:6:215:18 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.c:219:9:219:22 | call to __builtin_expect | 42 < a+0 when call to __builtin_expect is true | +| test.c:219:9:219:22 | call to __builtin_expect | 42 >= a+0 when call to __builtin_expect is false | +| test.c:219:9:219:22 | call to __builtin_expect | ... > ... != 0 when call to __builtin_expect is true | +| test.c:219:9:219:22 | call to __builtin_expect | ... > ... == 0 when call to __builtin_expect is false | +| test.c:219:9:219:22 | call to __builtin_expect | a < 42+1 when call to __builtin_expect is false | +| test.c:219:9:219:22 | call to __builtin_expect | a < 43 when call to __builtin_expect is false | +| test.c:219:9:219:22 | call to __builtin_expect | a >= 42+1 when call to __builtin_expect is true | +| test.c:219:9:219:22 | call to __builtin_expect | a >= 43 when call to __builtin_expect is true | +| test.c:219:9:219:22 | call to __builtin_expect | call to __builtin_expect != 0 when call to __builtin_expect is true | +| test.c:219:9:219:22 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | +| test.c:219:9:219:22 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | +| test.c:219:9:219:22 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:18:8:18:10 | call to get | call to get != 0 when call to get is true | +| test.cpp:18:8:18:10 | call to get | call to get != 1 when call to get is false | +| test.cpp:18:8:18:10 | call to get | call to get == 0 when call to get is false | +| test.cpp:18:8:18:10 | call to get | call to get == 1 when call to get is true | +| test.cpp:31:7:31:13 | ... == ... | - ... != x+0 when ... == ... is false | +| test.cpp:31:7:31:13 | ... == ... | - ... == x+0 when ... == ... is true | +| test.cpp:31:7:31:13 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:31:7:31:13 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:31:7:31:13 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:31:7:31:13 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:31:7:31:13 | ... == ... | x != -1 when ... == ... is false | +| test.cpp:31:7:31:13 | ... == ... | x != - ...+0 when ... == ... is false | +| test.cpp:31:7:31:13 | ... == ... | x == -1 when ... == ... is true | +| test.cpp:31:7:31:13 | ... == ... | x == - ...+0 when ... == ... is true | +| test.cpp:42:13:42:20 | call to getABool | call to getABool != 0 when call to getABool is true | +| test.cpp:42:13:42:20 | call to getABool | call to getABool != 1 when call to getABool is false | +| test.cpp:42:13:42:20 | call to getABool | call to getABool == 0 when call to getABool is false | +| test.cpp:42:13:42:20 | call to getABool | call to getABool == 1 when call to getABool is true | +| test.cpp:61:10:61:10 | i | i == 0 when i is Case[0] | +| test.cpp:61:10:61:10 | i | i == 1 when i is Case[1] | +| test.cpp:61:10:61:10 | i | i == 2 when i is Case[2] | +| test.cpp:74:10:74:10 | i | i < 11 when i is Case[0..10] | +| test.cpp:74:10:74:10 | i | i < 21 when i is Case[11..20] | +| test.cpp:74:10:74:10 | i | i >= 0 when i is Case[0..10] | +| test.cpp:74:10:74:10 | i | i >= 11 when i is Case[11..20] | +| test.cpp:93:6:93:6 | c | c != 0 when c is true | +| test.cpp:93:6:93:6 | c | c != 1 when c is false | +| test.cpp:93:6:93:6 | c | c == 0 when c is false | +| test.cpp:93:6:93:6 | c | c == 1 when c is true | +| test.cpp:99:6:99:6 | f | f != 0 when f is true | +| test.cpp:99:6:99:6 | f | f != 1 when f is false | +| test.cpp:99:6:99:6 | f | f == 0 when f is false | +| test.cpp:99:6:99:6 | f | f == 1 when f is true | +| test.cpp:105:6:105:14 | ... != ... | 0.0 != f+0 when ... != ... is true | +| test.cpp:105:6:105:14 | ... != ... | 0.0 == f+0 when ... != ... is false | +| test.cpp:105:6:105:14 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:105:6:105:14 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:105:6:105:14 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:105:6:105:14 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:105:6:105:14 | ... != ... | f != 0.0+0 when ... != ... is true | +| test.cpp:105:6:105:14 | ... != ... | f == 0.0+0 when ... != ... is false | +| test.cpp:111:6:111:14 | ... != ... | 0.0 != i+0 when ... != ... is true | +| test.cpp:111:6:111:14 | ... != ... | 0.0 == i+0 when ... != ... is false | +| test.cpp:111:6:111:14 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:111:6:111:14 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:111:6:111:14 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:111:6:111:14 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:111:6:111:14 | ... != ... | i != 0.0+0 when ... != ... is true | +| test.cpp:111:6:111:14 | ... != ... | i == 0.0+0 when ... != ... is false | +| test.cpp:122:9:122:9 | b | b != 0 when b is true | +| test.cpp:122:9:122:9 | b | b != 1 when b is false | +| test.cpp:122:9:122:9 | b | b == 0 when b is false | +| test.cpp:122:9:122:9 | b | b == 1 when b is true | +| test.cpp:125:13:125:20 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:125:13:125:20 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:125:13:125:20 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:125:13:125:20 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:125:13:125:20 | ! ... | call to safe != 0 when ! ... is false | +| test.cpp:125:13:125:20 | ! ... | call to safe != 1 when ! ... is true | +| test.cpp:125:13:125:20 | ! ... | call to safe == 0 when ! ... is true | +| test.cpp:125:13:125:20 | ! ... | call to safe == 1 when ! ... is false | +| test.cpp:125:14:125:17 | call to safe | ! ... != 0 when call to safe is false | +| test.cpp:125:14:125:17 | call to safe | ! ... != 1 when call to safe is true | +| test.cpp:125:14:125:17 | call to safe | ! ... == 0 when call to safe is true | +| test.cpp:125:14:125:17 | call to safe | ! ... == 1 when call to safe is false | +| test.cpp:125:14:125:17 | call to safe | call to safe != 0 when call to safe is true | +| test.cpp:125:14:125:17 | call to safe | call to safe != 1 when call to safe is false | +| test.cpp:125:14:125:17 | call to safe | call to safe == 0 when call to safe is false | +| test.cpp:125:14:125:17 | call to safe | call to safe == 1 when call to safe is true | +| test.cpp:131:6:131:21 | call to __builtin_expect | ... + ... != a+0 when call to __builtin_expect is false | +| test.cpp:131:6:131:21 | call to __builtin_expect | ... + ... == a+0 when call to __builtin_expect is true | +| test.cpp:131:6:131:21 | call to __builtin_expect | a != ... + ...+0 when call to __builtin_expect is false | +| test.cpp:131:6:131:21 | call to __builtin_expect | a != b+42 when call to __builtin_expect is false | +| test.cpp:131:6:131:21 | call to __builtin_expect | a == ... + ...+0 when call to __builtin_expect is true | +| test.cpp:131:6:131:21 | call to __builtin_expect | a == b+42 when call to __builtin_expect is true | +| test.cpp:131:6:131:21 | call to __builtin_expect | b != a+-42 when call to __builtin_expect is false | +| test.cpp:131:6:131:21 | call to __builtin_expect | b == a+-42 when call to __builtin_expect is true | +| test.cpp:131:6:131:21 | call to __builtin_expect | call to __builtin_expect != 0 when call to __builtin_expect is true | +| test.cpp:131:6:131:21 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | +| test.cpp:131:6:131:21 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | +| test.cpp:131:6:131:21 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:135:6:135:21 | call to __builtin_expect | ... + ... != a+0 when call to __builtin_expect is true | +| test.cpp:135:6:135:21 | call to __builtin_expect | ... + ... == a+0 when call to __builtin_expect is false | +| test.cpp:135:6:135:21 | call to __builtin_expect | a != ... + ...+0 when call to __builtin_expect is true | +| test.cpp:135:6:135:21 | call to __builtin_expect | a != b+42 when call to __builtin_expect is true | +| test.cpp:135:6:135:21 | call to __builtin_expect | a == ... + ...+0 when call to __builtin_expect is false | +| test.cpp:135:6:135:21 | call to __builtin_expect | a == b+42 when call to __builtin_expect is false | +| test.cpp:135:6:135:21 | call to __builtin_expect | b != a+-42 when call to __builtin_expect is true | +| test.cpp:135:6:135:21 | call to __builtin_expect | b == a+-42 when call to __builtin_expect is false | +| test.cpp:135:6:135:21 | call to __builtin_expect | call to __builtin_expect != 0 when call to __builtin_expect is true | +| test.cpp:135:6:135:21 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | +| test.cpp:135:6:135:21 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | +| test.cpp:135:6:135:21 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:141:6:141:21 | call to __builtin_expect | 42 != a+0 when call to __builtin_expect is false | +| test.cpp:141:6:141:21 | call to __builtin_expect | 42 == a+0 when call to __builtin_expect is true | +| test.cpp:141:6:141:21 | call to __builtin_expect | a != 42 when call to __builtin_expect is false | +| test.cpp:141:6:141:21 | call to __builtin_expect | a != 42+0 when call to __builtin_expect is false | +| test.cpp:141:6:141:21 | call to __builtin_expect | a == 42 when call to __builtin_expect is true | +| test.cpp:141:6:141:21 | call to __builtin_expect | a == 42+0 when call to __builtin_expect is true | +| test.cpp:141:6:141:21 | call to __builtin_expect | call to __builtin_expect != 0 when call to __builtin_expect is true | +| test.cpp:141:6:141:21 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | +| test.cpp:141:6:141:21 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | +| test.cpp:141:6:141:21 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:145:6:145:21 | call to __builtin_expect | 42 != a+0 when call to __builtin_expect is true | +| test.cpp:145:6:145:21 | call to __builtin_expect | 42 == a+0 when call to __builtin_expect is false | +| test.cpp:145:6:145:21 | call to __builtin_expect | a != 42 when call to __builtin_expect is true | +| test.cpp:145:6:145:21 | call to __builtin_expect | a != 42+0 when call to __builtin_expect is true | +| test.cpp:145:6:145:21 | call to __builtin_expect | a == 42 when call to __builtin_expect is false | +| test.cpp:145:6:145:21 | call to __builtin_expect | a == 42+0 when call to __builtin_expect is false | +| test.cpp:145:6:145:21 | call to __builtin_expect | call to __builtin_expect != 0 when call to __builtin_expect is true | +| test.cpp:145:6:145:21 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | +| test.cpp:145:6:145:21 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | +| test.cpp:145:6:145:21 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:152:7:152:8 | ! ... | 10 < a+1 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | 10 >= a+1 when ! ... is false | +| test.cpp:152:7:152:8 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:152:7:152:8 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:152:7:152:8 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | ... < ... != 0 when ! ... is false | +| test.cpp:152:7:152:8 | ! ... | ... < ... != 1 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | ... < ... == 0 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | ... < ... == 1 when ! ... is false | +| test.cpp:152:7:152:8 | ! ... | a < 10 when ! ... is false | +| test.cpp:152:7:152:8 | ! ... | a < 10+0 when ! ... is false | +| test.cpp:152:7:152:8 | ! ... | a >= 10 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | a >= 10+0 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | b != 0 when ! ... is false | +| test.cpp:152:7:152:8 | ! ... | b != 1 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | b == 0 when ! ... is true | +| test.cpp:152:7:152:8 | ! ... | b == 1 when ! ... is false | +| test.cpp:152:8:152:8 | b | 10 < a+1 when b is false | +| test.cpp:152:8:152:8 | b | 10 >= a+1 when b is true | +| test.cpp:152:8:152:8 | b | ! ... != 0 when b is false | +| test.cpp:152:8:152:8 | b | ! ... != 1 when b is true | +| test.cpp:152:8:152:8 | b | ! ... == 0 when b is true | +| test.cpp:152:8:152:8 | b | ! ... == 1 when b is false | +| test.cpp:152:8:152:8 | b | ... < ... != 0 when b is true | +| test.cpp:152:8:152:8 | b | ... < ... != 1 when b is false | +| test.cpp:152:8:152:8 | b | ... < ... == 0 when b is false | +| test.cpp:152:8:152:8 | b | ... < ... == 1 when b is true | +| test.cpp:152:8:152:8 | b | a < 10 when b is true | +| test.cpp:152:8:152:8 | b | a < 10+0 when b is true | +| test.cpp:152:8:152:8 | b | a >= 10 when b is false | +| test.cpp:152:8:152:8 | b | a >= 10+0 when b is false | +| test.cpp:152:8:152:8 | b | b != 0 when b is true | +| test.cpp:152:8:152:8 | b | b != 1 when b is false | +| test.cpp:152:8:152:8 | b | b == 0 when b is false | +| test.cpp:152:8:152:8 | b | b == 1 when b is true | +| test.cpp:160:7:160:8 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:160:7:160:8 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:160:7:160:8 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:160:7:160:8 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:160:7:160:8 | ! ... | ... != ... != 0 when ! ... is false | +| test.cpp:160:7:160:8 | ! ... | ... != ... != 1 when ! ... is true | +| test.cpp:160:7:160:8 | ! ... | ... != ... == 0 when ! ... is true | +| test.cpp:160:7:160:8 | ! ... | ... != ... == 1 when ! ... is false | +| test.cpp:160:7:160:8 | ! ... | a != b+0 when ! ... is false | +| test.cpp:160:7:160:8 | ! ... | a == b+0 when ! ... is true | +| test.cpp:160:7:160:8 | ! ... | b != a+0 when ! ... is false | +| test.cpp:160:7:160:8 | ! ... | b == a+0 when ! ... is true | +| test.cpp:160:7:160:8 | ! ... | c != 0 when ! ... is false | +| test.cpp:160:7:160:8 | ! ... | c != 1 when ! ... is true | +| test.cpp:160:7:160:8 | ! ... | c == 0 when ! ... is true | +| test.cpp:160:7:160:8 | ! ... | c == 1 when ! ... is false | +| test.cpp:160:8:160:8 | c | ! ... != 0 when c is false | +| test.cpp:160:8:160:8 | c | ! ... != 1 when c is true | +| test.cpp:160:8:160:8 | c | ! ... == 0 when c is true | +| test.cpp:160:8:160:8 | c | ! ... == 1 when c is false | +| test.cpp:160:8:160:8 | c | ... != ... != 0 when c is true | +| test.cpp:160:8:160:8 | c | ... != ... != 1 when c is false | +| test.cpp:160:8:160:8 | c | ... != ... == 0 when c is false | +| test.cpp:160:8:160:8 | c | ... != ... == 1 when c is true | +| test.cpp:160:8:160:8 | c | a != b+0 when c is true | +| test.cpp:160:8:160:8 | c | a == b+0 when c is false | +| test.cpp:160:8:160:8 | c | b != a+0 when c is true | +| test.cpp:160:8:160:8 | c | b == a+0 when c is false | +| test.cpp:160:8:160:8 | c | c != 0 when c is true | +| test.cpp:160:8:160:8 | c | c != 1 when c is false | +| test.cpp:160:8:160:8 | c | c == 0 when c is false | +| test.cpp:160:8:160:8 | c | c == 1 when c is true | +| test.cpp:168:7:168:8 | ! ... | 10 < a+0 when ! ... is false | +| test.cpp:168:7:168:8 | ! ... | 10 >= a+0 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:168:7:168:8 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:168:7:168:8 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | ... > ... != 0 when ! ... is false | +| test.cpp:168:7:168:8 | ! ... | ... > ... != 1 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | ... > ... == 0 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | ... > ... == 1 when ! ... is false | +| test.cpp:168:7:168:8 | ! ... | a < 10+1 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | a < 11 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | a >= 10+1 when ! ... is false | +| test.cpp:168:7:168:8 | ! ... | a >= 11 when ! ... is false | +| test.cpp:168:7:168:8 | ! ... | b != 0 when ! ... is false | +| test.cpp:168:7:168:8 | ! ... | b != 1 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | b == 0 when ! ... is true | +| test.cpp:168:7:168:8 | ! ... | b == 1 when ! ... is false | +| test.cpp:168:8:168:8 | b | 10 < a+0 when b is true | +| test.cpp:168:8:168:8 | b | 10 >= a+0 when b is false | +| test.cpp:168:8:168:8 | b | ! ... != 0 when b is false | +| test.cpp:168:8:168:8 | b | ! ... != 1 when b is true | +| test.cpp:168:8:168:8 | b | ! ... == 0 when b is true | +| test.cpp:168:8:168:8 | b | ! ... == 1 when b is false | +| test.cpp:168:8:168:8 | b | ... > ... != 0 when b is true | +| test.cpp:168:8:168:8 | b | ... > ... != 1 when b is false | +| test.cpp:168:8:168:8 | b | ... > ... == 0 when b is false | +| test.cpp:168:8:168:8 | b | ... > ... == 1 when b is true | +| test.cpp:168:8:168:8 | b | a < 10+1 when b is false | +| test.cpp:168:8:168:8 | b | a < 11 when b is false | +| test.cpp:168:8:168:8 | b | a >= 10+1 when b is true | +| test.cpp:168:8:168:8 | b | a >= 11 when b is true | +| test.cpp:168:8:168:8 | b | b != 0 when b is true | +| test.cpp:168:8:168:8 | b | b != 1 when b is false | +| test.cpp:168:8:168:8 | b | b == 0 when b is false | +| test.cpp:168:8:168:8 | b | b == 1 when b is true | +| test.cpp:176:7:176:8 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:176:7:176:8 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:176:7:176:8 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:176:7:176:8 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:176:7:176:8 | ! ... | ... > ... != 0 when ! ... is false | +| test.cpp:176:7:176:8 | ! ... | ... > ... != 1 when ! ... is true | +| test.cpp:176:7:176:8 | ! ... | ... > ... == 0 when ! ... is true | +| test.cpp:176:7:176:8 | ! ... | ... > ... == 1 when ! ... is false | +| test.cpp:176:7:176:8 | ! ... | a < b+1 when ! ... is true | +| test.cpp:176:7:176:8 | ! ... | a >= b+1 when ! ... is false | +| test.cpp:176:7:176:8 | ! ... | b < a+0 when ! ... is false | +| test.cpp:176:7:176:8 | ! ... | b >= a+0 when ! ... is true | +| test.cpp:176:7:176:8 | ! ... | c != 0 when ! ... is false | +| test.cpp:176:7:176:8 | ! ... | c != 1 when ! ... is true | +| test.cpp:176:7:176:8 | ! ... | c == 0 when ! ... is true | +| test.cpp:176:7:176:8 | ! ... | c == 1 when ! ... is false | +| test.cpp:176:8:176:8 | c | ! ... != 0 when c is false | +| test.cpp:176:8:176:8 | c | ! ... != 1 when c is true | +| test.cpp:176:8:176:8 | c | ! ... == 0 when c is true | +| test.cpp:176:8:176:8 | c | ! ... == 1 when c is false | +| test.cpp:176:8:176:8 | c | ... > ... != 0 when c is true | +| test.cpp:176:8:176:8 | c | ... > ... != 1 when c is false | +| test.cpp:176:8:176:8 | c | ... > ... == 0 when c is false | +| test.cpp:176:8:176:8 | c | ... > ... == 1 when c is true | +| test.cpp:176:8:176:8 | c | a < b+1 when c is false | +| test.cpp:176:8:176:8 | c | a >= b+1 when c is true | +| test.cpp:176:8:176:8 | c | b < a+0 when c is true | +| test.cpp:176:8:176:8 | c | b >= a+0 when c is false | +| test.cpp:176:8:176:8 | c | c != 0 when c is true | +| test.cpp:176:8:176:8 | c | c != 1 when c is false | +| test.cpp:176:8:176:8 | c | c == 0 when c is false | +| test.cpp:176:8:176:8 | c | c == 1 when c is true | +| test.cpp:182:6:182:16 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:182:6:182:16 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:182:6:182:16 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:182:6:182:16 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:182:6:182:16 | ! ... | ... && ... != 0 when ! ... is false | +| test.cpp:182:6:182:16 | ! ... | ... && ... != 1 when ! ... is true | +| test.cpp:182:6:182:16 | ! ... | ... && ... == 0 when ! ... is true | +| test.cpp:182:6:182:16 | ! ... | ... && ... == 1 when ! ... is false | +| test.cpp:182:6:182:16 | ! ... | b1 != 0 when ! ... is false | +| test.cpp:182:6:182:16 | ! ... | b1 == 1 when ! ... is false | +| test.cpp:182:6:182:16 | ! ... | b2 != 0 when ! ... is false | +| test.cpp:182:6:182:16 | ! ... | b2 == 1 when ! ... is false | +| test.cpp:182:8:182:9 | b1 | b1 != 0 when b1 is true | +| test.cpp:182:8:182:9 | b1 | b1 != 1 when b1 is false | +| test.cpp:182:8:182:9 | b1 | b1 == 0 when b1 is false | +| test.cpp:182:8:182:9 | b1 | b1 == 1 when b1 is true | +| test.cpp:182:8:182:15 | ... && ... | ! ... != 0 when ... && ... is false | +| test.cpp:182:8:182:15 | ... && ... | ! ... != 1 when ... && ... is true | +| test.cpp:182:8:182:15 | ... && ... | ! ... == 0 when ... && ... is true | +| test.cpp:182:8:182:15 | ... && ... | ! ... == 1 when ... && ... is false | +| test.cpp:182:8:182:15 | ... && ... | ... && ... != 0 when ... && ... is true | +| test.cpp:182:8:182:15 | ... && ... | ... && ... != 1 when ... && ... is false | +| test.cpp:182:8:182:15 | ... && ... | ... && ... == 0 when ... && ... is false | +| test.cpp:182:8:182:15 | ... && ... | ... && ... == 1 when ... && ... is true | +| test.cpp:182:8:182:15 | ... && ... | b1 != 0 when ... && ... is true | +| test.cpp:182:8:182:15 | ... && ... | b1 == 1 when ... && ... is true | +| test.cpp:182:8:182:15 | ... && ... | b2 != 0 when ... && ... is true | +| test.cpp:182:8:182:15 | ... && ... | b2 == 1 when ... && ... is true | +| test.cpp:182:14:182:15 | b2 | b2 != 0 when b2 is true | +| test.cpp:182:14:182:15 | b2 | b2 != 1 when b2 is false | +| test.cpp:182:14:182:15 | b2 | b2 == 0 when b2 is false | +| test.cpp:182:14:182:15 | b2 | b2 == 1 when b2 is true | +| test.cpp:193:6:193:16 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:193:6:193:16 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:193:6:193:16 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:193:6:193:16 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:193:6:193:16 | ! ... | ... \|\| ... != 0 when ! ... is false | +| test.cpp:193:6:193:16 | ! ... | ... \|\| ... != 1 when ! ... is true | +| test.cpp:193:6:193:16 | ! ... | ... \|\| ... == 0 when ! ... is true | +| test.cpp:193:6:193:16 | ! ... | ... \|\| ... == 1 when ! ... is false | +| test.cpp:193:6:193:16 | ! ... | b1 != 1 when ! ... is true | +| test.cpp:193:6:193:16 | ! ... | b1 == 0 when ! ... is true | +| test.cpp:193:6:193:16 | ! ... | b2 != 1 when ! ... is true | +| test.cpp:193:6:193:16 | ! ... | b2 == 0 when ! ... is true | +| test.cpp:193:8:193:9 | b1 | b1 != 0 when b1 is true | +| test.cpp:193:8:193:9 | b1 | b1 != 1 when b1 is false | +| test.cpp:193:8:193:9 | b1 | b1 == 0 when b1 is false | +| test.cpp:193:8:193:9 | b1 | b1 == 1 when b1 is true | +| test.cpp:193:8:193:15 | ... \|\| ... | ! ... != 0 when ... \|\| ... is false | +| test.cpp:193:8:193:15 | ... \|\| ... | ! ... != 1 when ... \|\| ... is true | +| test.cpp:193:8:193:15 | ... \|\| ... | ! ... == 0 when ... \|\| ... is true | +| test.cpp:193:8:193:15 | ... \|\| ... | ! ... == 1 when ... \|\| ... is false | +| test.cpp:193:8:193:15 | ... \|\| ... | ... \|\| ... != 0 when ... \|\| ... is true | +| test.cpp:193:8:193:15 | ... \|\| ... | ... \|\| ... != 1 when ... \|\| ... is false | +| test.cpp:193:8:193:15 | ... \|\| ... | ... \|\| ... == 0 when ... \|\| ... is false | +| test.cpp:193:8:193:15 | ... \|\| ... | ... \|\| ... == 1 when ... \|\| ... is true | +| test.cpp:193:8:193:15 | ... \|\| ... | b1 != 1 when ... \|\| ... is false | +| test.cpp:193:8:193:15 | ... \|\| ... | b1 == 0 when ... \|\| ... is false | +| test.cpp:193:8:193:15 | ... \|\| ... | b2 != 1 when ... \|\| ... is false | +| test.cpp:193:8:193:15 | ... \|\| ... | b2 == 0 when ... \|\| ... is false | +| test.cpp:193:14:193:15 | b2 | b2 != 0 when b2 is true | +| test.cpp:193:14:193:15 | b2 | b2 != 1 when b2 is false | +| test.cpp:193:14:193:15 | b2 | b2 == 0 when b2 is false | +| test.cpp:193:14:193:15 | b2 | b2 == 1 when b2 is true | +| test.cpp:211:9:211:15 | ... == ... | 0 != sc+0 when ... == ... is false | +| test.cpp:211:9:211:15 | ... == ... | 0 == sc+0 when ... == ... is true | +| test.cpp:211:9:211:15 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:211:9:211:15 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:211:9:211:15 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:211:9:211:15 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:211:9:211:15 | ... == ... | sc != 0 when ... == ... is false | +| test.cpp:211:9:211:15 | ... == ... | sc != 0+0 when ... == ... is false | +| test.cpp:211:9:211:15 | ... == ... | sc == 0 when ... == ... is true | +| test.cpp:211:9:211:15 | ... == ... | sc == 0+0 when ... == ... is true | +| test.cpp:214:9:214:17 | ... == ... | 0 != sc+0 when ... == ... is false | +| test.cpp:214:9:214:17 | ... == ... | 0 == sc+0 when ... == ... is true | +| test.cpp:214:9:214:17 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:214:9:214:17 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:214:9:214:17 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:214:9:214:17 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:214:9:214:17 | ... == ... | sc != 0 when ... == ... is false | +| test.cpp:214:9:214:17 | ... == ... | sc != 0+0 when ... == ... is false | +| test.cpp:214:9:214:17 | ... == ... | sc == 0 when ... == ... is true | +| test.cpp:214:9:214:17 | ... == ... | sc == 0+0 when ... == ... is true | +| test.cpp:217:9:217:15 | ... == ... | 0 != ul+0 when ... == ... is false | +| test.cpp:217:9:217:15 | ... == ... | 0 == ul+0 when ... == ... is true | +| test.cpp:217:9:217:15 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:217:9:217:15 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:217:9:217:15 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:217:9:217:15 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:217:9:217:15 | ... == ... | ul != 0 when ... == ... is false | +| test.cpp:217:9:217:15 | ... == ... | ul != 0+0 when ... == ... is false | +| test.cpp:217:9:217:15 | ... == ... | ul == 0 when ... == ... is true | +| test.cpp:217:9:217:15 | ... == ... | ul == 0+0 when ... == ... is true | +| test.cpp:220:9:220:14 | ... == ... | 0 != f+0 when ... == ... is false | +| test.cpp:220:9:220:14 | ... == ... | 0 == f+0 when ... == ... is true | +| test.cpp:220:9:220:14 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:220:9:220:14 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:220:9:220:14 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:220:9:220:14 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:220:9:220:14 | ... == ... | f != 0+0 when ... == ... is false | +| test.cpp:220:9:220:14 | ... == ... | f == 0+0 when ... == ... is true | +| test.cpp:223:9:223:16 | ... == ... | 0.0 != f+0 when ... == ... is false | +| test.cpp:223:9:223:16 | ... == ... | 0.0 == f+0 when ... == ... is true | +| test.cpp:223:9:223:16 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:223:9:223:16 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:223:9:223:16 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:223:9:223:16 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:223:9:223:16 | ... == ... | f != 0.0+0 when ... == ... is false | +| test.cpp:223:9:223:16 | ... == ... | f == 0.0+0 when ... == ... is true | +| test.cpp:226:9:226:14 | ... == ... | 0 != d+0 when ... == ... is false | +| test.cpp:226:9:226:14 | ... == ... | 0 == d+0 when ... == ... is true | +| test.cpp:226:9:226:14 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:226:9:226:14 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:226:9:226:14 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:226:9:226:14 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:226:9:226:14 | ... == ... | d != 0+0 when ... == ... is false | +| test.cpp:226:9:226:14 | ... == ... | d == 0+0 when ... == ... is true | +| test.cpp:229:9:229:14 | ... == ... | 0 != b+0 when ... == ... is false | +| test.cpp:229:9:229:14 | ... == ... | 0 == b+0 when ... == ... is true | +| test.cpp:229:9:229:14 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:229:9:229:14 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:229:9:229:14 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:229:9:229:14 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:229:9:229:14 | ... == ... | b != 0 when ... == ... is false | +| test.cpp:229:9:229:14 | ... == ... | b != 0+0 when ... == ... is false | +| test.cpp:229:9:229:14 | ... == ... | b == 0 when ... == ... is true | +| test.cpp:229:9:229:14 | ... == ... | b == 0+0 when ... == ... is true | +| test.cpp:232:9:232:18 | ... == ... | 0 != b+0 when ... == ... is false | +| test.cpp:232:9:232:18 | ... == ... | 0 == b+0 when ... == ... is true | +| test.cpp:232:9:232:18 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:232:9:232:18 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:232:9:232:18 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:232:9:232:18 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:232:9:232:18 | ... == ... | b != 0 when ... == ... is false | +| test.cpp:232:9:232:18 | ... == ... | b != 0+0 when ... == ... is false | +| test.cpp:232:9:232:18 | ... == ... | b == 0 when ... == ... is true | +| test.cpp:232:9:232:18 | ... == ... | b == 0+0 when ... == ... is true | +| test.cpp:235:9:235:17 | ... == ... | 0 != i+0 when ... == ... is false | +| test.cpp:235:9:235:17 | ... == ... | 0 == i+0 when ... == ... is true | +| test.cpp:235:9:235:17 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:235:9:235:17 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:235:9:235:17 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:235:9:235:17 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:235:9:235:17 | ... == ... | i != 0 when ... == ... is false | +| test.cpp:235:9:235:17 | ... == ... | i != 0+0 when ... == ... is false | +| test.cpp:235:9:235:17 | ... == ... | i == 0 when ... == ... is true | +| test.cpp:235:9:235:17 | ... == ... | i == 0+0 when ... == ... is true | +| test.cpp:238:9:238:17 | ... == ... | 0 != f+0 when ... == ... is false | +| test.cpp:238:9:238:17 | ... == ... | 0 == f+0 when ... == ... is true | +| test.cpp:238:9:238:17 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:238:9:238:17 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:238:9:238:17 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:238:9:238:17 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:238:9:238:17 | ... == ... | f != 0+0 when ... == ... is false | +| test.cpp:238:9:238:17 | ... == ... | f == 0+0 when ... == ... is true | +| test.cpp:241:9:241:17 | ... == ... | 0 != i+0 when ... == ... is false | +| test.cpp:241:9:241:17 | ... == ... | 0 == i+0 when ... == ... is true | +| test.cpp:241:9:241:17 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:241:9:241:17 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:241:9:241:17 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:241:9:241:17 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:241:9:241:17 | ... == ... | i != 0 when ... == ... is false | +| test.cpp:241:9:241:17 | ... == ... | i != 0+0 when ... == ... is false | +| test.cpp:241:9:241:17 | ... == ... | i == 0 when ... == ... is true | +| test.cpp:241:9:241:17 | ... == ... | i == 0+0 when ... == ... is true | +| test.cpp:241:9:241:30 | ... && ... | 0 == f+0 when ... && ... is true | +| test.cpp:241:9:241:30 | ... && ... | 0 == i+0 when ... && ... is true | +| test.cpp:241:9:241:30 | ... && ... | ... == ... != 0 when ... && ... is true | +| test.cpp:241:9:241:30 | ... && ... | ... == ... == 1 when ... && ... is true | +| test.cpp:241:9:241:30 | ... && ... | f == 0+0 when ... && ... is true | +| test.cpp:241:9:241:30 | ... && ... | i == 0 when ... && ... is true | +| test.cpp:241:9:241:30 | ... && ... | i == 0+0 when ... && ... is true | +| test.cpp:241:9:241:43 | ... && ... | 0 == f+0 when ... && ... is true | +| test.cpp:241:9:241:43 | ... && ... | 0 == i+0 when ... && ... is true | +| test.cpp:241:9:241:43 | ... && ... | ... == ... != 0 when ... && ... is true | +| test.cpp:241:9:241:43 | ... && ... | ... == ... == 1 when ... && ... is true | +| test.cpp:241:9:241:43 | ... && ... | f == 0+0 when ... && ... is true | +| test.cpp:241:9:241:43 | ... && ... | i == 0 when ... && ... is true | +| test.cpp:241:9:241:43 | ... && ... | i == 0+0 when ... && ... is true | +| test.cpp:241:22:241:30 | ... == ... | 0 != f+0 when ... == ... is false | +| test.cpp:241:22:241:30 | ... == ... | 0 == f+0 when ... == ... is true | +| test.cpp:241:22:241:30 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:241:22:241:30 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:241:22:241:30 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:241:22:241:30 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:241:22:241:30 | ... == ... | f != 0+0 when ... == ... is false | +| test.cpp:241:22:241:30 | ... == ... | f == 0+0 when ... == ... is true | +| test.cpp:241:35:241:43 | ... == ... | 0 != i+0 when ... == ... is false | +| test.cpp:241:35:241:43 | ... == ... | 0 == i+0 when ... == ... is true | +| test.cpp:241:35:241:43 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:241:35:241:43 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:241:35:241:43 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:241:35:241:43 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:241:35:241:43 | ... == ... | i != 0 when ... == ... is false | +| test.cpp:241:35:241:43 | ... == ... | i != 0+0 when ... == ... is false | +| test.cpp:241:35:241:43 | ... == ... | i == 0 when ... == ... is true | +| test.cpp:241:35:241:43 | ... == ... | i == 0+0 when ... == ... is true | +| test.cpp:247:6:247:18 | ... == ... | 0 != ... == ...+0 when ... == ... is false | +| test.cpp:247:6:247:18 | ... == ... | 0 == ... == ...+0 when ... == ... is true | +| test.cpp:247:6:247:18 | ... == ... | ... == ... != 0 when ... == ... is false | +| test.cpp:247:6:247:18 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:247:6:247:18 | ... == ... | ... == ... != 0+0 when ... == ... is false | +| test.cpp:247:6:247:18 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:247:6:247:18 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:247:6:247:18 | ... == ... | ... == ... == 0 when ... == ... is true | +| test.cpp:247:6:247:18 | ... == ... | ... == ... == 0+0 when ... == ... is true | +| test.cpp:247:6:247:18 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:247:6:247:18 | ... == ... | a != b+0 when ... == ... is true | +| test.cpp:247:6:247:18 | ... == ... | a == b+0 when ... == ... is false | +| test.cpp:247:6:247:18 | ... == ... | b != a+0 when ... == ... is true | +| test.cpp:247:6:247:18 | ... == ... | b == a+0 when ... == ... is false | +| test.cpp:253:6:253:18 | ... != ... | 0 != ... == ...+0 when ... != ... is true | +| test.cpp:253:6:253:18 | ... != ... | 0 == ... == ...+0 when ... != ... is false | +| test.cpp:253:6:253:18 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:253:6:253:18 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:253:6:253:18 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:253:6:253:18 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:253:6:253:18 | ... != ... | ... == ... != 0 when ... != ... is true | +| test.cpp:253:6:253:18 | ... != ... | ... == ... != 0+0 when ... != ... is true | +| test.cpp:253:6:253:18 | ... != ... | ... == ... == 0 when ... != ... is false | +| test.cpp:253:6:253:18 | ... != ... | ... == ... == 0+0 when ... != ... is false | +| test.cpp:253:6:253:18 | ... != ... | a != b+0 when ... != ... is false | +| test.cpp:253:6:253:18 | ... != ... | a == b+0 when ... != ... is true | +| test.cpp:253:6:253:18 | ... != ... | b != a+0 when ... != ... is false | +| test.cpp:253:6:253:18 | ... != ... | b == a+0 when ... != ... is true | +| test.cpp:260:6:260:18 | ... == ... | 0 != ... != ...+0 when ... == ... is false | +| test.cpp:260:6:260:18 | ... == ... | 0 == ... != ...+0 when ... == ... is true | +| test.cpp:260:6:260:18 | ... == ... | ... != ... != 0 when ... == ... is false | +| test.cpp:260:6:260:18 | ... == ... | ... != ... != 0+0 when ... == ... is false | +| test.cpp:260:6:260:18 | ... == ... | ... != ... == 0 when ... == ... is true | +| test.cpp:260:6:260:18 | ... == ... | ... != ... == 0+0 when ... == ... is true | +| test.cpp:260:6:260:18 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:260:6:260:18 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:260:6:260:18 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:260:6:260:18 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:260:6:260:18 | ... == ... | a != b+0 when ... == ... is false | +| test.cpp:260:6:260:18 | ... == ... | a == b+0 when ... == ... is true | +| test.cpp:260:6:260:18 | ... == ... | b != a+0 when ... == ... is false | +| test.cpp:260:6:260:18 | ... == ... | b == a+0 when ... == ... is true | +| test.cpp:266:6:266:18 | ... != ... | 0 != ... != ...+0 when ... != ... is true | +| test.cpp:266:6:266:18 | ... != ... | 0 == ... != ...+0 when ... != ... is false | +| test.cpp:266:6:266:18 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:266:6:266:18 | ... != ... | ... != ... != 0+0 when ... != ... is true | +| test.cpp:266:6:266:18 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:266:6:266:18 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:266:6:266:18 | ... != ... | ... != ... == 0+0 when ... != ... is false | +| test.cpp:266:6:266:18 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:266:6:266:18 | ... != ... | a != b+0 when ... != ... is true | +| test.cpp:266:6:266:18 | ... != ... | a == b+0 when ... != ... is false | +| test.cpp:266:6:266:18 | ... != ... | b != a+0 when ... != ... is true | +| test.cpp:266:6:266:18 | ... != ... | b == a+0 when ... != ... is false | +| test.cpp:273:6:273:17 | ... == ... | 0 != ... < ...+0 when ... == ... is false | +| test.cpp:273:6:273:17 | ... == ... | 0 == ... < ...+0 when ... == ... is true | +| test.cpp:273:6:273:17 | ... == ... | ... < ... != 0 when ... == ... is false | +| test.cpp:273:6:273:17 | ... == ... | ... < ... != 0+0 when ... == ... is false | +| test.cpp:273:6:273:17 | ... == ... | ... < ... == 0 when ... == ... is true | +| test.cpp:273:6:273:17 | ... == ... | ... < ... == 0+0 when ... == ... is true | +| test.cpp:273:6:273:17 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:273:6:273:17 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:273:6:273:17 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:273:6:273:17 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:273:6:273:17 | ... == ... | a < b+0 when ... == ... is false | +| test.cpp:273:6:273:17 | ... == ... | a >= b+0 when ... == ... is true | +| test.cpp:273:6:273:17 | ... == ... | b < a+1 when ... == ... is true | +| test.cpp:273:6:273:17 | ... == ... | b >= a+1 when ... == ... is false | +| test.cpp:279:6:279:17 | ... != ... | 0 != ... < ...+0 when ... != ... is true | +| test.cpp:279:6:279:17 | ... != ... | 0 == ... < ...+0 when ... != ... is false | +| test.cpp:279:6:279:17 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:279:6:279:17 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:279:6:279:17 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:279:6:279:17 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:279:6:279:17 | ... != ... | ... < ... != 0 when ... != ... is true | +| test.cpp:279:6:279:17 | ... != ... | ... < ... != 0+0 when ... != ... is true | +| test.cpp:279:6:279:17 | ... != ... | ... < ... == 0 when ... != ... is false | +| test.cpp:279:6:279:17 | ... != ... | ... < ... == 0+0 when ... != ... is false | +| test.cpp:279:6:279:17 | ... != ... | a < b+0 when ... != ... is true | +| test.cpp:279:6:279:17 | ... != ... | a >= b+0 when ... != ... is false | +| test.cpp:279:6:279:17 | ... != ... | b < a+1 when ... != ... is false | +| test.cpp:279:6:279:17 | ... != ... | b >= a+1 when ... != ... is true | +| test.cpp:287:6:287:19 | ... == ... | 0 != ... == ...+0 when ... == ... is false | +| test.cpp:287:6:287:19 | ... == ... | 0 == ... == ...+0 when ... == ... is true | +| test.cpp:287:6:287:19 | ... == ... | 42 != a+0 when ... == ... is true | +| test.cpp:287:6:287:19 | ... == ... | 42 == a+0 when ... == ... is false | +| test.cpp:287:6:287:19 | ... == ... | ... == ... != 0 when ... == ... is false | +| test.cpp:287:6:287:19 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:287:6:287:19 | ... == ... | ... == ... != 0+0 when ... == ... is false | +| test.cpp:287:6:287:19 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:287:6:287:19 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:287:6:287:19 | ... == ... | ... == ... == 0 when ... == ... is true | +| test.cpp:287:6:287:19 | ... == ... | ... == ... == 0+0 when ... == ... is true | +| test.cpp:287:6:287:19 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:287:6:287:19 | ... == ... | a != 42 when ... == ... is true | +| test.cpp:287:6:287:19 | ... == ... | a != 42+0 when ... == ... is true | +| test.cpp:287:6:287:19 | ... == ... | a == 42 when ... == ... is false | +| test.cpp:287:6:287:19 | ... == ... | a == 42+0 when ... == ... is false | +| test.cpp:293:6:293:19 | ... != ... | 0 != ... == ...+0 when ... != ... is true | +| test.cpp:293:6:293:19 | ... != ... | 0 == ... == ...+0 when ... != ... is false | +| test.cpp:293:6:293:19 | ... != ... | 42 != a+0 when ... != ... is false | +| test.cpp:293:6:293:19 | ... != ... | 42 == a+0 when ... != ... is true | +| test.cpp:293:6:293:19 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:293:6:293:19 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:293:6:293:19 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:293:6:293:19 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:293:6:293:19 | ... != ... | ... == ... != 0 when ... != ... is true | +| test.cpp:293:6:293:19 | ... != ... | ... == ... != 0+0 when ... != ... is true | +| test.cpp:293:6:293:19 | ... != ... | ... == ... == 0 when ... != ... is false | +| test.cpp:293:6:293:19 | ... != ... | ... == ... == 0+0 when ... != ... is false | +| test.cpp:293:6:293:19 | ... != ... | a != 42 when ... != ... is false | +| test.cpp:293:6:293:19 | ... != ... | a != 42+0 when ... != ... is false | +| test.cpp:293:6:293:19 | ... != ... | a == 42 when ... != ... is true | +| test.cpp:293:6:293:19 | ... != ... | a == 42+0 when ... != ... is true | +| test.cpp:300:6:300:19 | ... == ... | 0 != ... != ...+0 when ... == ... is false | +| test.cpp:300:6:300:19 | ... == ... | 0 == ... != ...+0 when ... == ... is true | +| test.cpp:300:6:300:19 | ... == ... | 42 != a+0 when ... == ... is false | +| test.cpp:300:6:300:19 | ... == ... | 42 == a+0 when ... == ... is true | +| test.cpp:300:6:300:19 | ... == ... | ... != ... != 0 when ... == ... is false | +| test.cpp:300:6:300:19 | ... == ... | ... != ... != 0+0 when ... == ... is false | +| test.cpp:300:6:300:19 | ... == ... | ... != ... == 0 when ... == ... is true | +| test.cpp:300:6:300:19 | ... == ... | ... != ... == 0+0 when ... == ... is true | +| test.cpp:300:6:300:19 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:300:6:300:19 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:300:6:300:19 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:300:6:300:19 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:300:6:300:19 | ... == ... | a != 42 when ... == ... is false | +| test.cpp:300:6:300:19 | ... == ... | a != 42+0 when ... == ... is false | +| test.cpp:300:6:300:19 | ... == ... | a == 42 when ... == ... is true | +| test.cpp:300:6:300:19 | ... == ... | a == 42+0 when ... == ... is true | +| test.cpp:306:6:306:19 | ... != ... | 0 != ... != ...+0 when ... != ... is true | +| test.cpp:306:6:306:19 | ... != ... | 0 == ... != ...+0 when ... != ... is false | +| test.cpp:306:6:306:19 | ... != ... | 42 != a+0 when ... != ... is true | +| test.cpp:306:6:306:19 | ... != ... | 42 == a+0 when ... != ... is false | +| test.cpp:306:6:306:19 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:306:6:306:19 | ... != ... | ... != ... != 0+0 when ... != ... is true | +| test.cpp:306:6:306:19 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:306:6:306:19 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:306:6:306:19 | ... != ... | ... != ... == 0+0 when ... != ... is false | +| test.cpp:306:6:306:19 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:306:6:306:19 | ... != ... | a != 42 when ... != ... is true | +| test.cpp:306:6:306:19 | ... != ... | a != 42+0 when ... != ... is true | +| test.cpp:306:6:306:19 | ... != ... | a == 42 when ... != ... is false | +| test.cpp:306:6:306:19 | ... != ... | a == 42+0 when ... != ... is false | +| test.cpp:312:6:312:18 | ... == ... | 0 != ... < ...+0 when ... == ... is false | +| test.cpp:312:6:312:18 | ... == ... | 0 == ... < ...+0 when ... == ... is true | +| test.cpp:312:6:312:18 | ... == ... | 42 < a+1 when ... == ... is true | +| test.cpp:312:6:312:18 | ... == ... | 42 >= a+1 when ... == ... is false | +| test.cpp:312:6:312:18 | ... == ... | ... < ... != 0 when ... == ... is false | +| test.cpp:312:6:312:18 | ... == ... | ... < ... != 0+0 when ... == ... is false | +| test.cpp:312:6:312:18 | ... == ... | ... < ... == 0 when ... == ... is true | +| test.cpp:312:6:312:18 | ... == ... | ... < ... == 0+0 when ... == ... is true | +| test.cpp:312:6:312:18 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:312:6:312:18 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:312:6:312:18 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:312:6:312:18 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:312:6:312:18 | ... == ... | a < 42 when ... == ... is false | +| test.cpp:312:6:312:18 | ... == ... | a < 42+0 when ... == ... is false | +| test.cpp:312:6:312:18 | ... == ... | a >= 42 when ... == ... is true | +| test.cpp:312:6:312:18 | ... == ... | a >= 42+0 when ... == ... is true | +| test.cpp:318:6:318:18 | ... != ... | 0 != ... < ...+0 when ... != ... is true | +| test.cpp:318:6:318:18 | ... != ... | 0 == ... < ...+0 when ... != ... is false | +| test.cpp:318:6:318:18 | ... != ... | 42 < a+1 when ... != ... is false | +| test.cpp:318:6:318:18 | ... != ... | 42 >= a+1 when ... != ... is true | +| test.cpp:318:6:318:18 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:318:6:318:18 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:318:6:318:18 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:318:6:318:18 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:318:6:318:18 | ... != ... | ... < ... != 0 when ... != ... is true | +| test.cpp:318:6:318:18 | ... != ... | ... < ... != 0+0 when ... != ... is true | +| test.cpp:318:6:318:18 | ... != ... | ... < ... == 0 when ... != ... is false | +| test.cpp:318:6:318:18 | ... != ... | ... < ... == 0+0 when ... != ... is false | +| test.cpp:318:6:318:18 | ... != ... | a < 42 when ... != ... is true | +| test.cpp:318:6:318:18 | ... != ... | a < 42+0 when ... != ... is true | +| test.cpp:318:6:318:18 | ... != ... | a >= 42 when ... != ... is false | +| test.cpp:318:6:318:18 | ... != ... | a >= 42+0 when ... != ... is false | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql index b05f5b95d001..59996548113a 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql @@ -38,4 +38,4 @@ where | msg = left + op + k + " when " + guard + " is " + value ) -select guard.getLocation().getStartLine(), msg +select guard, msg diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index a60784a0e10e..05afe345b8c4 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -1,165 +1,196 @@ -| test.c:7:9:7:13 | ... > ... | false | 10 | 11 | -| test.c:7:9:7:13 | ... > ... | true | 7 | 9 | -| test.c:17:8:17:12 | ... < ... | true | 17 | 17 | -| test.c:17:8:17:12 | ... < ... | true | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | true | 18 | 18 | -| test.c:17:17:17:21 | ... > ... | true | 18 | 18 | -| test.c:26:11:26:15 | ... > ... | false | 2 | 2 | -| test.c:26:11:26:15 | ... > ... | false | 31 | 34 | -| test.c:26:11:26:15 | ... > ... | false | 34 | 34 | -| test.c:26:11:26:15 | ... > ... | false | 39 | 42 | -| test.c:26:11:26:15 | ... > ... | false | 42 | 42 | -| test.c:26:11:26:15 | ... > ... | false | 42 | 44 | -| test.c:26:11:26:15 | ... > ... | false | 45 | 45 | -| test.c:26:11:26:15 | ... > ... | false | 45 | 47 | -| test.c:26:11:26:15 | ... > ... | false | 51 | 53 | -| test.c:26:11:26:15 | ... > ... | false | 56 | 58 | -| test.c:26:11:26:15 | ... > ... | false | 58 | 58 | -| test.c:26:11:26:15 | ... > ... | false | 58 | 66 | -| test.c:26:11:26:15 | ... > ... | false | 62 | 62 | -| test.c:26:11:26:15 | ... > ... | true | 26 | 28 | -| test.c:34:16:34:21 | ... < ... | false | 2 | 2 | -| test.c:34:16:34:21 | ... < ... | false | 39 | 42 | -| test.c:34:16:34:21 | ... < ... | false | 42 | 42 | -| test.c:34:16:34:21 | ... < ... | false | 42 | 44 | -| test.c:34:16:34:21 | ... < ... | false | 45 | 45 | -| test.c:34:16:34:21 | ... < ... | false | 45 | 47 | -| test.c:34:16:34:21 | ... < ... | false | 51 | 53 | -| test.c:34:16:34:21 | ... < ... | false | 56 | 58 | -| test.c:34:16:34:21 | ... < ... | false | 58 | 58 | -| test.c:34:16:34:21 | ... < ... | false | 58 | 66 | -| test.c:34:16:34:21 | ... < ... | false | 62 | 62 | -| test.c:34:16:34:21 | ... < ... | true | 34 | 34 | -| test.c:42:16:42:21 | ... < ... | true | 42 | 42 | -| test.c:42:16:42:21 | ... < ... | true | 42 | 44 | -| test.c:42:16:42:21 | ... < ... | true | 45 | 45 | -| test.c:42:16:42:21 | ... < ... | true | 45 | 47 | -| test.c:42:16:42:21 | ... < ... | true | 51 | 53 | -| test.c:44:12:44:16 | ... > ... | false | 42 | 42 | -| test.c:44:12:44:16 | ... > ... | false | 51 | 53 | -| test.c:44:12:44:16 | ... > ... | true | 45 | 45 | -| test.c:44:12:44:16 | ... > ... | true | 45 | 47 | -| test.c:45:16:45:20 | ... > ... | true | 45 | 47 | -| test.c:58:9:58:14 | ... == ... | false | 58 | 58 | -| test.c:58:9:58:14 | ... == ... | false | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | false | 62 | 62 | -| test.c:58:19:58:23 | ... < ... | false | 62 | 62 | -| test.c:75:9:75:14 | ... == ... | false | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | true | 75 | 77 | -| test.c:85:8:85:13 | ... == ... | true | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | true | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | true | 86 | 86 | -| test.c:85:18:85:23 | ... != ... | true | 86 | 86 | -| test.c:94:11:94:16 | ... != ... | false | 70 | 70 | -| test.c:94:11:94:16 | ... != ... | false | 99 | 102 | -| test.c:94:11:94:16 | ... != ... | false | 102 | 102 | -| test.c:94:11:94:16 | ... != ... | false | 107 | 109 | -| test.c:94:11:94:16 | ... != ... | false | 109 | 109 | -| test.c:94:11:94:16 | ... != ... | false | 109 | 117 | -| test.c:94:11:94:16 | ... != ... | false | 113 | 113 | -| test.c:94:11:94:16 | ... != ... | true | 94 | 96 | -| test.c:102:16:102:21 | ... < ... | false | 70 | 70 | -| test.c:102:16:102:21 | ... < ... | false | 107 | 109 | -| test.c:102:16:102:21 | ... < ... | false | 109 | 109 | -| test.c:102:16:102:21 | ... < ... | false | 109 | 117 | -| test.c:102:16:102:21 | ... < ... | false | 113 | 113 | -| test.c:102:16:102:21 | ... < ... | true | 102 | 102 | -| test.c:109:9:109:14 | ... == ... | false | 109 | 109 | -| test.c:109:9:109:14 | ... == ... | false | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | false | 113 | 113 | -| test.c:109:19:109:23 | ... < ... | false | 113 | 113 | -| test.c:126:7:126:7 | 1 | true | 126 | 126 | -| test.c:126:7:126:7 | 1 | true | 126 | 128 | -| test.c:126:7:126:7 | 1 | true | 131 | 131 | -| test.c:126:7:126:7 | 1 | true | 131 | 132 | -| test.c:126:7:126:7 | 1 | true | 134 | 123 | -| test.c:126:7:126:28 | ... && ... | true | 126 | 128 | -| test.c:126:12:126:26 | call to test3_condition | true | 126 | 128 | -| test.c:131:7:131:7 | b | true | 131 | 132 | -| test.c:137:7:137:7 | 0 | false | 142 | 136 | -| test.c:146:7:146:8 | ! ... | true | 146 | 147 | -| test.c:146:8:146:8 | x | false | 146 | 147 | -| test.c:152:8:152:8 | p | true | 152 | 154 | -| test.c:158:8:158:9 | ! ... | true | 158 | 160 | -| test.c:158:9:158:9 | p | false | 158 | 160 | -| test.c:164:8:164:8 | s | true | 164 | 166 | -| test.c:170:8:170:9 | ! ... | true | 170 | 172 | -| test.c:170:9:170:9 | s | false | 170 | 172 | -| test.c:176:8:176:15 | ! ... | true | 176 | 178 | -| test.c:176:10:176:14 | ... < ... | false | 176 | 178 | -| test.c:182:8:182:34 | ! ... | true | 182 | 184 | -| test.c:182:10:182:20 | ... >= ... | true | 181 | 182 | -| test.c:182:10:182:20 | ... >= ... | true | 182 | 182 | -| test.c:182:10:182:33 | ... && ... | false | 182 | 184 | -| test.c:182:10:182:33 | ... && ... | true | 181 | 182 | -| test.c:182:25:182:33 | ... < ... | true | 181 | 182 | -| test.c:190:7:190:8 | ! ... | true | 190 | 192 | -| test.c:190:8:190:8 | c | false | 190 | 192 | -| test.c:198:7:198:8 | ! ... | true | 198 | 200 | -| test.c:198:8:198:8 | b | false | 198 | 200 | -| test.c:206:7:206:8 | ! ... | true | 206 | 208 | -| test.c:206:8:206:8 | c | false | 206 | 208 | -| test.cpp:18:8:18:10 | call to get | true | 19 | 19 | -| test.cpp:31:7:31:13 | ... == ... | false | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 | -| test.cpp:31:7:31:13 | ... == ... | true | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | true | 31 | 32 | -| test.cpp:42:13:42:20 | call to getABool | true | 43 | 45 | -| test.cpp:61:10:61:10 | i | Case[0] | 62 | 64 | -| test.cpp:61:10:61:10 | i | Case[1] | 65 | 66 | -| test.cpp:74:10:74:10 | i | Case[0..10] | 75 | 77 | -| test.cpp:74:10:74:10 | i | Case[11..20] | 78 | 79 | -| test.cpp:93:6:93:6 | c | true | 93 | 94 | -| test.cpp:99:6:99:6 | f | true | 99 | 100 | -| test.cpp:105:6:105:14 | ... != ... | true | 105 | 106 | -| test.cpp:111:6:111:14 | ... != ... | true | 111 | 112 | -| test.cpp:122:9:122:9 | b | true | 123 | 125 | -| test.cpp:122:9:122:9 | b | true | 125 | 125 | -| test.cpp:125:13:125:20 | ! ... | true | 125 | 125 | -| test.cpp:125:14:125:17 | call to safe | false | 125 | 125 | -| test.cpp:131:6:131:21 | call to __builtin_expect | true | 131 | 132 | -| test.cpp:135:6:135:21 | call to __builtin_expect | true | 135 | 136 | -| test.cpp:141:6:141:21 | call to __builtin_expect | true | 141 | 142 | -| test.cpp:145:6:145:21 | call to __builtin_expect | true | 145 | 146 | -| test.cpp:152:7:152:8 | ! ... | true | 152 | 153 | -| test.cpp:152:8:152:8 | b | false | 152 | 153 | -| test.cpp:160:7:160:8 | ! ... | true | 160 | 162 | -| test.cpp:160:8:160:8 | c | false | 160 | 162 | -| test.cpp:168:7:168:8 | ! ... | true | 168 | 170 | -| test.cpp:168:8:168:8 | b | false | 168 | 170 | -| test.cpp:176:7:176:8 | ! ... | true | 176 | 178 | -| test.cpp:176:8:176:8 | c | false | 176 | 178 | -| test.cpp:182:6:182:16 | ! ... | false | 185 | 188 | -| test.cpp:182:6:182:16 | ! ... | true | 182 | 184 | -| test.cpp:182:8:182:9 | b1 | true | 181 | 182 | -| test.cpp:182:8:182:9 | b1 | true | 182 | 182 | -| test.cpp:182:8:182:15 | ... && ... | false | 182 | 184 | -| test.cpp:182:8:182:15 | ... && ... | true | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | true | 185 | 188 | -| test.cpp:182:14:182:15 | b2 | true | 181 | 182 | -| test.cpp:193:6:193:16 | ! ... | false | 197 | 199 | -| test.cpp:193:6:193:16 | ! ... | true | 193 | 196 | -| test.cpp:193:8:193:9 | b1 | false | 192 | 193 | -| test.cpp:193:8:193:9 | b1 | false | 193 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | false | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | false | 193 | 196 | -| test.cpp:193:8:193:15 | ... \|\| ... | true | 197 | 199 | -| test.cpp:193:14:193:15 | b2 | false | 192 | 193 | -| test.cpp:211:9:211:15 | ... == ... | true | 211 | 212 | -| test.cpp:214:9:214:17 | ... == ... | true | 214 | 215 | -| test.cpp:217:9:217:15 | ... == ... | true | 217 | 218 | -| test.cpp:220:9:220:14 | ... == ... | true | 220 | 221 | -| test.cpp:223:9:223:16 | ... == ... | true | 223 | 224 | -| test.cpp:226:9:226:14 | ... == ... | true | 226 | 227 | -| test.cpp:229:9:229:14 | ... == ... | true | 229 | 230 | -| test.cpp:232:9:232:18 | ... == ... | true | 232 | 233 | -| test.cpp:235:9:235:17 | ... == ... | true | 235 | 236 | -| test.cpp:238:9:238:17 | ... == ... | true | 238 | 239 | -| test.cpp:241:9:241:17 | ... == ... | true | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | true | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | true | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | true | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | true | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | true | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | true | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | true | 241 | 242 | +| test.c:7:9:7:13 | ... > ... | false | test.c:10:12:11:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | true | test.c:7:16:9:14 | { ... } | +| test.c:17:8:17:12 | ... < ... | true | test.c:17:17:17:21 | y | +| test.c:17:8:17:12 | ... < ... | true | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | true | test.c:18:9:18:14 | ExprStmt | +| test.c:17:17:17:21 | ... > ... | true | test.c:18:9:18:14 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | false | test.c:2:5:2:8 | test | +| test.c:26:11:26:15 | ... > ... | false | test.c:31:5:34:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | false | test.c:34:16:34:21 | j | +| test.c:26:11:26:15 | ... > ... | false | test.c:34:29:34:26 | { ... } | +| test.c:26:11:26:15 | ... > ... | false | test.c:39:5:42:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | false | test.c:42:5:42:26 | label ...: | +| test.c:26:11:26:15 | ... > ... | false | test.c:42:16:42:21 | j | +| test.c:26:11:26:15 | ... > ... | false | test.c:42:29:44:16 | { ... } | +| test.c:26:11:26:15 | ... > ... | false | test.c:45:13:45:20 | if (...) ... | +| test.c:26:11:26:15 | ... > ... | false | test.c:45:23:47:22 | { ... } | +| test.c:26:11:26:15 | ... > ... | false | test.c:51:14:53:21 | { ... } | +| test.c:26:11:26:15 | ... > ... | false | test.c:56:5:58:14 | label ...: | +| test.c:26:11:26:15 | ... > ... | false | test.c:58:19:58:23 | y | +| test.c:26:11:26:15 | ... > ... | false | test.c:58:26:66:12 | { ... } | +| test.c:26:11:26:15 | ... > ... | false | test.c:62:9:62:16 | return ... | +| test.c:26:11:26:15 | ... > ... | true | test.c:26:18:28:11 | { ... } | +| test.c:34:16:34:21 | ... < ... | false | test.c:2:5:2:8 | test | +| test.c:34:16:34:21 | ... < ... | false | test.c:39:5:42:13 | ExprStmt | +| test.c:34:16:34:21 | ... < ... | false | test.c:42:5:42:26 | label ...: | +| test.c:34:16:34:21 | ... < ... | false | test.c:42:16:42:21 | j | +| test.c:34:16:34:21 | ... < ... | false | test.c:42:29:44:16 | { ... } | +| test.c:34:16:34:21 | ... < ... | false | test.c:45:13:45:20 | if (...) ... | +| test.c:34:16:34:21 | ... < ... | false | test.c:45:23:47:22 | { ... } | +| test.c:34:16:34:21 | ... < ... | false | test.c:51:14:53:21 | { ... } | +| test.c:34:16:34:21 | ... < ... | false | test.c:56:5:58:14 | label ...: | +| test.c:34:16:34:21 | ... < ... | false | test.c:58:19:58:23 | y | +| test.c:34:16:34:21 | ... < ... | false | test.c:58:26:66:12 | { ... } | +| test.c:34:16:34:21 | ... < ... | false | test.c:62:9:62:16 | return ... | +| test.c:34:16:34:21 | ... < ... | true | test.c:34:29:34:26 | { ... } | +| test.c:42:16:42:21 | ... < ... | true | test.c:42:5:42:26 | label ...: | +| test.c:42:16:42:21 | ... < ... | true | test.c:42:29:44:16 | { ... } | +| test.c:42:16:42:21 | ... < ... | true | test.c:45:13:45:20 | if (...) ... | +| test.c:42:16:42:21 | ... < ... | true | test.c:45:23:47:22 | { ... } | +| test.c:42:16:42:21 | ... < ... | true | test.c:51:14:53:21 | { ... } | +| test.c:44:12:44:16 | ... > ... | false | test.c:42:5:42:26 | label ...: | +| test.c:44:12:44:16 | ... > ... | false | test.c:51:14:53:21 | { ... } | +| test.c:44:12:44:16 | ... > ... | true | test.c:45:13:45:20 | if (...) ... | +| test.c:44:12:44:16 | ... > ... | true | test.c:45:23:47:22 | { ... } | +| test.c:45:16:45:20 | ... > ... | true | test.c:45:23:47:22 | { ... } | +| test.c:58:9:58:14 | ... == ... | false | test.c:58:19:58:23 | y | +| test.c:58:9:58:14 | ... == ... | false | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | false | test.c:62:9:62:16 | return ... | +| test.c:58:19:58:23 | ... < ... | false | test.c:62:9:62:16 | return ... | +| test.c:75:9:75:14 | ... == ... | false | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | true | test.c:75:17:77:14 | { ... } | +| test.c:85:8:85:13 | ... == ... | true | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | true | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | true | test.c:86:9:86:14 | ExprStmt | +| test.c:85:18:85:23 | ... != ... | true | test.c:86:9:86:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | false | test.c:70:5:70:9 | test2 | +| test.c:94:11:94:16 | ... != ... | false | test.c:99:5:102:13 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | false | test.c:102:16:102:21 | j | +| test.c:94:11:94:16 | ... != ... | false | test.c:102:29:102:26 | { ... } | +| test.c:94:11:94:16 | ... != ... | false | test.c:107:5:109:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | false | test.c:109:19:109:23 | y | +| test.c:94:11:94:16 | ... != ... | false | test.c:109:26:117:12 | { ... } | +| test.c:94:11:94:16 | ... != ... | false | test.c:113:9:113:16 | return ... | +| test.c:94:11:94:16 | ... != ... | true | test.c:94:19:96:11 | { ... } | +| test.c:102:16:102:21 | ... < ... | false | test.c:70:5:70:9 | test2 | +| test.c:102:16:102:21 | ... < ... | false | test.c:107:5:109:14 | ExprStmt | +| test.c:102:16:102:21 | ... < ... | false | test.c:109:19:109:23 | y | +| test.c:102:16:102:21 | ... < ... | false | test.c:109:26:117:12 | { ... } | +| test.c:102:16:102:21 | ... < ... | false | test.c:113:9:113:16 | return ... | +| test.c:102:16:102:21 | ... < ... | true | test.c:102:29:102:26 | { ... } | +| test.c:109:9:109:14 | ... == ... | false | test.c:109:19:109:23 | y | +| test.c:109:9:109:14 | ... == ... | false | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | false | test.c:113:9:113:16 | return ... | +| test.c:109:19:109:23 | ... < ... | false | test.c:113:9:113:16 | return ... | +| test.c:126:7:126:7 | 1 | true | test.c:126:12:126:26 | call to test3_condition | +| test.c:126:7:126:7 | 1 | true | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:7 | 1 | true | test.c:131:3:131:7 | if (...) ... | +| test.c:126:7:126:7 | 1 | true | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:7 | 1 | true | test.c:134:1:123:10 | return ... | +| test.c:126:7:126:28 | ... && ... | true | test.c:126:31:128:16 | { ... } | +| test.c:126:12:126:26 | call to test3_condition | true | test.c:126:31:128:16 | { ... } | +| test.c:131:7:131:7 | b | true | test.c:131:10:132:16 | { ... } | +| test.c:137:7:137:7 | 0 | false | test.c:142:3:136:10 | return ... | +| test.c:146:7:146:8 | ! ... | true | test.c:146:11:147:9 | { ... } | +| test.c:146:8:146:8 | x | false | test.c:146:11:147:9 | { ... } | +| test.c:152:8:152:8 | p | true | test.c:152:11:154:5 | { ... } | +| test.c:158:8:158:9 | ! ... | true | test.c:158:12:160:5 | { ... } | +| test.c:158:9:158:9 | p | false | test.c:158:12:160:5 | { ... } | +| test.c:164:8:164:8 | s | true | test.c:164:11:166:5 | { ... } | +| test.c:170:8:170:9 | ! ... | true | test.c:170:12:172:5 | { ... } | +| test.c:170:9:170:9 | s | false | test.c:170:12:172:5 | { ... } | +| test.c:176:8:176:15 | ! ... | true | test.c:176:18:178:5 | { ... } | +| test.c:176:10:176:14 | ... < ... | false | test.c:176:18:178:5 | { ... } | +| test.c:182:8:182:34 | ! ... | true | test.c:182:37:184:5 | { ... } | +| test.c:182:10:182:20 | ... >= ... | true | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:20 | ... >= ... | true | test.c:182:25:182:33 | foo | +| test.c:182:10:182:33 | ... && ... | false | test.c:182:37:184:5 | { ... } | +| test.c:182:10:182:33 | ... && ... | true | test.c:181:25:182:20 | { ... } | +| test.c:182:25:182:33 | ... < ... | true | test.c:181:25:182:20 | { ... } | +| test.c:190:7:190:8 | ! ... | true | test.c:190:11:192:3 | { ... } | +| test.c:190:8:190:8 | c | false | test.c:190:11:192:3 | { ... } | +| test.c:198:7:198:8 | ! ... | true | test.c:198:11:200:3 | { ... } | +| test.c:198:8:198:8 | b | false | test.c:198:11:200:3 | { ... } | +| test.c:206:7:206:8 | ! ... | true | test.c:206:11:208:3 | { ... } | +| test.c:206:8:206:8 | c | false | test.c:206:11:208:3 | { ... } | +| test.c:215:6:215:18 | call to __builtin_expect | true | test.c:215:21:217:5 | { ... } | +| test.c:219:9:219:22 | call to __builtin_expect | true | test.c:219:25:221:5 | { ... } | +| test.cpp:18:8:18:10 | call to get | true | test.cpp:19:5:19:14 | ExprStmt | +| test.cpp:31:7:31:13 | ... == ... | false | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | false | test.cpp:34:1:34:1 | return ... | +| test.cpp:31:7:31:13 | ... == ... | true | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | true | test.cpp:31:16:32:21 | { ... } | +| test.cpp:42:13:42:20 | call to getABool | true | test.cpp:43:9:45:23 | { ... } | +| test.cpp:61:10:61:10 | i | Case[0] | test.cpp:62:5:64:12 | case ...: | +| test.cpp:61:10:61:10 | i | Case[1] | test.cpp:65:5:66:10 | case ...: | +| test.cpp:74:10:74:10 | i | Case[0..10] | test.cpp:75:5:77:12 | case ...: | +| test.cpp:74:10:74:10 | i | Case[11..20] | test.cpp:78:5:79:10 | case ...: | +| test.cpp:93:6:93:6 | c | true | test.cpp:93:9:94:7 | { ... } | +| test.cpp:99:6:99:6 | f | true | test.cpp:99:9:100:7 | { ... } | +| test.cpp:105:6:105:14 | ... != ... | true | test.cpp:105:17:106:7 | { ... } | +| test.cpp:111:6:111:14 | ... != ... | true | test.cpp:111:17:112:7 | { ... } | +| test.cpp:122:9:122:9 | b | true | test.cpp:123:5:125:20 | { ... } | +| test.cpp:122:9:122:9 | b | true | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:13:125:20 | ! ... | true | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:14:125:17 | call to safe | false | test.cpp:125:23:125:29 | return ... | +| test.cpp:131:6:131:21 | call to __builtin_expect | true | test.cpp:131:40:132:9 | { ... } | +| test.cpp:135:6:135:21 | call to __builtin_expect | true | test.cpp:135:40:136:9 | { ... } | +| test.cpp:141:6:141:21 | call to __builtin_expect | true | test.cpp:141:36:142:9 | { ... } | +| test.cpp:145:6:145:21 | call to __builtin_expect | true | test.cpp:145:36:146:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | true | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | false | test.cpp:152:11:153:9 | { ... } | +| test.cpp:160:7:160:8 | ! ... | true | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | false | test.cpp:160:11:162:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | true | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | false | test.cpp:168:11:170:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | true | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | false | test.cpp:176:11:178:3 | { ... } | +| test.cpp:182:6:182:16 | ! ... | false | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | true | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:8:182:9 | b1 | true | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:9 | b1 | true | test.cpp:182:14:182:15 | b2 | +| test.cpp:182:8:182:15 | ... && ... | false | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | true | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | true | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:14:182:15 | b2 | true | test.cpp:181:41:182:9 | { ... } | +| test.cpp:193:6:193:16 | ! ... | false | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | true | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:9 | b1 | false | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:9 | b1 | false | test.cpp:193:14:193:15 | b2 | +| test.cpp:193:8:193:15 | ... \|\| ... | false | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | false | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | true | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:14:193:15 | b2 | false | test.cpp:192:40:193:9 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | true | test.cpp:211:18:212:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | true | test.cpp:214:20:215:13 | { ... } | +| test.cpp:217:9:217:15 | ... == ... | true | test.cpp:217:18:218:13 | { ... } | +| test.cpp:220:9:220:14 | ... == ... | true | test.cpp:220:17:221:13 | { ... } | +| test.cpp:223:9:223:16 | ... == ... | true | test.cpp:223:19:224:13 | { ... } | +| test.cpp:226:9:226:14 | ... == ... | true | test.cpp:226:17:227:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | true | test.cpp:229:17:230:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | true | test.cpp:232:21:233:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | true | test.cpp:235:20:236:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | true | test.cpp:238:20:239:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | true | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | true | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | true | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | true | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | true | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | true | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | true | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | true | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | true | test.cpp:241:46:242:13 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | false | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | true | test.cpp:247:21:249:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | false | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | true | test.cpp:253:21:255:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | false | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | true | test.cpp:260:21:262:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | false | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | true | test.cpp:266:21:268:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | false | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | true | test.cpp:273:20:275:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | false | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | true | test.cpp:279:20:281:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | false | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | true | test.cpp:287:22:289:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | false | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | true | test.cpp:293:22:295:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | false | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | true | test.cpp:300:22:302:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | false | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | true | test.cpp:306:22:308:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | false | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | true | test.cpp:312:21:314:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | false | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | true | test.cpp:318:21:320:3 | { ... } | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql index 93ce054cd820..698b80a06a02 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql @@ -7,10 +7,6 @@ import cpp import semmle.code.cpp.controlflow.Guards -from GuardCondition guard, AbstractValue value, int start, int end -where - exists(BasicBlock block | - guard.valueControls(block, value) and - block.hasLocationInfo(_, start, _, end, _) - ) -select guard, value, start, end +from GuardCondition guard, AbstractValue value, BasicBlock block +where guard.valueControls(block, value) +select guard, value, block diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index 67dd6f68ed41..c9f52e5f190c 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -1,922 +1,1226 @@ binary -| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | test.c:7:13:7:13 | 0 | 1 | 10 | 11 | -| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | test.c:7:13:7:13 | 0 | 1 | 7 | 9 | -| test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | < | test.c:7:9:7:9 | x | 0 | 7 | 9 | -| test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | >= | test.c:7:9:7:9 | x | 0 | 10 | 11 | -| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | 17 | 17 | -| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | 18 | 18 | -| test.c:17:8:17:12 | ... < ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | 17 | 17 | -| test.c:17:8:17:12 | ... < ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:17 | y | >= | test.c:17:21:17:21 | 1 | 1 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:21:17:21 | 1 | < | test.c:17:17:17:17 | y | 0 | 18 | 18 | -| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:17 | y | >= | test.c:17:21:17:21 | 1 | 1 | 18 | 18 | -| test.c:17:17:17:21 | ... > ... | test.c:17:21:17:21 | 1 | < | test.c:17:17:17:17 | y | 0 | 18 | 18 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 2 | 2 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 31 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 34 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 39 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 42 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 42 | 44 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 45 | 45 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 45 | 47 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 51 | 53 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 56 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 58 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 58 | 66 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 62 | 62 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | >= | test.c:26:15:26:15 | 0 | 1 | 26 | 28 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | < | test.c:26:11:26:11 | x | 0 | 26 | 28 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 2 | 2 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 31 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 34 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 39 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 42 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 42 | 44 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 45 | 45 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 45 | 47 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 51 | 53 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 56 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 58 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 58 | 66 | -| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 62 | 62 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | < | test.c:34:20:34:21 | 10 | 0 | 34 | 34 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 2 | 2 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 39 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 42 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 42 | 44 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 45 | 45 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 45 | 47 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 51 | 53 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 56 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 58 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 58 | 66 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 62 | 62 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 2 | 2 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 39 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 42 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 42 | 44 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 45 | 45 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 45 | 47 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 51 | 53 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 56 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 58 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 58 | 66 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 62 | 62 | -| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | >= | test.c:34:16:34:16 | j | 1 | 34 | 34 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 42 | 42 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 42 | 44 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 45 | 45 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 45 | 47 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 51 | 53 | -| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 42 | 42 | -| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 42 | 44 | -| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 45 | 45 | -| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 45 | 47 | -| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 51 | 53 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | test.c:44:16:44:16 | 0 | 1 | 42 | 42 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | test.c:44:16:44:16 | 0 | 1 | 51 | 53 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | test.c:44:16:44:16 | 0 | 1 | 45 | 45 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | test.c:44:16:44:16 | 0 | 1 | 45 | 47 | -| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | < | test.c:44:12:44:12 | z | 0 | 45 | 45 | -| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | < | test.c:44:12:44:12 | z | 0 | 45 | 47 | -| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | >= | test.c:44:12:44:12 | z | 0 | 42 | 42 | -| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | >= | test.c:44:12:44:12 | z | 0 | 51 | 53 | -| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | >= | test.c:45:20:45:20 | 0 | 1 | 45 | 47 | -| test.c:45:16:45:20 | ... > ... | test.c:45:20:45:20 | 0 | < | test.c:45:16:45:16 | y | 0 | 45 | 47 | -| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | 58 | 58 | -| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | 62 | 62 | -| test.c:58:9:58:14 | ... == ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | 58 | 58 | -| test.c:58:9:58:14 | ... == ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:19 | y | >= | test.c:58:23:58:23 | 0 | 0 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:23:58:23 | 0 | < | test.c:58:19:58:19 | y | 1 | 62 | 62 | -| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:19 | y | >= | test.c:58:23:58:23 | 0 | 0 | 62 | 62 | -| test.c:58:19:58:23 | ... < ... | test.c:58:23:58:23 | 0 | < | test.c:58:19:58:19 | y | 1 | 62 | 62 | -| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | != | test.c:75:14:75:14 | 0 | 0 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | 75 | 77 | -| test.c:75:9:75:14 | ... == ... | test.c:75:14:75:14 | 0 | != | test.c:75:9:75:9 | x | 0 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | 75 | 77 | -| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:8 | x | != | test.c:85:13:85:13 | 0 | 0 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | 75 | 77 | -| test.c:75:9:75:14 | ... == ... | test.c:85:13:85:13 | 0 | != | test.c:85:8:85:8 | x | 0 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | 75 | 77 | -| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | 86 | 86 | -| test.c:85:8:85:13 | ... == ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | 86 | 86 | -| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | 86 | 86 | -| test.c:85:8:85:13 | ... == ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:18 | y | != | test.c:85:23:85:23 | 0 | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:23:85:23 | 0 | != | test.c:85:18:85:18 | y | 0 | 86 | 86 | -| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:18 | y | != | test.c:85:23:85:23 | 0 | 0 | 86 | 86 | -| test.c:85:18:85:23 | ... != ... | test.c:85:23:85:23 | 0 | != | test.c:85:18:85:18 | y | 0 | 86 | 86 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | != | test.c:94:16:94:16 | 0 | 0 | 94 | 96 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 70 | 70 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 99 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 102 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 107 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 109 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 109 | 117 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 113 | 113 | -| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | != | test.c:94:11:94:11 | x | 0 | 94 | 96 | -| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 70 | 70 | -| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 99 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 102 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 107 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 109 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 109 | 117 | -| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 113 | 113 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | < | test.c:102:20:102:21 | 10 | 0 | 102 | 102 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 70 | 70 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 107 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 109 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 109 | 117 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 113 | 113 | -| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 70 | 70 | -| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 107 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 109 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 109 | 117 | -| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 113 | 113 | -| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | >= | test.c:102:16:102:16 | j | 1 | 102 | 102 | -| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | 109 | 109 | -| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | 113 | 113 | -| test.c:109:9:109:14 | ... == ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | 109 | 109 | -| test.c:109:9:109:14 | ... == ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | test.c:109:23:109:23 | 0 | 0 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:23:109:23 | 0 | < | test.c:109:19:109:19 | y | 1 | 113 | 113 | -| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | test.c:109:23:109:23 | 0 | 0 | 113 | 113 | -| test.c:109:19:109:23 | ... < ... | test.c:109:23:109:23 | 0 | < | test.c:109:19:109:19 | y | 1 | 113 | 113 | -| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | 181 | 182 | -| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | 182 | 182 | -| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | 181 | 182 | -| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | 182 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:25:182:27 | foo | < | test.c:182:31:182:33 | 1.0 | 0 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:31:182:33 | 1.0 | >= | test.c:182:25:182:27 | foo | 1 | 181 | 182 | -| test.c:182:25:182:33 | ... < ... | test.c:182:25:182:27 | foo | < | test.c:182:31:182:33 | 1.0 | 0 | 181 | 182 | -| test.c:182:25:182:33 | ... < ... | test.c:182:31:182:33 | 1.0 | >= | test.c:182:25:182:27 | foo | 1 | 181 | 182 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 34 | 34 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 31 | 32 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 34 | 34 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 31 | 32 | -| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:6 | f | != | test.cpp:105:11:105:14 | 0.0 | 0 | 105 | 106 | -| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:11:105:14 | 0.0 | != | test.cpp:105:6:105:6 | f | 0 | 105 | 106 | -| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:6 | i | != | test.cpp:111:11:111:14 | 0.0 | 0 | 111 | 112 | -| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:11:111:14 | 0.0 | != | test.cpp:111:6:111:6 | i | 0 | 111 | 112 | -| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:23:131:23 | a | == | test.cpp:131:28:131:28 | b | 42 | 131 | 132 | -| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:23:131:23 | a | == | test.cpp:131:28:131:33 | ... + ... | 0 | 131 | 132 | -| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:28:131:28 | b | == | test.cpp:131:23:131:23 | a | -42 | 131 | 132 | -| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:28:131:33 | ... + ... | == | test.cpp:131:23:131:23 | a | 0 | 131 | 132 | -| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:23:135:23 | a | != | test.cpp:135:28:135:28 | b | 42 | 135 | 136 | -| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:23:135:23 | a | != | test.cpp:135:28:135:33 | ... + ... | 0 | 135 | 136 | -| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:28:135:28 | b | != | test.cpp:135:23:135:23 | a | -42 | 135 | 136 | -| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:28:135:33 | ... + ... | != | test.cpp:135:23:135:23 | a | 0 | 135 | 136 | -| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:23 | a | == | test.cpp:141:28:141:29 | 42 | 0 | 141 | 142 | -| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:28:141:29 | 42 | == | test.cpp:141:23:141:23 | a | 0 | 141 | 142 | -| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | test.cpp:145:28:145:29 | 42 | 0 | 145 | 146 | -| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:28:145:29 | 42 | != | test.cpp:145:23:145:23 | a | 0 | 145 | 146 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:8 | a | >= | test.cpp:151:12:151:13 | 10 | 0 | 152 | 153 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:151:12:151:13 | 10 | < | test.cpp:151:8:151:8 | a | 1 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:151:8:151:8 | a | >= | test.cpp:151:12:151:13 | 10 | 0 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:151:12:151:13 | 10 | < | test.cpp:151:8:151:8 | a | 1 | 152 | 153 | -| test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:12 | a | == | test.cpp:158:17:158:17 | b | 0 | 160 | 162 | -| test.cpp:160:7:160:8 | ! ... | test.cpp:158:17:158:17 | b | == | test.cpp:158:12:158:12 | a | 0 | 160 | 162 | -| test.cpp:160:8:160:8 | c | test.cpp:158:12:158:12 | a | == | test.cpp:158:17:158:17 | b | 0 | 160 | 162 | -| test.cpp:160:8:160:8 | c | test.cpp:158:17:158:17 | b | == | test.cpp:158:12:158:12 | a | 0 | 160 | 162 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:12 | a | < | test.cpp:166:16:166:17 | 10 | 1 | 168 | 170 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:166:16:166:17 | 10 | >= | test.cpp:166:12:166:12 | a | 0 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:166:12:166:12 | a | < | test.cpp:166:16:166:17 | 10 | 1 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:166:16:166:17 | 10 | >= | test.cpp:166:12:166:12 | a | 0 | 168 | 170 | -| test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:12 | a | < | test.cpp:174:16:174:16 | b | 1 | 176 | 178 | -| test.cpp:176:7:176:8 | ! ... | test.cpp:174:16:174:16 | b | >= | test.cpp:174:12:174:12 | a | 0 | 176 | 178 | -| test.cpp:176:8:176:8 | c | test.cpp:174:12:174:12 | a | < | test.cpp:174:16:174:16 | b | 1 | 176 | 178 | -| test.cpp:176:8:176:8 | c | test.cpp:174:16:174:16 | b | >= | test.cpp:174:12:174:12 | a | 0 | 176 | 178 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:10 | sc | == | test.cpp:211:15:211:15 | 0 | 0 | 211 | 212 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:15:211:15 | 0 | == | test.cpp:211:9:211:10 | sc | 0 | 211 | 212 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:10 | sc | == | test.cpp:214:15:214:17 | 0 | 0 | 211 | 212 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:15:214:17 | 0 | == | test.cpp:214:9:214:10 | sc | 0 | 211 | 212 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:10 | sc | == | test.cpp:211:15:211:15 | 0 | 0 | 214 | 215 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:15:211:15 | 0 | == | test.cpp:211:9:211:10 | sc | 0 | 214 | 215 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:10 | sc | == | test.cpp:214:15:214:17 | 0 | 0 | 214 | 215 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:15:214:17 | 0 | == | test.cpp:214:9:214:10 | sc | 0 | 214 | 215 | -| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:10 | ul | == | test.cpp:217:15:217:15 | 0 | 0 | 217 | 218 | -| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:15:217:15 | 0 | == | test.cpp:217:9:217:10 | ul | 0 | 217 | 218 | -| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:9 | f | == | test.cpp:220:14:220:14 | 0 | 0 | 220 | 221 | -| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:14:220:14 | 0 | == | test.cpp:220:9:220:9 | f | 0 | 220 | 221 | -| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:9 | f | == | test.cpp:223:14:223:16 | 0.0 | 0 | 223 | 224 | -| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:14:223:16 | 0.0 | == | test.cpp:223:9:223:9 | f | 0 | 223 | 224 | -| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:9 | d | == | test.cpp:226:14:226:14 | 0 | 0 | 226 | 227 | -| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:14:226:14 | 0 | == | test.cpp:226:9:226:9 | d | 0 | 226 | 227 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:9 | b | == | test.cpp:229:14:229:14 | 0 | 0 | 229 | 230 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:14:229:14 | 0 | == | test.cpp:229:9:229:9 | b | 0 | 229 | 230 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:9 | b | == | test.cpp:232:14:232:18 | 0 | 0 | 229 | 230 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:14:232:18 | 0 | == | test.cpp:232:9:232:9 | b | 0 | 229 | 230 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:9 | b | == | test.cpp:229:14:229:14 | 0 | 0 | 232 | 233 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:14:229:14 | 0 | == | test.cpp:229:9:229:9 | b | 0 | 232 | 233 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:9 | b | == | test.cpp:232:14:232:18 | 0 | 0 | 232 | 233 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:14:232:18 | 0 | == | test.cpp:232:9:232:9 | b | 0 | 232 | 233 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 235 | 236 | -| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 238 | 239 | -| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 238 | 239 | -| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 238 | 239 | -| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 238 | 239 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | 241 | 242 | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | test.c:7:13:7:13 | 0 | 1 | test.c:10:12:11:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | test.c:7:13:7:13 | 0 | 1 | test.c:7:16:9:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | < | test.c:7:9:7:9 | x | 0 | test.c:7:16:9:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | >= | test.c:7:9:7:9 | x | 0 | test.c:10:12:11:14 | { ... } | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | test.c:17:17:17:21 | y | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:12 | ... < ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | test.c:17:17:17:21 | y | +| test.c:17:8:17:12 | ... < ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:17 | y | >= | test.c:17:21:17:21 | 1 | 1 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:21:17:21 | 1 | < | test.c:17:17:17:17 | y | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:17 | y | >= | test.c:17:21:17:21 | 1 | 1 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:17:17:21 | ... > ... | test.c:17:21:17:21 | 1 | < | test.c:17:17:17:17 | y | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:2:5:2:8 | test | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:31:5:34:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:34:16:34:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:34:29:34:26 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:39:5:42:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:42:5:42:26 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:42:16:42:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:42:29:44:16 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:45:23:47:22 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:51:14:53:21 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:56:5:58:14 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:58:19:58:23 | y | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:58:26:66:12 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | test.c:62:9:62:16 | return ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | >= | test.c:26:15:26:15 | 0 | 1 | test.c:26:18:28:11 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | < | test.c:26:11:26:11 | x | 0 | test.c:26:18:28:11 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:2:5:2:8 | test | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:31:5:34:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:34:16:34:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:34:29:34:26 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:39:5:42:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:42:5:42:26 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:42:16:42:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:42:29:44:16 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:45:13:45:20 | if (...) ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:45:23:47:22 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:51:14:53:21 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:56:5:58:14 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:58:19:58:23 | y | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:58:26:66:12 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | test.c:62:9:62:16 | return ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | < | test.c:34:20:34:21 | 10 | 0 | test.c:34:29:34:26 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:2:5:2:8 | test | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:39:5:42:13 | ExprStmt | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:42:5:42:26 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:42:16:42:21 | j | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:42:29:44:16 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:45:13:45:20 | if (...) ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:45:23:47:22 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:51:14:53:21 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:56:5:58:14 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:58:19:58:23 | y | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:58:26:66:12 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | test.c:62:9:62:16 | return ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:2:5:2:8 | test | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:39:5:42:13 | ExprStmt | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:42:5:42:26 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:42:16:42:21 | j | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:42:29:44:16 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:45:23:47:22 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:51:14:53:21 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:56:5:58:14 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:58:19:58:23 | y | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:58:26:66:12 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | test.c:62:9:62:16 | return ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | >= | test.c:34:16:34:16 | j | 1 | test.c:34:29:34:26 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | test.c:42:5:42:26 | label ...: | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | test.c:42:29:44:16 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | test.c:45:13:45:20 | if (...) ... | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | test.c:45:23:47:22 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | test.c:51:14:53:21 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | test.c:42:5:42:26 | label ...: | +| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | test.c:42:29:44:16 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | test.c:45:23:47:22 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | test.c:51:14:53:21 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | test.c:44:16:44:16 | 0 | 1 | test.c:42:5:42:26 | label ...: | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | test.c:44:16:44:16 | 0 | 1 | test.c:51:14:53:21 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | test.c:44:16:44:16 | 0 | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | test.c:44:16:44:16 | 0 | 1 | test.c:45:23:47:22 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | < | test.c:44:12:44:12 | z | 0 | test.c:45:13:45:20 | if (...) ... | +| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | < | test.c:44:12:44:12 | z | 0 | test.c:45:23:47:22 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | >= | test.c:44:12:44:12 | z | 0 | test.c:42:5:42:26 | label ...: | +| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | >= | test.c:44:12:44:12 | z | 0 | test.c:51:14:53:21 | { ... } | +| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | >= | test.c:45:20:45:20 | 0 | 1 | test.c:45:23:47:22 | { ... } | +| test.c:45:16:45:20 | ... > ... | test.c:45:20:45:20 | 0 | < | test.c:45:16:45:16 | y | 0 | test.c:45:23:47:22 | { ... } | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | test.c:58:19:58:23 | y | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:14 | ... == ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | test.c:58:19:58:23 | y | +| test.c:58:9:58:14 | ... == ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:19 | y | >= | test.c:58:23:58:23 | 0 | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:23:58:23 | 0 | < | test.c:58:19:58:19 | y | 1 | test.c:62:9:62:16 | return ... | +| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:19 | y | >= | test.c:58:23:58:23 | 0 | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:19:58:23 | ... < ... | test.c:58:23:58:23 | 0 | < | test.c:58:19:58:19 | y | 1 | test.c:62:9:62:16 | return ... | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | != | test.c:75:14:75:14 | 0 | 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:75:14:75:14 | 0 | != | test.c:75:9:75:9 | x | 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:8 | x | != | test.c:85:13:85:13 | 0 | 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:13:85:13 | 0 | != | test.c:85:8:85:8 | x | 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | test.c:75:17:77:14 | { ... } | +| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:13 | ... == ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:13 | ... == ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:18 | y | != | test.c:85:23:85:23 | 0 | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:23:85:23 | 0 | != | test.c:85:18:85:18 | y | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:18 | y | != | test.c:85:23:85:23 | 0 | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:18:85:23 | ... != ... | test.c:85:23:85:23 | 0 | != | test.c:85:18:85:18 | y | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | != | test.c:94:16:94:16 | 0 | 0 | test.c:94:19:96:11 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | test.c:70:5:70:9 | test2 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | test.c:99:5:102:13 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | test.c:102:16:102:21 | j | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | test.c:102:29:102:26 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | test.c:107:5:109:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | test.c:109:19:109:23 | y | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | test.c:109:26:117:12 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | test.c:113:9:113:16 | return ... | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | != | test.c:94:11:94:11 | x | 0 | test.c:94:19:96:11 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | test.c:70:5:70:9 | test2 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | test.c:99:5:102:13 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | test.c:102:16:102:21 | j | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | test.c:102:29:102:26 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | test.c:107:5:109:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | test.c:109:19:109:23 | y | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | test.c:109:26:117:12 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | test.c:113:9:113:16 | return ... | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | < | test.c:102:20:102:21 | 10 | 0 | test.c:102:29:102:26 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | test.c:70:5:70:9 | test2 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | test.c:107:5:109:14 | ExprStmt | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | test.c:109:19:109:23 | y | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | test.c:109:26:117:12 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | test.c:113:9:113:16 | return ... | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | test.c:70:5:70:9 | test2 | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | test.c:107:5:109:14 | ExprStmt | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | test.c:109:19:109:23 | y | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | test.c:109:26:117:12 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | test.c:113:9:113:16 | return ... | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | >= | test.c:102:16:102:16 | j | 1 | test.c:102:29:102:26 | { ... } | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | test.c:109:19:109:23 | y | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:14 | ... == ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | test.c:109:19:109:23 | y | +| test.c:109:9:109:14 | ... == ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | test.c:109:23:109:23 | 0 | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:23:109:23 | 0 | < | test.c:109:19:109:19 | y | 1 | test.c:113:9:113:16 | return ... | +| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | test.c:109:23:109:23 | 0 | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:19:109:23 | ... < ... | test.c:109:23:109:23 | 0 | < | test.c:109:19:109:19 | y | 1 | test.c:113:9:113:16 | return ... | +| test.c:176:8:176:15 | ! ... | test.c:176:10:176:10 | a | >= | test.c:176:14:176:14 | b | 0 | test.c:176:18:178:5 | { ... } | +| test.c:176:8:176:15 | ! ... | test.c:176:14:176:14 | b | < | test.c:176:10:176:10 | a | 1 | test.c:176:18:178:5 | { ... } | +| test.c:176:10:176:14 | ... < ... | test.c:176:10:176:10 | a | >= | test.c:176:14:176:14 | b | 0 | test.c:176:18:178:5 | { ... } | +| test.c:176:10:176:14 | ... < ... | test.c:176:14:176:14 | b | < | test.c:176:10:176:10 | a | 1 | test.c:176:18:178:5 | { ... } | +| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:182:25:182:33 | foo | +| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:182:25:182:33 | foo | +| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:25:182:27 | foo | < | test.c:182:31:182:33 | 1.0 | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:31:182:33 | 1.0 | >= | test.c:182:25:182:27 | foo | 1 | test.c:181:25:182:20 | { ... } | +| test.c:182:25:182:33 | ... < ... | test.c:182:25:182:27 | foo | < | test.c:182:31:182:33 | 1.0 | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:25:182:33 | ... < ... | test.c:182:31:182:33 | 1.0 | >= | test.c:182:25:182:27 | foo | 1 | test.c:181:25:182:20 | { ... } | +| test.c:190:7:190:8 | ! ... | test.c:188:11:188:11 | a | == | test.c:188:16:188:16 | b | 0 | test.c:190:11:192:3 | { ... } | +| test.c:190:7:190:8 | ! ... | test.c:188:16:188:16 | b | == | test.c:188:11:188:11 | a | 0 | test.c:190:11:192:3 | { ... } | +| test.c:190:8:190:8 | c | test.c:188:11:188:11 | a | == | test.c:188:16:188:16 | b | 0 | test.c:190:11:192:3 | { ... } | +| test.c:190:8:190:8 | c | test.c:188:16:188:16 | b | == | test.c:188:11:188:11 | a | 0 | test.c:190:11:192:3 | { ... } | +| test.c:198:7:198:8 | ! ... | test.c:196:11:196:11 | a | < | test.c:196:15:196:16 | 10 | 1 | test.c:198:11:200:3 | { ... } | +| test.c:198:7:198:8 | ! ... | test.c:196:15:196:16 | 10 | >= | test.c:196:11:196:11 | a | 0 | test.c:198:11:200:3 | { ... } | +| test.c:198:8:198:8 | b | test.c:196:11:196:11 | a | < | test.c:196:15:196:16 | 10 | 1 | test.c:198:11:200:3 | { ... } | +| test.c:198:8:198:8 | b | test.c:196:15:196:16 | 10 | >= | test.c:196:11:196:11 | a | 0 | test.c:198:11:200:3 | { ... } | +| test.c:206:7:206:8 | ! ... | test.c:204:11:204:11 | a | < | test.c:204:15:204:15 | b | 1 | test.c:206:11:208:3 | { ... } | +| test.c:206:7:206:8 | ! ... | test.c:204:15:204:15 | b | >= | test.c:204:11:204:11 | a | 0 | test.c:206:11:208:3 | { ... } | +| test.c:206:8:206:8 | c | test.c:204:11:204:11 | a | < | test.c:204:15:204:15 | b | 1 | test.c:206:11:208:3 | { ... } | +| test.c:206:8:206:8 | c | test.c:204:15:204:15 | b | >= | test.c:204:11:204:11 | a | 0 | test.c:206:11:208:3 | { ... } | +| test.c:215:6:215:18 | call to __builtin_expect | test.c:215:13:215:13 | a | >= | test.c:215:17:215:17 | b | 1 | test.c:215:21:217:5 | { ... } | +| test.c:215:6:215:18 | call to __builtin_expect | test.c:215:17:215:17 | b | < | test.c:215:13:215:13 | a | 0 | test.c:215:21:217:5 | { ... } | +| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:16:219:16 | a | >= | test.c:219:20:219:21 | 42 | 1 | test.c:219:25:221:5 | { ... } | +| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:20:219:21 | 42 | < | test.c:219:16:219:16 | a | 0 | test.c:219:25:221:5 | { ... } | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:34:1:34:1 | return ... | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:31:16:32:21 | { ... } | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | test.cpp:34:1:34:1 | return ... | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | test.cpp:31:16:32:21 | { ... } | +| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:6 | f | != | test.cpp:105:11:105:14 | 0.0 | 0 | test.cpp:105:17:106:7 | { ... } | +| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:11:105:14 | 0.0 | != | test.cpp:105:6:105:6 | f | 0 | test.cpp:105:17:106:7 | { ... } | +| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:6 | i | != | test.cpp:111:11:111:14 | 0.0 | 0 | test.cpp:111:17:112:7 | { ... } | +| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:11:111:14 | 0.0 | != | test.cpp:111:6:111:6 | i | 0 | test.cpp:111:17:112:7 | { ... } | +| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:23:131:23 | a | == | test.cpp:131:28:131:28 | b | 42 | test.cpp:131:40:132:9 | { ... } | +| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:23:131:23 | a | == | test.cpp:131:28:131:33 | ... + ... | 0 | test.cpp:131:40:132:9 | { ... } | +| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:28:131:28 | b | == | test.cpp:131:23:131:23 | a | -42 | test.cpp:131:40:132:9 | { ... } | +| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:28:131:33 | ... + ... | == | test.cpp:131:23:131:23 | a | 0 | test.cpp:131:40:132:9 | { ... } | +| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:23:135:23 | a | != | test.cpp:135:28:135:28 | b | 42 | test.cpp:135:40:136:9 | { ... } | +| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:23:135:23 | a | != | test.cpp:135:28:135:33 | ... + ... | 0 | test.cpp:135:40:136:9 | { ... } | +| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:28:135:28 | b | != | test.cpp:135:23:135:23 | a | -42 | test.cpp:135:40:136:9 | { ... } | +| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:28:135:33 | ... + ... | != | test.cpp:135:23:135:23 | a | 0 | test.cpp:135:40:136:9 | { ... } | +| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:23 | a | == | test.cpp:141:28:141:29 | 42 | 0 | test.cpp:141:36:142:9 | { ... } | +| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:28:141:29 | 42 | == | test.cpp:141:23:141:23 | a | 0 | test.cpp:141:36:142:9 | { ... } | +| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | test.cpp:145:28:145:29 | 42 | 0 | test.cpp:145:36:146:9 | { ... } | +| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:28:145:29 | 42 | != | test.cpp:145:23:145:23 | a | 0 | test.cpp:145:36:146:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:8 | a | >= | test.cpp:151:12:151:13 | 10 | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:151:12:151:13 | 10 | < | test.cpp:151:8:151:8 | a | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:151:8:151:8 | a | >= | test.cpp:151:12:151:13 | 10 | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:151:12:151:13 | 10 | < | test.cpp:151:8:151:8 | a | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:12 | a | == | test.cpp:158:17:158:17 | b | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:7:160:8 | ! ... | test.cpp:158:17:158:17 | b | == | test.cpp:158:12:158:12 | a | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | test.cpp:158:12:158:12 | a | == | test.cpp:158:17:158:17 | b | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | test.cpp:158:17:158:17 | b | == | test.cpp:158:12:158:12 | a | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:12 | a | < | test.cpp:166:16:166:17 | 10 | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:166:16:166:17 | 10 | >= | test.cpp:166:12:166:12 | a | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:166:12:166:12 | a | < | test.cpp:166:16:166:17 | 10 | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:166:16:166:17 | 10 | >= | test.cpp:166:12:166:12 | a | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:12 | a | < | test.cpp:174:16:174:16 | b | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | test.cpp:174:16:174:16 | b | >= | test.cpp:174:12:174:12 | a | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | test.cpp:174:12:174:12 | a | < | test.cpp:174:16:174:16 | b | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | test.cpp:174:16:174:16 | b | >= | test.cpp:174:12:174:12 | a | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:10 | sc | == | test.cpp:211:15:211:15 | 0 | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:15:211:15 | 0 | == | test.cpp:211:9:211:10 | sc | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:10 | sc | == | test.cpp:214:15:214:17 | 0 | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:15:214:17 | 0 | == | test.cpp:214:9:214:10 | sc | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:10 | sc | == | test.cpp:211:15:211:15 | 0 | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:15:211:15 | 0 | == | test.cpp:211:9:211:10 | sc | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:10 | sc | == | test.cpp:214:15:214:17 | 0 | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:15:214:17 | 0 | == | test.cpp:214:9:214:10 | sc | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:10 | ul | == | test.cpp:217:15:217:15 | 0 | 0 | test.cpp:217:18:218:13 | { ... } | +| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:15:217:15 | 0 | == | test.cpp:217:9:217:10 | ul | 0 | test.cpp:217:18:218:13 | { ... } | +| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:9 | f | == | test.cpp:220:14:220:14 | 0 | 0 | test.cpp:220:17:221:13 | { ... } | +| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:14:220:14 | 0 | == | test.cpp:220:9:220:9 | f | 0 | test.cpp:220:17:221:13 | { ... } | +| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:9 | f | == | test.cpp:223:14:223:16 | 0.0 | 0 | test.cpp:223:19:224:13 | { ... } | +| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:14:223:16 | 0.0 | == | test.cpp:223:9:223:9 | f | 0 | test.cpp:223:19:224:13 | { ... } | +| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:9 | d | == | test.cpp:226:14:226:14 | 0 | 0 | test.cpp:226:17:227:13 | { ... } | +| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:14:226:14 | 0 | == | test.cpp:226:9:226:9 | d | 0 | test.cpp:226:17:227:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:9 | b | == | test.cpp:229:14:229:14 | 0 | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:14:229:14 | 0 | == | test.cpp:229:9:229:9 | b | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:9 | b | == | test.cpp:232:14:232:18 | 0 | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:14:232:18 | 0 | == | test.cpp:232:9:232:9 | b | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:9 | b | == | test.cpp:229:14:229:14 | 0 | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:14:229:14 | 0 | == | test.cpp:229:9:229:9 | b | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:9 | b | == | test.cpp:232:14:232:18 | 0 | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:14:232:18 | 0 | == | test.cpp:232:9:232:9 | b | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | test.cpp:238:20:239:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | test.cpp:238:20:239:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | test.cpp:238:20:239:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | test.cpp:238:20:239:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:12:238:12 | f | == | test.cpp:238:17:238:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:17:238:17 | 0 | == | test.cpp:238:12:238:12 | f | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:25:241:25 | f | == | test.cpp:241:30:241:30 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:30:241:30 | 0 | == | test.cpp:241:25:241:25 | f | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:12:235:12 | i | == | test.cpp:235:17:235:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:17:235:17 | 0 | == | test.cpp:235:12:235:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:12:241:12 | i | == | test.cpp:241:17:241:17 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:17:241:17 | 0 | == | test.cpp:241:12:241:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:38:241:38 | i | == | test.cpp:241:43:241:43 | 0 | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:43:241:43 | 0 | == | test.cpp:241:38:241:38 | i | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:7:247:7 | a | != | test.cpp:247:12:247:12 | b | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:7:247:7 | a | == | test.cpp:247:12:247:12 | b | 0 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:7:247:12 | ... == ... | != | test.cpp:247:18:247:18 | 0 | 0 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:7:247:12 | ... == ... | == | test.cpp:247:18:247:18 | 0 | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:12:247:12 | b | != | test.cpp:247:7:247:7 | a | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:12:247:12 | b | == | test.cpp:247:7:247:7 | a | 0 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:18:247:18 | 0 | != | test.cpp:247:7:247:12 | ... == ... | 0 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:18:247:18 | 0 | == | test.cpp:247:7:247:12 | ... == ... | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:253:7:253:7 | a | != | test.cpp:253:12:253:12 | b | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:253:7:253:7 | a | == | test.cpp:253:12:253:12 | b | 0 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:253:12:253:12 | b | != | test.cpp:253:7:253:7 | a | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:253:12:253:12 | b | == | test.cpp:253:7:253:7 | a | 0 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:247:7:247:7 | a | != | test.cpp:247:12:247:12 | b | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:247:7:247:7 | a | == | test.cpp:247:12:247:12 | b | 0 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:247:12:247:12 | b | != | test.cpp:247:7:247:7 | a | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:247:12:247:12 | b | == | test.cpp:247:7:247:7 | a | 0 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:7:253:7 | a | != | test.cpp:253:12:253:12 | b | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:7:253:7 | a | == | test.cpp:253:12:253:12 | b | 0 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:7:253:12 | ... == ... | != | test.cpp:253:18:253:18 | 0 | 0 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:7:253:12 | ... == ... | == | test.cpp:253:18:253:18 | 0 | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:12:253:12 | b | != | test.cpp:253:7:253:7 | a | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:12:253:12 | b | == | test.cpp:253:7:253:7 | a | 0 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:18:253:18 | 0 | != | test.cpp:253:7:253:12 | ... == ... | 0 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:18:253:18 | 0 | == | test.cpp:253:7:253:12 | ... == ... | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:7:260:7 | a | != | test.cpp:260:12:260:12 | b | 0 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:7:260:7 | a | == | test.cpp:260:12:260:12 | b | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:7:260:12 | ... != ... | != | test.cpp:260:18:260:18 | 0 | 0 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:7:260:12 | ... != ... | == | test.cpp:260:18:260:18 | 0 | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:12:260:12 | b | != | test.cpp:260:7:260:7 | a | 0 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:12:260:12 | b | == | test.cpp:260:7:260:7 | a | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:18:260:18 | 0 | != | test.cpp:260:7:260:12 | ... != ... | 0 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:18:260:18 | 0 | == | test.cpp:260:7:260:12 | ... != ... | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:266:7:266:7 | a | != | test.cpp:266:12:266:12 | b | 0 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:266:7:266:7 | a | == | test.cpp:266:12:266:12 | b | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:266:12:266:12 | b | != | test.cpp:266:7:266:7 | a | 0 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:266:12:266:12 | b | == | test.cpp:266:7:266:7 | a | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:260:7:260:7 | a | != | test.cpp:260:12:260:12 | b | 0 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:260:7:260:7 | a | == | test.cpp:260:12:260:12 | b | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:260:12:260:12 | b | != | test.cpp:260:7:260:7 | a | 0 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:260:12:260:12 | b | == | test.cpp:260:7:260:7 | a | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:7:266:7 | a | != | test.cpp:266:12:266:12 | b | 0 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:7:266:7 | a | == | test.cpp:266:12:266:12 | b | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:7:266:12 | ... != ... | != | test.cpp:266:18:266:18 | 0 | 0 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:7:266:12 | ... != ... | == | test.cpp:266:18:266:18 | 0 | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:12:266:12 | b | != | test.cpp:266:7:266:7 | a | 0 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:12:266:12 | b | == | test.cpp:266:7:266:7 | a | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:18:266:18 | 0 | != | test.cpp:266:7:266:12 | ... != ... | 0 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:18:266:18 | 0 | == | test.cpp:266:7:266:12 | ... != ... | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:7:273:7 | a | < | test.cpp:273:11:273:11 | b | 0 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:7:273:7 | a | >= | test.cpp:273:11:273:11 | b | 0 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:7:273:11 | ... < ... | != | test.cpp:273:17:273:17 | 0 | 0 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:7:273:11 | ... < ... | == | test.cpp:273:17:273:17 | 0 | 0 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:11:273:11 | b | < | test.cpp:273:7:273:7 | a | 1 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:11:273:11 | b | >= | test.cpp:273:7:273:7 | a | 1 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:17:273:17 | 0 | != | test.cpp:273:7:273:11 | ... < ... | 0 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:17:273:17 | 0 | == | test.cpp:273:7:273:11 | ... < ... | 0 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:279:7:279:7 | a | < | test.cpp:279:11:279:11 | b | 0 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:279:7:279:7 | a | >= | test.cpp:279:11:279:11 | b | 0 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:279:11:279:11 | b | < | test.cpp:279:7:279:7 | a | 1 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:279:11:279:11 | b | >= | test.cpp:279:7:279:7 | a | 1 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:273:7:273:7 | a | < | test.cpp:273:11:273:11 | b | 0 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:273:7:273:7 | a | >= | test.cpp:273:11:273:11 | b | 0 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:273:11:273:11 | b | < | test.cpp:273:7:273:7 | a | 1 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:273:11:273:11 | b | >= | test.cpp:273:7:273:7 | a | 1 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:7:279:7 | a | < | test.cpp:279:11:279:11 | b | 0 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:7:279:7 | a | >= | test.cpp:279:11:279:11 | b | 0 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:7:279:11 | ... < ... | != | test.cpp:279:17:279:17 | 0 | 0 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:7:279:11 | ... < ... | == | test.cpp:279:17:279:17 | 0 | 0 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:11:279:11 | b | < | test.cpp:279:7:279:7 | a | 1 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:11:279:11 | b | >= | test.cpp:279:7:279:7 | a | 1 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:17:279:17 | 0 | != | test.cpp:279:7:279:11 | ... < ... | 0 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:17:279:17 | 0 | == | test.cpp:279:7:279:11 | ... < ... | 0 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:7:287:7 | a | != | test.cpp:287:12:287:13 | 42 | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:7:287:7 | a | == | test.cpp:287:12:287:13 | 42 | 0 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:7:287:13 | ... == ... | != | test.cpp:287:19:287:19 | 0 | 0 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:7:287:13 | ... == ... | == | test.cpp:287:19:287:19 | 0 | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:12:287:13 | 42 | != | test.cpp:287:7:287:7 | a | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:12:287:13 | 42 | == | test.cpp:287:7:287:7 | a | 0 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:19:287:19 | 0 | != | test.cpp:287:7:287:13 | ... == ... | 0 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:19:287:19 | 0 | == | test.cpp:287:7:287:13 | ... == ... | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:293:7:293:7 | a | != | test.cpp:293:12:293:13 | 42 | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:293:7:293:7 | a | == | test.cpp:293:12:293:13 | 42 | 0 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:293:12:293:13 | 42 | != | test.cpp:293:7:293:7 | a | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:293:12:293:13 | 42 | == | test.cpp:293:7:293:7 | a | 0 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:287:7:287:7 | a | != | test.cpp:287:12:287:13 | 42 | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:287:7:287:7 | a | == | test.cpp:287:12:287:13 | 42 | 0 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:287:12:287:13 | 42 | != | test.cpp:287:7:287:7 | a | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:287:12:287:13 | 42 | == | test.cpp:287:7:287:7 | a | 0 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:7:293:7 | a | != | test.cpp:293:12:293:13 | 42 | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:7:293:7 | a | == | test.cpp:293:12:293:13 | 42 | 0 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:7:293:13 | ... == ... | != | test.cpp:293:19:293:19 | 0 | 0 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:7:293:13 | ... == ... | == | test.cpp:293:19:293:19 | 0 | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:12:293:13 | 42 | != | test.cpp:293:7:293:7 | a | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:12:293:13 | 42 | == | test.cpp:293:7:293:7 | a | 0 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:19:293:19 | 0 | != | test.cpp:293:7:293:13 | ... == ... | 0 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:19:293:19 | 0 | == | test.cpp:293:7:293:13 | ... == ... | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:7:300:7 | a | != | test.cpp:300:12:300:13 | 42 | 0 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:7:300:7 | a | == | test.cpp:300:12:300:13 | 42 | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:7:300:13 | ... != ... | != | test.cpp:300:19:300:19 | 0 | 0 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:7:300:13 | ... != ... | == | test.cpp:300:19:300:19 | 0 | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:12:300:13 | 42 | != | test.cpp:300:7:300:7 | a | 0 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:12:300:13 | 42 | == | test.cpp:300:7:300:7 | a | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:19:300:19 | 0 | != | test.cpp:300:7:300:13 | ... != ... | 0 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:19:300:19 | 0 | == | test.cpp:300:7:300:13 | ... != ... | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:306:7:306:7 | a | != | test.cpp:306:12:306:13 | 42 | 0 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:306:7:306:7 | a | == | test.cpp:306:12:306:13 | 42 | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:306:12:306:13 | 42 | != | test.cpp:306:7:306:7 | a | 0 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:306:12:306:13 | 42 | == | test.cpp:306:7:306:7 | a | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:300:7:300:7 | a | != | test.cpp:300:12:300:13 | 42 | 0 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:300:7:300:7 | a | == | test.cpp:300:12:300:13 | 42 | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:300:12:300:13 | 42 | != | test.cpp:300:7:300:7 | a | 0 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:300:12:300:13 | 42 | == | test.cpp:300:7:300:7 | a | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:7:306:7 | a | != | test.cpp:306:12:306:13 | 42 | 0 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:7:306:7 | a | == | test.cpp:306:12:306:13 | 42 | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:7:306:13 | ... != ... | != | test.cpp:306:19:306:19 | 0 | 0 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:7:306:13 | ... != ... | == | test.cpp:306:19:306:19 | 0 | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:12:306:13 | 42 | != | test.cpp:306:7:306:7 | a | 0 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:12:306:13 | 42 | == | test.cpp:306:7:306:7 | a | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:19:306:19 | 0 | != | test.cpp:306:7:306:13 | ... != ... | 0 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:19:306:19 | 0 | == | test.cpp:306:7:306:13 | ... != ... | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:7:312:7 | a | < | test.cpp:312:11:312:12 | 42 | 0 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:7:312:7 | a | >= | test.cpp:312:11:312:12 | 42 | 0 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:7:312:12 | ... < ... | != | test.cpp:312:18:312:18 | 0 | 0 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:7:312:12 | ... < ... | == | test.cpp:312:18:312:18 | 0 | 0 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:11:312:12 | 42 | < | test.cpp:312:7:312:7 | a | 1 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:11:312:12 | 42 | >= | test.cpp:312:7:312:7 | a | 1 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:18:312:18 | 0 | != | test.cpp:312:7:312:12 | ... < ... | 0 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:18:312:18 | 0 | == | test.cpp:312:7:312:12 | ... < ... | 0 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:318:7:318:7 | a | < | test.cpp:318:11:318:12 | 42 | 0 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:318:7:318:7 | a | >= | test.cpp:318:11:318:12 | 42 | 0 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:318:11:318:12 | 42 | < | test.cpp:318:7:318:7 | a | 1 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:318:11:318:12 | 42 | >= | test.cpp:318:7:318:7 | a | 1 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:312:7:312:7 | a | < | test.cpp:312:11:312:12 | 42 | 0 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:312:7:312:7 | a | >= | test.cpp:312:11:312:12 | 42 | 0 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:312:11:312:12 | 42 | < | test.cpp:312:7:312:7 | a | 1 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:312:11:312:12 | 42 | >= | test.cpp:312:7:312:7 | a | 1 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:7 | a | < | test.cpp:318:11:318:12 | 42 | 0 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:7 | a | >= | test.cpp:318:11:318:12 | 42 | 0 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:12 | ... < ... | != | test.cpp:318:18:318:18 | 0 | 0 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:12 | ... < ... | == | test.cpp:318:18:318:18 | 0 | 0 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:11:318:12 | 42 | < | test.cpp:318:7:318:7 | a | 1 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:11:318:12 | 42 | >= | test.cpp:318:7:318:7 | a | 1 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:18:318:18 | 0 | != | test.cpp:318:7:318:12 | ... < ... | 0 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:18:318:18 | 0 | == | test.cpp:318:7:318:12 | ... < ... | 0 | test.cpp:320:10:322:3 | { ... } | unary -| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | 10 | 11 | -| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | 7 | 9 | -| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | != | 0 | 7 | 9 | -| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | != | 1 | 10 | 11 | -| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | == | 0 | 10 | 11 | -| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | == | 1 | 7 | 9 | -| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | 17 | 17 | -| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | 18 | 18 | -| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:12 | ... < ... | != | 0 | 17 | 17 | -| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:12 | ... < ... | != | 0 | 18 | 18 | -| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:12 | ... < ... | == | 1 | 17 | 17 | -| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:12 | ... < ... | == | 1 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:8 | x | < | 0 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:12 | ... < ... | != | 0 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:12 | ... < ... | == | 1 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:17 | y | >= | 2 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:21 | ... > ... | != | 0 | 18 | 18 | -| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:21 | ... > ... | == | 1 | 18 | 18 | -| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:17 | y | >= | 2 | 18 | 18 | -| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:21 | ... > ... | != | 0 | 18 | 18 | -| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:21 | ... > ... | == | 1 | 18 | 18 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 2 | 2 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 31 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 34 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 39 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 42 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 42 | 44 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 45 | 45 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 45 | 47 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 51 | 53 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 56 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 58 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 58 | 66 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 62 | 62 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | >= | 1 | 26 | 28 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 0 | 26 | 28 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 2 | 2 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 31 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 34 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 39 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 42 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 42 | 44 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 45 | 45 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 45 | 47 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 51 | 53 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 56 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 58 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 58 | 66 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | 62 | 62 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 2 | 2 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 31 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 34 | 34 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 39 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 42 | 42 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 42 | 44 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 45 | 45 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 45 | 47 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 51 | 53 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 56 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 58 | 58 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 58 | 66 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | 62 | 62 | -| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 1 | 26 | 28 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | < | 10 | 34 | 34 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 2 | 2 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 39 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 42 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 42 | 44 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 45 | 45 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 45 | 47 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 51 | 53 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 56 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 58 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 58 | 66 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 62 | 62 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 0 | 34 | 34 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 2 | 2 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 39 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 42 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 42 | 44 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 45 | 45 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 45 | 47 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 51 | 53 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 56 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 58 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 58 | 66 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | 62 | 62 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 2 | 2 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 39 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 42 | 42 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 42 | 44 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 45 | 45 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 45 | 47 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 51 | 53 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 56 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 58 | 58 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 58 | 66 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | 62 | 62 | -| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 1 | 34 | 34 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 42 | 42 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 42 | 44 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 45 | 45 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 45 | 47 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 51 | 53 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | 42 | 42 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | 42 | 44 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | 45 | 45 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | 45 | 47 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | 51 | 53 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | 42 | 42 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | 42 | 44 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | 45 | 45 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | 45 | 47 | -| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | 51 | 53 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | 42 | 42 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | 51 | 53 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | 45 | 45 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | 45 | 47 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | != | 0 | 45 | 45 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | != | 0 | 45 | 47 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | != | 1 | 42 | 42 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | != | 1 | 51 | 53 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | == | 0 | 42 | 42 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | == | 0 | 51 | 53 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | == | 1 | 45 | 45 | -| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | == | 1 | 45 | 47 | -| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | >= | 1 | 45 | 47 | -| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:20 | ... > ... | != | 0 | 45 | 47 | -| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:20 | ... > ... | == | 1 | 45 | 47 | -| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | 58 | 58 | -| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | 62 | 62 | -| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:14 | ... == ... | != | 1 | 58 | 58 | -| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:14 | ... == ... | != | 1 | 62 | 62 | -| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:14 | ... == ... | == | 0 | 58 | 58 | -| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:14 | ... == ... | == | 0 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:9 | x | != | 0 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:14 | ... == ... | != | 1 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:14 | ... == ... | == | 0 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:19 | y | >= | 0 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:23 | ... < ... | != | 1 | 62 | 62 | -| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:23 | ... < ... | == | 0 | 62 | 62 | -| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:19 | y | >= | 0 | 62 | 62 | -| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:23 | ... < ... | != | 1 | 62 | 62 | -| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:23 | ... < ... | == | 0 | 62 | 62 | -| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | != | 0 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | == | 0 | 75 | 77 | -| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:14 | ... == ... | != | 0 | 75 | 77 | -| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:14 | ... == ... | != | 1 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:14 | ... == ... | == | 0 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:14 | ... == ... | == | 1 | 75 | 77 | -| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:8 | x | != | 0 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 75 | 77 | -| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:13 | ... == ... | != | 0 | 75 | 77 | -| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:13 | ... == ... | != | 1 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:13 | ... == ... | == | 0 | 78 | 79 | -| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:13 | ... == ... | == | 1 | 75 | 77 | -| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:9 | x | == | 0 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:9 | x | == | 0 | 86 | 86 | -| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:14 | ... == ... | != | 0 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:14 | ... == ... | != | 0 | 86 | 86 | -| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:14 | ... == ... | == | 1 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:14 | ... == ... | == | 1 | 86 | 86 | -| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 86 | 86 | -| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:13 | ... == ... | != | 0 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:13 | ... == ... | != | 0 | 86 | 86 | -| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:13 | ... == ... | == | 1 | 85 | 85 | -| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:13 | ... == ... | == | 1 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:75:9:75:9 | x | == | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:75:9:75:14 | ... == ... | != | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:75:9:75:14 | ... == ... | == | 1 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:8 | x | == | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:13 | ... == ... | != | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:13 | ... == ... | == | 1 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:18 | y | != | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:23 | ... != ... | != | 0 | 86 | 86 | -| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:23 | ... != ... | == | 1 | 86 | 86 | -| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:18 | y | != | 0 | 86 | 86 | -| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:23 | ... != ... | != | 0 | 86 | 86 | -| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:23 | ... != ... | == | 1 | 86 | 86 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | != | 0 | 94 | 96 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 70 | 70 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 99 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 102 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 107 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 109 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 109 | 117 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 113 | 113 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 0 | 94 | 96 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | 70 | 70 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | 99 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | 102 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | 107 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | 109 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | 109 | 117 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | 113 | 113 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | 70 | 70 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | 99 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | 102 | 102 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | 107 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | 109 | 109 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | 109 | 117 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | 113 | 113 | -| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 1 | 94 | 96 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | < | 10 | 102 | 102 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 70 | 70 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 107 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 109 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 109 | 117 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 113 | 113 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 0 | 102 | 102 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | 70 | 70 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | 107 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | 109 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | 109 | 117 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | 113 | 113 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | 70 | 70 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | 107 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | 109 | 109 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | 109 | 117 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | 113 | 113 | -| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 1 | 102 | 102 | -| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 109 | 109 | -| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | -| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:14 | ... == ... | != | 1 | 109 | 109 | -| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:14 | ... == ... | != | 1 | 113 | 113 | -| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:14 | ... == ... | == | 0 | 109 | 109 | -| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:14 | ... == ... | == | 0 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:14 | ... == ... | != | 1 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:14 | ... == ... | == | 0 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:23 | ... < ... | != | 1 | 113 | 113 | -| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:23 | ... < ... | == | 0 | 113 | 113 | -| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 | -| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:23 | ... < ... | != | 1 | 113 | 113 | -| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:23 | ... < ... | == | 0 | 113 | 113 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 126 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 126 | 126 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 131 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 | -| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 | -| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | -| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 | -| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | -| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 | -| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | -| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 | -| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | 131 | 132 | -| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | == | 1 | 131 | 132 | -| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | != | 1 | 142 | 136 | -| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | == | 0 | 142 | 136 | -| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 | -| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | == | 1 | 146 | 147 | -| test.c:146:7:146:8 | ! ... | test.c:146:8:146:8 | x | == | 0 | 146 | 147 | -| test.c:146:8:146:8 | x | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 | -| test.c:146:8:146:8 | x | test.c:146:7:146:8 | ! ... | == | 1 | 146 | 147 | -| test.c:146:8:146:8 | x | test.c:146:8:146:8 | x | == | 0 | 146 | 147 | -| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | != | 0 | 152 | 154 | -| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | == | 1 | 152 | 154 | -| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | != | 0 | 158 | 160 | -| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | == | 1 | 158 | 160 | -| test.c:158:8:158:9 | ! ... | test.c:158:9:158:9 | p | == | 0 | 158 | 160 | -| test.c:158:9:158:9 | p | test.c:158:8:158:9 | ! ... | != | 0 | 158 | 160 | -| test.c:158:9:158:9 | p | test.c:158:8:158:9 | ! ... | == | 1 | 158 | 160 | -| test.c:158:9:158:9 | p | test.c:158:9:158:9 | p | == | 0 | 158 | 160 | -| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | != | 0 | 164 | 166 | -| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | == | 1 | 164 | 166 | -| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | != | 0 | 170 | 172 | -| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | == | 1 | 170 | 172 | -| test.c:170:8:170:9 | ! ... | test.c:170:9:170:9 | s | == | 0 | 170 | 172 | -| test.c:170:9:170:9 | s | test.c:170:8:170:9 | ! ... | != | 0 | 170 | 172 | -| test.c:170:9:170:9 | s | test.c:170:8:170:9 | ! ... | == | 1 | 170 | 172 | -| test.c:170:9:170:9 | s | test.c:170:9:170:9 | s | == | 0 | 170 | 172 | -| test.c:176:8:176:15 | ! ... | test.c:176:8:176:15 | ! ... | != | 0 | 176 | 178 | -| test.c:176:8:176:15 | ! ... | test.c:176:8:176:15 | ! ... | == | 1 | 176 | 178 | -| test.c:176:8:176:15 | ! ... | test.c:176:10:176:14 | ... < ... | == | 0 | 176 | 178 | -| test.c:176:10:176:14 | ... < ... | test.c:176:8:176:15 | ! ... | != | 0 | 176 | 178 | -| test.c:176:10:176:14 | ... < ... | test.c:176:8:176:15 | ! ... | == | 1 | 176 | 178 | -| test.c:176:10:176:14 | ... < ... | test.c:176:10:176:14 | ... < ... | == | 0 | 176 | 178 | -| test.c:182:8:182:34 | ! ... | test.c:182:8:182:34 | ! ... | != | 0 | 182 | 184 | -| test.c:182:8:182:34 | ! ... | test.c:182:8:182:34 | ! ... | == | 1 | 182 | 184 | -| test.c:182:8:182:34 | ! ... | test.c:182:10:182:33 | ... && ... | == | 0 | 182 | 184 | -| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:20 | ... >= ... | != | 0 | 181 | 182 | -| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:20 | ... >= ... | != | 0 | 182 | 182 | -| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:20 | ... >= ... | == | 1 | 181 | 182 | -| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:20 | ... >= ... | == | 1 | 182 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:8:182:34 | ! ... | != | 0 | 182 | 184 | -| test.c:182:10:182:33 | ... && ... | test.c:182:8:182:34 | ! ... | != | 1 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:8:182:34 | ! ... | == | 0 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:8:182:34 | ! ... | == | 1 | 182 | 184 | -| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:20 | ... >= ... | != | 0 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:20 | ... >= ... | == | 1 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:33 | ... && ... | != | 0 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:33 | ... && ... | == | 0 | 182 | 184 | -| test.c:182:10:182:33 | ... && ... | test.c:182:25:182:33 | ... < ... | != | 0 | 181 | 182 | -| test.c:182:10:182:33 | ... && ... | test.c:182:25:182:33 | ... < ... | == | 1 | 181 | 182 | -| test.c:182:25:182:33 | ... < ... | test.c:182:25:182:33 | ... < ... | != | 0 | 181 | 182 | -| test.c:182:25:182:33 | ... < ... | test.c:182:25:182:33 | ... < ... | == | 1 | 181 | 182 | -| test.c:190:7:190:8 | ! ... | test.c:190:7:190:8 | ! ... | != | 0 | 190 | 192 | -| test.c:190:7:190:8 | ! ... | test.c:190:7:190:8 | ! ... | == | 1 | 190 | 192 | -| test.c:190:7:190:8 | ! ... | test.c:190:8:190:8 | c | == | 0 | 190 | 192 | -| test.c:190:8:190:8 | c | test.c:190:7:190:8 | ! ... | != | 0 | 190 | 192 | -| test.c:190:8:190:8 | c | test.c:190:7:190:8 | ! ... | == | 1 | 190 | 192 | -| test.c:190:8:190:8 | c | test.c:190:8:190:8 | c | == | 0 | 190 | 192 | -| test.c:198:7:198:8 | ! ... | test.c:198:7:198:8 | ! ... | != | 0 | 198 | 200 | -| test.c:198:7:198:8 | ! ... | test.c:198:7:198:8 | ! ... | == | 1 | 198 | 200 | -| test.c:198:7:198:8 | ! ... | test.c:198:8:198:8 | b | == | 0 | 198 | 200 | -| test.c:198:8:198:8 | b | test.c:198:7:198:8 | ! ... | != | 0 | 198 | 200 | -| test.c:198:8:198:8 | b | test.c:198:7:198:8 | ! ... | == | 1 | 198 | 200 | -| test.c:198:8:198:8 | b | test.c:198:8:198:8 | b | == | 0 | 198 | 200 | -| test.c:206:7:206:8 | ! ... | test.c:206:7:206:8 | ! ... | != | 0 | 206 | 208 | -| test.c:206:7:206:8 | ! ... | test.c:206:7:206:8 | ! ... | == | 1 | 206 | 208 | -| test.c:206:7:206:8 | ! ... | test.c:206:8:206:8 | c | == | 0 | 206 | 208 | -| test.c:206:8:206:8 | c | test.c:206:7:206:8 | ! ... | != | 0 | 206 | 208 | -| test.c:206:8:206:8 | c | test.c:206:7:206:8 | ! ... | == | 1 | 206 | 208 | -| test.c:206:8:206:8 | c | test.c:206:8:206:8 | c | == | 0 | 206 | 208 | -| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 | -| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | 19 | 19 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 31 | 32 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | 31 | 32 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | 34 | 34 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | 34 | 34 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 30 | 30 | -| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 31 | 32 | -| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | 43 | 45 | -| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | 43 | 45 | -| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 0 | 62 | 64 | -| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 1 | 65 | 66 | -| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 11 | 75 | 77 | -| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 21 | 78 | 79 | -| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | 75 | 77 | -| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 11 | 78 | 79 | -| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | != | 0 | 93 | 94 | -| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | == | 1 | 93 | 94 | -| test.cpp:99:6:99:6 | f | test.cpp:99:6:99:6 | f | != | 0 | 99 | 100 | -| test.cpp:99:6:99:6 | f | test.cpp:99:6:99:6 | f | == | 1 | 99 | 100 | -| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:14 | ... != ... | != | 0 | 105 | 106 | -| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:14 | ... != ... | == | 1 | 105 | 106 | -| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:14 | ... != ... | != | 0 | 111 | 112 | -| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:14 | ... != ... | == | 1 | 111 | 112 | -| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | != | 0 | 123 | 125 | -| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | != | 0 | 125 | 125 | -| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | == | 1 | 123 | 125 | -| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | == | 1 | 125 | 125 | -| test.cpp:125:13:125:20 | ! ... | test.cpp:125:13:125:20 | ! ... | != | 0 | 125 | 125 | -| test.cpp:125:13:125:20 | ! ... | test.cpp:125:13:125:20 | ! ... | == | 1 | 125 | 125 | -| test.cpp:125:13:125:20 | ! ... | test.cpp:125:14:125:17 | call to safe | != | 1 | 125 | 125 | -| test.cpp:125:13:125:20 | ! ... | test.cpp:125:14:125:17 | call to safe | == | 0 | 125 | 125 | -| test.cpp:125:14:125:17 | call to safe | test.cpp:125:13:125:20 | ! ... | != | 0 | 125 | 125 | -| test.cpp:125:14:125:17 | call to safe | test.cpp:125:13:125:20 | ! ... | == | 1 | 125 | 125 | -| test.cpp:125:14:125:17 | call to safe | test.cpp:125:14:125:17 | call to safe | != | 1 | 125 | 125 | -| test.cpp:125:14:125:17 | call to safe | test.cpp:125:14:125:17 | call to safe | == | 0 | 125 | 125 | -| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:6:131:21 | call to __builtin_expect | != | 0 | 131 | 132 | -| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:6:131:21 | call to __builtin_expect | == | 1 | 131 | 132 | -| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:6:135:21 | call to __builtin_expect | != | 0 | 135 | 136 | -| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:6:135:21 | call to __builtin_expect | == | 1 | 135 | 136 | -| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:6:141:21 | call to __builtin_expect | != | 0 | 141 | 142 | -| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:6:141:21 | call to __builtin_expect | == | 1 | 141 | 142 | -| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:23 | a | == | 42 | 141 | 142 | -| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | != | 0 | 145 | 146 | -| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | == | 1 | 145 | 146 | -| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | 42 | 145 | 146 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:8 | a | >= | 10 | 152 | 153 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:13 | ... < ... | != | 1 | 152 | 153 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:13 | ... < ... | == | 0 | 152 | 153 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:152:7:152:8 | ! ... | != | 0 | 152 | 153 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:152:7:152:8 | ! ... | == | 1 | 152 | 153 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:152:8:152:8 | b | != | 1 | 152 | 153 | -| test.cpp:152:7:152:8 | ! ... | test.cpp:152:8:152:8 | b | == | 0 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:151:8:151:8 | a | >= | 10 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:151:8:151:13 | ... < ... | != | 1 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:151:8:151:13 | ... < ... | == | 0 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:152:7:152:8 | ! ... | != | 0 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:152:7:152:8 | ! ... | == | 1 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:152:8:152:8 | b | != | 1 | 152 | 153 | -| test.cpp:152:8:152:8 | b | test.cpp:152:8:152:8 | b | == | 0 | 152 | 153 | -| test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:17 | ... != ... | != | 1 | 160 | 162 | -| test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:17 | ... != ... | == | 0 | 160 | 162 | -| test.cpp:160:7:160:8 | ! ... | test.cpp:160:7:160:8 | ! ... | != | 0 | 160 | 162 | -| test.cpp:160:7:160:8 | ! ... | test.cpp:160:7:160:8 | ! ... | == | 1 | 160 | 162 | -| test.cpp:160:7:160:8 | ! ... | test.cpp:160:8:160:8 | c | != | 1 | 160 | 162 | -| test.cpp:160:7:160:8 | ! ... | test.cpp:160:8:160:8 | c | == | 0 | 160 | 162 | -| test.cpp:160:8:160:8 | c | test.cpp:158:12:158:17 | ... != ... | != | 1 | 160 | 162 | -| test.cpp:160:8:160:8 | c | test.cpp:158:12:158:17 | ... != ... | == | 0 | 160 | 162 | -| test.cpp:160:8:160:8 | c | test.cpp:160:7:160:8 | ! ... | != | 0 | 160 | 162 | -| test.cpp:160:8:160:8 | c | test.cpp:160:7:160:8 | ! ... | == | 1 | 160 | 162 | -| test.cpp:160:8:160:8 | c | test.cpp:160:8:160:8 | c | != | 1 | 160 | 162 | -| test.cpp:160:8:160:8 | c | test.cpp:160:8:160:8 | c | == | 0 | 160 | 162 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:12 | a | < | 11 | 168 | 170 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:17 | ... > ... | != | 1 | 168 | 170 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:17 | ... > ... | == | 0 | 168 | 170 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:168:7:168:8 | ! ... | != | 0 | 168 | 170 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:168:7:168:8 | ! ... | == | 1 | 168 | 170 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:168:8:168:8 | b | != | 1 | 168 | 170 | -| test.cpp:168:7:168:8 | ! ... | test.cpp:168:8:168:8 | b | == | 0 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:166:12:166:12 | a | < | 11 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:166:12:166:17 | ... > ... | != | 1 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:166:12:166:17 | ... > ... | == | 0 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:168:7:168:8 | ! ... | != | 0 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:168:7:168:8 | ! ... | == | 1 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:168:8:168:8 | b | != | 1 | 168 | 170 | -| test.cpp:168:8:168:8 | b | test.cpp:168:8:168:8 | b | == | 0 | 168 | 170 | -| test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:16 | ... > ... | != | 1 | 176 | 178 | -| test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:16 | ... > ... | == | 0 | 176 | 178 | -| test.cpp:176:7:176:8 | ! ... | test.cpp:176:7:176:8 | ! ... | != | 0 | 176 | 178 | -| test.cpp:176:7:176:8 | ! ... | test.cpp:176:7:176:8 | ! ... | == | 1 | 176 | 178 | -| test.cpp:176:7:176:8 | ! ... | test.cpp:176:8:176:8 | c | != | 1 | 176 | 178 | -| test.cpp:176:7:176:8 | ! ... | test.cpp:176:8:176:8 | c | == | 0 | 176 | 178 | -| test.cpp:176:8:176:8 | c | test.cpp:174:12:174:16 | ... > ... | != | 1 | 176 | 178 | -| test.cpp:176:8:176:8 | c | test.cpp:174:12:174:16 | ... > ... | == | 0 | 176 | 178 | -| test.cpp:176:8:176:8 | c | test.cpp:176:7:176:8 | ! ... | != | 0 | 176 | 178 | -| test.cpp:176:8:176:8 | c | test.cpp:176:7:176:8 | ! ... | == | 1 | 176 | 178 | -| test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | != | 1 | 176 | 178 | -| test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | == | 0 | 176 | 178 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 0 | 182 | 184 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 185 | 188 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 185 | 188 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 1 | 182 | 184 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:9 | b1 | != | 0 | 185 | 188 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:9 | b1 | == | 1 | 185 | 188 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 185 | 188 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | != | 1 | 182 | 184 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | == | 0 | 182 | 184 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 185 | 188 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | != | 0 | 185 | 188 | -| test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | == | 1 | 185 | 188 | -| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | 181 | 182 | -| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | 182 | 182 | -| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | 181 | 182 | -| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | 182 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 0 | 182 | 184 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 185 | 188 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 185 | 188 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 1 | 182 | 184 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | != | 0 | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | != | 0 | 185 | 188 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | == | 1 | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | == | 1 | 185 | 188 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 185 | 188 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 1 | 182 | 184 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 0 | 182 | 184 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 185 | 188 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | != | 0 | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | != | 0 | 185 | 188 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | 181 | 182 | -| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | 185 | 188 | -| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | != | 0 | 181 | 182 | -| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | == | 1 | 181 | 182 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 193 | 196 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 1 | 197 | 199 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 0 | 197 | 199 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 193 | 196 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 196 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 196 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 0 | 197 | 199 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 193 | 196 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 193 | 196 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 1 | 197 | 199 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | != | 1 | 193 | 196 | -| test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | == | 0 | 193 | 196 | -| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | 192 | 193 | -| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 193 | -| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | 192 | 193 | -| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 193 | 196 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 1 | 197 | 199 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 0 | 197 | 199 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 193 | 196 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | != | 1 | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 196 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | == | 0 | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 196 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 0 | 197 | 199 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 193 | 196 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 193 | 196 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 1 | 197 | 199 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | != | 1 | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | != | 1 | 193 | 196 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | 192 | 193 | -| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | 193 | 196 | -| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | 192 | 193 | -| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | 192 | 193 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:10 | sc | == | 0 | 211 | 212 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:15 | ... == ... | != | 0 | 211 | 212 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:15 | ... == ... | == | 1 | 211 | 212 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:10 | sc | == | 0 | 211 | 212 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:17 | ... == ... | != | 0 | 211 | 212 | -| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:17 | ... == ... | == | 1 | 211 | 212 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:10 | sc | == | 0 | 214 | 215 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:15 | ... == ... | != | 0 | 214 | 215 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:15 | ... == ... | == | 1 | 214 | 215 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:10 | sc | == | 0 | 214 | 215 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:17 | ... == ... | != | 0 | 214 | 215 | -| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:17 | ... == ... | == | 1 | 214 | 215 | -| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:10 | ul | == | 0 | 217 | 218 | -| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:15 | ... == ... | != | 0 | 217 | 218 | -| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:15 | ... == ... | == | 1 | 217 | 218 | -| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:14 | ... == ... | != | 0 | 220 | 221 | -| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:14 | ... == ... | == | 1 | 220 | 221 | -| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:16 | ... == ... | != | 0 | 223 | 224 | -| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:16 | ... == ... | == | 1 | 223 | 224 | -| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:14 | ... == ... | != | 0 | 226 | 227 | -| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:14 | ... == ... | == | 1 | 226 | 227 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:9 | b | == | 0 | 229 | 230 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:14 | ... == ... | != | 0 | 229 | 230 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:14 | ... == ... | == | 1 | 229 | 230 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:9 | b | == | 0 | 229 | 230 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:18 | ... == ... | != | 0 | 229 | 230 | -| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:18 | ... == ... | == | 1 | 229 | 230 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:9 | b | == | 0 | 232 | 233 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:14 | ... == ... | != | 0 | 232 | 233 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:14 | ... == ... | == | 1 | 232 | 233 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:9 | b | == | 0 | 232 | 233 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:18 | ... == ... | != | 0 | 232 | 233 | -| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:18 | ... == ... | == | 1 | 232 | 233 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 235 | 236 | -| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | 235 | 236 | -| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 238 | 239 | -| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 238 | 239 | -| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 238 | 239 | -| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 238 | 239 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 241 | -| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 241 | -| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 241 | -| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | 241 | 242 | -| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | 241 | 242 | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | test.c:10:12:11:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | test.c:7:16:9:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | != | 0 | test.c:7:16:9:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | != | 1 | test.c:10:12:11:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | == | 0 | test.c:10:12:11:14 | { ... } | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | == | 1 | test.c:7:16:9:14 | { ... } | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | test.c:17:17:17:21 | y | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:12 | ... < ... | != | 0 | test.c:17:17:17:21 | y | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:12 | ... < ... | != | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:12 | ... < ... | == | 1 | test.c:17:17:17:21 | y | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:12 | ... < ... | == | 1 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:8 | x | < | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:12 | ... < ... | != | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:12 | ... < ... | == | 1 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:17 | y | >= | 2 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:21 | ... > ... | != | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:21 | ... > ... | == | 1 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:17 | y | >= | 2 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:21 | ... > ... | != | 0 | test.c:18:9:18:14 | ExprStmt | +| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:21 | ... > ... | == | 1 | test.c:18:9:18:14 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:2:5:2:8 | test | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:31:5:34:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:34:16:34:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:34:29:34:26 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:39:5:42:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:42:5:42:26 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:42:16:42:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:42:29:44:16 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:45:23:47:22 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:51:14:53:21 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:56:5:58:14 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:58:19:58:23 | y | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:58:26:66:12 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | test.c:62:9:62:16 | return ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | >= | 1 | test.c:26:18:28:11 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 0 | test.c:26:18:28:11 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:2:5:2:8 | test | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:31:5:34:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:34:16:34:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:34:29:34:26 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:39:5:42:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:42:5:42:26 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:42:16:42:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:42:29:44:16 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:45:23:47:22 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:51:14:53:21 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:56:5:58:14 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:58:19:58:23 | y | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:58:26:66:12 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | != | 1 | test.c:62:9:62:16 | return ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:2:5:2:8 | test | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:31:5:34:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:34:16:34:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:34:29:34:26 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:39:5:42:13 | ExprStmt | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:42:5:42:26 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:42:16:42:21 | j | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:42:29:44:16 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:45:13:45:20 | if (...) ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:45:23:47:22 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:51:14:53:21 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:56:5:58:14 | label ...: | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:58:19:58:23 | y | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:58:26:66:12 | { ... } | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 0 | test.c:62:9:62:16 | return ... | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:15 | ... > ... | == | 1 | test.c:26:18:28:11 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | < | 10 | test.c:34:29:34:26 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:2:5:2:8 | test | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:39:5:42:13 | ExprStmt | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:42:5:42:26 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:42:16:42:21 | j | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:42:29:44:16 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:45:13:45:20 | if (...) ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:45:23:47:22 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:51:14:53:21 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:56:5:58:14 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:58:19:58:23 | y | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:58:26:66:12 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | test.c:62:9:62:16 | return ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 0 | test.c:34:29:34:26 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:2:5:2:8 | test | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:39:5:42:13 | ExprStmt | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:42:5:42:26 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:42:16:42:21 | j | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:42:29:44:16 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:45:23:47:22 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:51:14:53:21 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:56:5:58:14 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:58:19:58:23 | y | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:58:26:66:12 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | != | 1 | test.c:62:9:62:16 | return ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:2:5:2:8 | test | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:39:5:42:13 | ExprStmt | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:42:5:42:26 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:42:16:42:21 | j | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:42:29:44:16 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:45:13:45:20 | if (...) ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:45:23:47:22 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:51:14:53:21 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:56:5:58:14 | label ...: | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:58:19:58:23 | y | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:58:26:66:12 | { ... } | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 0 | test.c:62:9:62:16 | return ... | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:21 | ... < ... | == | 1 | test.c:34:29:34:26 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | test.c:42:5:42:26 | label ...: | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | test.c:42:29:44:16 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | test.c:45:13:45:20 | if (...) ... | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | test.c:45:23:47:22 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | test.c:51:14:53:21 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | test.c:42:5:42:26 | label ...: | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | test.c:42:29:44:16 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | test.c:45:13:45:20 | if (...) ... | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | test.c:45:23:47:22 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | != | 0 | test.c:51:14:53:21 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | test.c:42:5:42:26 | label ...: | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | test.c:42:29:44:16 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | test.c:45:23:47:22 | { ... } | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:21 | ... < ... | == | 1 | test.c:51:14:53:21 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | test.c:42:5:42:26 | label ...: | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | test.c:51:14:53:21 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | test.c:45:23:47:22 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | != | 0 | test.c:45:13:45:20 | if (...) ... | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | != | 0 | test.c:45:23:47:22 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | != | 1 | test.c:42:5:42:26 | label ...: | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | != | 1 | test.c:51:14:53:21 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | == | 0 | test.c:42:5:42:26 | label ...: | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | == | 0 | test.c:51:14:53:21 | { ... } | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | == | 1 | test.c:45:13:45:20 | if (...) ... | +| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:16 | ... > ... | == | 1 | test.c:45:23:47:22 | { ... } | +| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | >= | 1 | test.c:45:23:47:22 | { ... } | +| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:20 | ... > ... | != | 0 | test.c:45:23:47:22 | { ... } | +| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:20 | ... > ... | == | 1 | test.c:45:23:47:22 | { ... } | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | test.c:58:19:58:23 | y | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:14 | ... == ... | != | 1 | test.c:58:19:58:23 | y | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:14 | ... == ... | != | 1 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:14 | ... == ... | == | 0 | test.c:58:19:58:23 | y | +| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:14 | ... == ... | == | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:9 | x | != | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:14 | ... == ... | != | 1 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:14 | ... == ... | == | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:19 | y | >= | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:23 | ... < ... | != | 1 | test.c:62:9:62:16 | return ... | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:23 | ... < ... | == | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:19 | y | >= | 0 | test.c:62:9:62:16 | return ... | +| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:23 | ... < ... | != | 1 | test.c:62:9:62:16 | return ... | +| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:23 | ... < ... | == | 0 | test.c:62:9:62:16 | return ... | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | != | 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | == | 0 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:14 | ... == ... | != | 0 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:14 | ... == ... | != | 1 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:14 | ... == ... | == | 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:14 | ... == ... | == | 1 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:8 | x | != | 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:8 | x | == | 0 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:13 | ... == ... | != | 0 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:13 | ... == ... | != | 1 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:13 | ... == ... | == | 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:14 | ... == ... | test.c:85:8:85:13 | ... == ... | == | 1 | test.c:75:17:77:14 | { ... } | +| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:9 | x | == | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:9 | x | == | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:14 | ... == ... | != | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:14 | ... == ... | != | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:14 | ... == ... | == | 1 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:75:9:75:14 | ... == ... | == | 1 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:13 | ... == ... | != | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:13 | ... == ... | != | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:13 | ... == ... | == | 1 | test.c:85:18:85:23 | y | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:13 | ... == ... | == | 1 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:75:9:75:9 | x | == | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:75:9:75:14 | ... == ... | != | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:75:9:75:14 | ... == ... | == | 1 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:8 | x | == | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:13 | ... == ... | != | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:13 | ... == ... | == | 1 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:18 | y | != | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:23 | ... != ... | != | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:23 | ... != ... | == | 1 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:18 | y | != | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:23 | ... != ... | != | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:23 | ... != ... | == | 1 | test.c:86:9:86:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | != | 0 | test.c:94:19:96:11 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | test.c:70:5:70:9 | test2 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | test.c:99:5:102:13 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | test.c:102:16:102:21 | j | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | test.c:102:29:102:26 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | test.c:107:5:109:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | test.c:109:19:109:23 | y | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | test.c:109:26:117:12 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | test.c:113:9:113:16 | return ... | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 0 | test.c:94:19:96:11 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | test.c:70:5:70:9 | test2 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | test.c:99:5:102:13 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | test.c:102:16:102:21 | j | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | test.c:102:29:102:26 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | test.c:107:5:109:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | test.c:109:19:109:23 | y | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | test.c:109:26:117:12 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | != | 1 | test.c:113:9:113:16 | return ... | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | test.c:70:5:70:9 | test2 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | test.c:99:5:102:13 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | test.c:102:16:102:21 | j | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | test.c:102:29:102:26 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | test.c:107:5:109:14 | ExprStmt | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | test.c:109:19:109:23 | y | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | test.c:109:26:117:12 | { ... } | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 0 | test.c:113:9:113:16 | return ... | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:16 | ... != ... | == | 1 | test.c:94:19:96:11 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | < | 10 | test.c:102:29:102:26 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | test.c:70:5:70:9 | test2 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | test.c:107:5:109:14 | ExprStmt | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | test.c:109:19:109:23 | y | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | test.c:109:26:117:12 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | test.c:113:9:113:16 | return ... | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 0 | test.c:102:29:102:26 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | test.c:70:5:70:9 | test2 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | test.c:107:5:109:14 | ExprStmt | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | test.c:109:19:109:23 | y | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | test.c:109:26:117:12 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | != | 1 | test.c:113:9:113:16 | return ... | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | test.c:70:5:70:9 | test2 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | test.c:107:5:109:14 | ExprStmt | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | test.c:109:19:109:23 | y | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | test.c:109:26:117:12 | { ... } | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 0 | test.c:113:9:113:16 | return ... | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:21 | ... < ... | == | 1 | test.c:102:29:102:26 | { ... } | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | test.c:109:19:109:23 | y | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:14 | ... == ... | != | 1 | test.c:109:19:109:23 | y | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:14 | ... == ... | != | 1 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:14 | ... == ... | == | 0 | test.c:109:19:109:23 | y | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:14 | ... == ... | == | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:14 | ... == ... | != | 1 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:14 | ... == ... | == | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:23 | ... < ... | != | 1 | test.c:113:9:113:16 | return ... | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:23 | ... < ... | == | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | 0 | test.c:113:9:113:16 | return ... | +| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:23 | ... < ... | != | 1 | test.c:113:9:113:16 | return ... | +| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:23 | ... < ... | == | 0 | test.c:113:9:113:16 | return ... | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | test.c:126:12:126:26 | call to test3_condition | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:3:131:7 | if (...) ... | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | test.c:134:1:123:10 | return ... | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:126:12:126:26 | call to test3_condition | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:3:131:7 | if (...) ... | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | test.c:131:10:132:16 | { ... } | +| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | == | 1 | test.c:131:10:132:16 | { ... } | +| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | != | 1 | test.c:142:3:136:10 | return ... | +| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | == | 0 | test.c:142:3:136:10 | return ... | +| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | test.c:146:11:147:9 | { ... } | +| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | == | 1 | test.c:146:11:147:9 | { ... } | +| test.c:146:7:146:8 | ! ... | test.c:146:8:146:8 | x | == | 0 | test.c:146:11:147:9 | { ... } | +| test.c:146:8:146:8 | x | test.c:146:7:146:8 | ! ... | != | 0 | test.c:146:11:147:9 | { ... } | +| test.c:146:8:146:8 | x | test.c:146:7:146:8 | ! ... | == | 1 | test.c:146:11:147:9 | { ... } | +| test.c:146:8:146:8 | x | test.c:146:8:146:8 | x | == | 0 | test.c:146:11:147:9 | { ... } | +| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | != | 0 | test.c:152:11:154:5 | { ... } | +| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | == | 1 | test.c:152:11:154:5 | { ... } | +| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | != | 0 | test.c:158:12:160:5 | { ... } | +| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | == | 1 | test.c:158:12:160:5 | { ... } | +| test.c:158:8:158:9 | ! ... | test.c:158:9:158:9 | p | == | 0 | test.c:158:12:160:5 | { ... } | +| test.c:158:9:158:9 | p | test.c:158:8:158:9 | ! ... | != | 0 | test.c:158:12:160:5 | { ... } | +| test.c:158:9:158:9 | p | test.c:158:8:158:9 | ! ... | == | 1 | test.c:158:12:160:5 | { ... } | +| test.c:158:9:158:9 | p | test.c:158:9:158:9 | p | == | 0 | test.c:158:12:160:5 | { ... } | +| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | != | 0 | test.c:164:11:166:5 | { ... } | +| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | == | 1 | test.c:164:11:166:5 | { ... } | +| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | != | 0 | test.c:170:12:172:5 | { ... } | +| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | == | 1 | test.c:170:12:172:5 | { ... } | +| test.c:170:8:170:9 | ! ... | test.c:170:9:170:9 | s | == | 0 | test.c:170:12:172:5 | { ... } | +| test.c:170:9:170:9 | s | test.c:170:8:170:9 | ! ... | != | 0 | test.c:170:12:172:5 | { ... } | +| test.c:170:9:170:9 | s | test.c:170:8:170:9 | ! ... | == | 1 | test.c:170:12:172:5 | { ... } | +| test.c:170:9:170:9 | s | test.c:170:9:170:9 | s | == | 0 | test.c:170:12:172:5 | { ... } | +| test.c:176:8:176:15 | ! ... | test.c:176:8:176:15 | ! ... | != | 0 | test.c:176:18:178:5 | { ... } | +| test.c:176:8:176:15 | ! ... | test.c:176:8:176:15 | ! ... | == | 1 | test.c:176:18:178:5 | { ... } | +| test.c:176:8:176:15 | ! ... | test.c:176:10:176:14 | ... < ... | == | 0 | test.c:176:18:178:5 | { ... } | +| test.c:176:10:176:14 | ... < ... | test.c:176:8:176:15 | ! ... | != | 0 | test.c:176:18:178:5 | { ... } | +| test.c:176:10:176:14 | ... < ... | test.c:176:8:176:15 | ! ... | == | 1 | test.c:176:18:178:5 | { ... } | +| test.c:176:10:176:14 | ... < ... | test.c:176:10:176:14 | ... < ... | == | 0 | test.c:176:18:178:5 | { ... } | +| test.c:182:8:182:34 | ! ... | test.c:182:8:182:34 | ! ... | != | 0 | test.c:182:37:184:5 | { ... } | +| test.c:182:8:182:34 | ! ... | test.c:182:8:182:34 | ! ... | == | 1 | test.c:182:37:184:5 | { ... } | +| test.c:182:8:182:34 | ! ... | test.c:182:10:182:33 | ... && ... | == | 0 | test.c:182:37:184:5 | { ... } | +| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:20 | ... >= ... | != | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:20 | ... >= ... | != | 0 | test.c:182:25:182:33 | foo | +| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:20 | ... >= ... | == | 1 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:20 | ... >= ... | == | 1 | test.c:182:25:182:33 | foo | +| test.c:182:10:182:33 | ... && ... | test.c:182:8:182:34 | ! ... | != | 0 | test.c:182:37:184:5 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:8:182:34 | ! ... | != | 1 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:8:182:34 | ! ... | == | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:8:182:34 | ! ... | == | 1 | test.c:182:37:184:5 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:20 | ... >= ... | != | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:20 | ... >= ... | == | 1 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:33 | ... && ... | != | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:33 | ... && ... | == | 0 | test.c:182:37:184:5 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:25:182:33 | ... < ... | != | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:10:182:33 | ... && ... | test.c:182:25:182:33 | ... < ... | == | 1 | test.c:181:25:182:20 | { ... } | +| test.c:182:25:182:33 | ... < ... | test.c:182:25:182:33 | ... < ... | != | 0 | test.c:181:25:182:20 | { ... } | +| test.c:182:25:182:33 | ... < ... | test.c:182:25:182:33 | ... < ... | == | 1 | test.c:181:25:182:20 | { ... } | +| test.c:190:7:190:8 | ! ... | test.c:190:7:190:8 | ! ... | != | 0 | test.c:190:11:192:3 | { ... } | +| test.c:190:7:190:8 | ! ... | test.c:190:7:190:8 | ! ... | == | 1 | test.c:190:11:192:3 | { ... } | +| test.c:190:7:190:8 | ! ... | test.c:190:8:190:8 | c | == | 0 | test.c:190:11:192:3 | { ... } | +| test.c:190:8:190:8 | c | test.c:190:7:190:8 | ! ... | != | 0 | test.c:190:11:192:3 | { ... } | +| test.c:190:8:190:8 | c | test.c:190:7:190:8 | ! ... | == | 1 | test.c:190:11:192:3 | { ... } | +| test.c:190:8:190:8 | c | test.c:190:8:190:8 | c | == | 0 | test.c:190:11:192:3 | { ... } | +| test.c:198:7:198:8 | ! ... | test.c:196:11:196:11 | a | < | 11 | test.c:198:11:200:3 | { ... } | +| test.c:198:7:198:8 | ! ... | test.c:198:7:198:8 | ! ... | != | 0 | test.c:198:11:200:3 | { ... } | +| test.c:198:7:198:8 | ! ... | test.c:198:7:198:8 | ! ... | == | 1 | test.c:198:11:200:3 | { ... } | +| test.c:198:7:198:8 | ! ... | test.c:198:8:198:8 | b | == | 0 | test.c:198:11:200:3 | { ... } | +| test.c:198:8:198:8 | b | test.c:196:11:196:11 | a | < | 11 | test.c:198:11:200:3 | { ... } | +| test.c:198:8:198:8 | b | test.c:198:7:198:8 | ! ... | != | 0 | test.c:198:11:200:3 | { ... } | +| test.c:198:8:198:8 | b | test.c:198:7:198:8 | ! ... | == | 1 | test.c:198:11:200:3 | { ... } | +| test.c:198:8:198:8 | b | test.c:198:8:198:8 | b | == | 0 | test.c:198:11:200:3 | { ... } | +| test.c:206:7:206:8 | ! ... | test.c:206:7:206:8 | ! ... | != | 0 | test.c:206:11:208:3 | { ... } | +| test.c:206:7:206:8 | ! ... | test.c:206:7:206:8 | ! ... | == | 1 | test.c:206:11:208:3 | { ... } | +| test.c:206:7:206:8 | ! ... | test.c:206:8:206:8 | c | == | 0 | test.c:206:11:208:3 | { ... } | +| test.c:206:8:206:8 | c | test.c:206:7:206:8 | ! ... | != | 0 | test.c:206:11:208:3 | { ... } | +| test.c:206:8:206:8 | c | test.c:206:7:206:8 | ! ... | == | 1 | test.c:206:11:208:3 | { ... } | +| test.c:206:8:206:8 | c | test.c:206:8:206:8 | c | == | 0 | test.c:206:11:208:3 | { ... } | +| test.c:215:6:215:18 | call to __builtin_expect | test.c:215:6:215:18 | call to __builtin_expect | != | 0 | test.c:215:21:217:5 | { ... } | +| test.c:215:6:215:18 | call to __builtin_expect | test.c:215:6:215:18 | call to __builtin_expect | == | 1 | test.c:215:21:217:5 | { ... } | +| test.c:215:6:215:18 | call to __builtin_expect | test.c:215:13:215:17 | ... > ... | != | 0 | test.c:215:21:217:5 | { ... } | +| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:9:219:22 | call to __builtin_expect | != | 0 | test.c:219:25:221:5 | { ... } | +| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:9:219:22 | call to __builtin_expect | == | 1 | test.c:219:25:221:5 | { ... } | +| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:16:219:16 | a | >= | 43 | test.c:219:25:221:5 | { ... } | +| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:16:219:21 | ... > ... | != | 0 | test.c:219:25:221:5 | { ... } | +| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | test.cpp:19:5:19:14 | ExprStmt | +| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | test.cpp:19:5:19:14 | ExprStmt | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | test.cpp:34:1:34:1 | return ... | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | test.cpp:31:16:32:21 | { ... } | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | test.cpp:31:16:32:21 | { ... } | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | test.cpp:34:1:34:1 | return ... | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | test.cpp:34:1:34:1 | return ... | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | test.cpp:31:16:32:21 | { ... } | +| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | test.cpp:43:9:45:23 | { ... } | +| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | test.cpp:43:9:45:23 | { ... } | +| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 0 | test.cpp:62:5:64:12 | case ...: | +| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 1 | test.cpp:65:5:66:10 | case ...: | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 11 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 21 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 11 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | != | 0 | test.cpp:93:9:94:7 | { ... } | +| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | == | 1 | test.cpp:93:9:94:7 | { ... } | +| test.cpp:99:6:99:6 | f | test.cpp:99:6:99:6 | f | != | 0 | test.cpp:99:9:100:7 | { ... } | +| test.cpp:99:6:99:6 | f | test.cpp:99:6:99:6 | f | == | 1 | test.cpp:99:9:100:7 | { ... } | +| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:14 | ... != ... | != | 0 | test.cpp:105:17:106:7 | { ... } | +| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:14 | ... != ... | == | 1 | test.cpp:105:17:106:7 | { ... } | +| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:14 | ... != ... | != | 0 | test.cpp:111:17:112:7 | { ... } | +| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:14 | ... != ... | == | 1 | test.cpp:111:17:112:7 | { ... } | +| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | != | 0 | test.cpp:123:5:125:20 | { ... } | +| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | != | 0 | test.cpp:125:23:125:29 | return ... | +| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | == | 1 | test.cpp:123:5:125:20 | { ... } | +| test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | == | 1 | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:13:125:20 | ! ... | test.cpp:125:13:125:20 | ! ... | != | 0 | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:13:125:20 | ! ... | test.cpp:125:13:125:20 | ! ... | == | 1 | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:13:125:20 | ! ... | test.cpp:125:14:125:17 | call to safe | != | 1 | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:13:125:20 | ! ... | test.cpp:125:14:125:17 | call to safe | == | 0 | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:14:125:17 | call to safe | test.cpp:125:13:125:20 | ! ... | != | 0 | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:14:125:17 | call to safe | test.cpp:125:13:125:20 | ! ... | == | 1 | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:14:125:17 | call to safe | test.cpp:125:14:125:17 | call to safe | != | 1 | test.cpp:125:23:125:29 | return ... | +| test.cpp:125:14:125:17 | call to safe | test.cpp:125:14:125:17 | call to safe | == | 0 | test.cpp:125:23:125:29 | return ... | +| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:6:131:21 | call to __builtin_expect | != | 0 | test.cpp:131:40:132:9 | { ... } | +| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:6:131:21 | call to __builtin_expect | == | 1 | test.cpp:131:40:132:9 | { ... } | +| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:6:135:21 | call to __builtin_expect | != | 0 | test.cpp:135:40:136:9 | { ... } | +| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:6:135:21 | call to __builtin_expect | == | 1 | test.cpp:135:40:136:9 | { ... } | +| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:6:141:21 | call to __builtin_expect | != | 0 | test.cpp:141:36:142:9 | { ... } | +| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:6:141:21 | call to __builtin_expect | == | 1 | test.cpp:141:36:142:9 | { ... } | +| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:23 | a | == | 42 | test.cpp:141:36:142:9 | { ... } | +| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | != | 0 | test.cpp:145:36:146:9 | { ... } | +| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | == | 1 | test.cpp:145:36:146:9 | { ... } | +| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | 42 | test.cpp:145:36:146:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:8 | a | >= | 10 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:13 | ... < ... | != | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:13 | ... < ... | == | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:152:7:152:8 | ! ... | != | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:152:7:152:8 | ! ... | == | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:152:8:152:8 | b | != | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:7:152:8 | ! ... | test.cpp:152:8:152:8 | b | == | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:151:8:151:8 | a | >= | 10 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:151:8:151:13 | ... < ... | != | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:151:8:151:13 | ... < ... | == | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:152:7:152:8 | ! ... | != | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:152:7:152:8 | ! ... | == | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:152:8:152:8 | b | != | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:152:8:152:8 | b | test.cpp:152:8:152:8 | b | == | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:17 | ... != ... | != | 1 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:17 | ... != ... | == | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:7:160:8 | ! ... | test.cpp:160:7:160:8 | ! ... | != | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:7:160:8 | ! ... | test.cpp:160:7:160:8 | ! ... | == | 1 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:7:160:8 | ! ... | test.cpp:160:8:160:8 | c | != | 1 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:7:160:8 | ! ... | test.cpp:160:8:160:8 | c | == | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | test.cpp:158:12:158:17 | ... != ... | != | 1 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | test.cpp:158:12:158:17 | ... != ... | == | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | test.cpp:160:7:160:8 | ! ... | != | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | test.cpp:160:7:160:8 | ! ... | == | 1 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | test.cpp:160:8:160:8 | c | != | 1 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:160:8:160:8 | c | test.cpp:160:8:160:8 | c | == | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:12 | a | < | 11 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:17 | ... > ... | != | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:17 | ... > ... | == | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:168:7:168:8 | ! ... | != | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:168:7:168:8 | ! ... | == | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:168:8:168:8 | b | != | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:7:168:8 | ! ... | test.cpp:168:8:168:8 | b | == | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:166:12:166:12 | a | < | 11 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:166:12:166:17 | ... > ... | != | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:166:12:166:17 | ... > ... | == | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:168:7:168:8 | ! ... | != | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:168:7:168:8 | ! ... | == | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:168:8:168:8 | b | != | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:168:8:168:8 | b | test.cpp:168:8:168:8 | b | == | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:16 | ... > ... | != | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:16 | ... > ... | == | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | test.cpp:176:7:176:8 | ! ... | != | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | test.cpp:176:7:176:8 | ! ... | == | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | test.cpp:176:8:176:8 | c | != | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:7:176:8 | ! ... | test.cpp:176:8:176:8 | c | == | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | test.cpp:174:12:174:16 | ... > ... | != | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | test.cpp:174:12:174:16 | ... > ... | == | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | test.cpp:176:7:176:8 | ! ... | != | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | test.cpp:176:7:176:8 | ! ... | == | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | != | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | == | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 0 | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 1 | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | != | 1 | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | == | 0 | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | != | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:182:14:182:15 | b2 | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:182:14:182:15 | b2 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 0 | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 1 | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 1 | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 0 | test.cpp:182:19:184:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | != | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | != | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | != | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 1 | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 0 | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 0 | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 1 | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | != | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:193:14:193:15 | b2 | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:193:14:193:15 | b2 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 1 | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 0 | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 0 | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 1 | test.cpp:197:10:199:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | != | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | != | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:10 | sc | == | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:15 | ... == ... | != | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:15 | ... == ... | == | 1 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:10 | sc | == | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:17 | ... == ... | != | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:211:9:211:15 | ... == ... | test.cpp:214:9:214:17 | ... == ... | == | 1 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:10 | sc | == | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:15 | ... == ... | != | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:211:9:211:15 | ... == ... | == | 1 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:10 | sc | == | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:17 | ... == ... | != | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:214:9:214:17 | ... == ... | test.cpp:214:9:214:17 | ... == ... | == | 1 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:10 | ul | == | 0 | test.cpp:217:18:218:13 | { ... } | +| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:15 | ... == ... | != | 0 | test.cpp:217:18:218:13 | { ... } | +| test.cpp:217:9:217:15 | ... == ... | test.cpp:217:9:217:15 | ... == ... | == | 1 | test.cpp:217:18:218:13 | { ... } | +| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:14 | ... == ... | != | 0 | test.cpp:220:17:221:13 | { ... } | +| test.cpp:220:9:220:14 | ... == ... | test.cpp:220:9:220:14 | ... == ... | == | 1 | test.cpp:220:17:221:13 | { ... } | +| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:16 | ... == ... | != | 0 | test.cpp:223:19:224:13 | { ... } | +| test.cpp:223:9:223:16 | ... == ... | test.cpp:223:9:223:16 | ... == ... | == | 1 | test.cpp:223:19:224:13 | { ... } | +| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:14 | ... == ... | != | 0 | test.cpp:226:17:227:13 | { ... } | +| test.cpp:226:9:226:14 | ... == ... | test.cpp:226:9:226:14 | ... == ... | == | 1 | test.cpp:226:17:227:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:9 | b | == | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:14 | ... == ... | != | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:229:9:229:14 | ... == ... | == | 1 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:9 | b | == | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:18 | ... == ... | != | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:229:9:229:14 | ... == ... | test.cpp:232:9:232:18 | ... == ... | == | 1 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:9 | b | == | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:14 | ... == ... | != | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:229:9:229:14 | ... == ... | == | 1 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:9 | b | == | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:18 | ... == ... | != | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:232:9:232:18 | ... == ... | test.cpp:232:9:232:18 | ... == ... | == | 1 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:9:235:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | test.cpp:235:20:236:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | test.cpp:238:20:239:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | test.cpp:238:20:239:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | test.cpp:238:20:239:13 | { ... } | +| test.cpp:238:9:238:17 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | test.cpp:238:20:239:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:17 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:9:241:30 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:235:12:235:12 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:12:241:12 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:9:241:43 | ... && ... | test.cpp:241:38:241:38 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:238:9:238:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:22:241:30 | ... == ... | test.cpp:241:22:241:30 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:9:235:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:9:235:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:235:12:235:12 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:9:241:17 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:9:241:17 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:12:241:12 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:35:241:43 | ... == ... | != | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:35:241:43 | ... == ... | == | 1 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:35:241:43 | ... == ... | test.cpp:241:38:241:38 | i | == | 0 | test.cpp:241:46:242:13 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:6:247:18 | ... == ... | != | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:6:247:18 | ... == ... | != | 1 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:6:247:18 | ... == ... | == | 0 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:6:247:18 | ... == ... | == | 1 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:7:247:12 | ... == ... | != | 0 | test.cpp:249:10:251:3 | { ... } | +| test.cpp:247:6:247:18 | ... == ... | test.cpp:247:7:247:12 | ... == ... | == | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:6:253:18 | ... != ... | != | 0 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:6:253:18 | ... != ... | != | 1 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:6:253:18 | ... != ... | == | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:6:253:18 | ... != ... | == | 1 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:7:253:12 | ... == ... | != | 0 | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:6:253:18 | ... != ... | test.cpp:253:7:253:12 | ... == ... | == | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:6:260:18 | ... == ... | != | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:6:260:18 | ... == ... | != | 1 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:6:260:18 | ... == ... | == | 0 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:6:260:18 | ... == ... | == | 1 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:7:260:12 | ... != ... | != | 0 | test.cpp:262:10:264:3 | { ... } | +| test.cpp:260:6:260:18 | ... == ... | test.cpp:260:7:260:12 | ... != ... | == | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:6:266:18 | ... != ... | != | 0 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:6:266:18 | ... != ... | != | 1 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:6:266:18 | ... != ... | == | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:6:266:18 | ... != ... | == | 1 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:7:266:12 | ... != ... | != | 0 | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:6:266:18 | ... != ... | test.cpp:266:7:266:12 | ... != ... | == | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:6:273:17 | ... == ... | != | 0 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:6:273:17 | ... == ... | != | 1 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:6:273:17 | ... == ... | == | 0 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:6:273:17 | ... == ... | == | 1 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:7:273:11 | ... < ... | != | 0 | test.cpp:275:10:277:3 | { ... } | +| test.cpp:273:6:273:17 | ... == ... | test.cpp:273:7:273:11 | ... < ... | == | 0 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:6:279:17 | ... != ... | != | 0 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:6:279:17 | ... != ... | != | 1 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:6:279:17 | ... != ... | == | 0 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:6:279:17 | ... != ... | == | 1 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:7:279:11 | ... < ... | != | 0 | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:6:279:17 | ... != ... | test.cpp:279:7:279:11 | ... < ... | == | 0 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:6:287:19 | ... == ... | != | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:6:287:19 | ... == ... | != | 1 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:6:287:19 | ... == ... | == | 0 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:6:287:19 | ... == ... | == | 1 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:7:287:7 | a | != | 42 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:7:287:7 | a | == | 42 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:7:287:13 | ... == ... | != | 0 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:287:7:287:13 | ... == ... | == | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:293:7:293:7 | a | != | 42 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:6:287:19 | ... == ... | test.cpp:293:7:293:7 | a | == | 42 | test.cpp:289:10:291:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:287:7:287:7 | a | != | 42 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:287:7:287:7 | a | == | 42 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:6:293:19 | ... != ... | != | 0 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:6:293:19 | ... != ... | != | 1 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:6:293:19 | ... != ... | == | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:6:293:19 | ... != ... | == | 1 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:7:293:7 | a | != | 42 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:7:293:7 | a | == | 42 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:7:293:13 | ... == ... | != | 0 | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:6:293:19 | ... != ... | test.cpp:293:7:293:13 | ... == ... | == | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:6:300:19 | ... == ... | != | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:6:300:19 | ... == ... | != | 1 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:6:300:19 | ... == ... | == | 0 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:6:300:19 | ... == ... | == | 1 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:7:300:7 | a | != | 42 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:7:300:7 | a | == | 42 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:7:300:13 | ... != ... | != | 0 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:300:7:300:13 | ... != ... | == | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:306:7:306:7 | a | != | 42 | test.cpp:302:10:304:3 | { ... } | +| test.cpp:300:6:300:19 | ... == ... | test.cpp:306:7:306:7 | a | == | 42 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:300:7:300:7 | a | != | 42 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:300:7:300:7 | a | == | 42 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:6:306:19 | ... != ... | != | 0 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:6:306:19 | ... != ... | != | 1 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:6:306:19 | ... != ... | == | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:6:306:19 | ... != ... | == | 1 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:7:306:7 | a | != | 42 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:7:306:7 | a | == | 42 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:7:306:13 | ... != ... | != | 0 | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:6:306:19 | ... != ... | test.cpp:306:7:306:13 | ... != ... | == | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:6:312:18 | ... == ... | != | 0 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:6:312:18 | ... == ... | != | 1 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:6:312:18 | ... == ... | == | 0 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:6:312:18 | ... == ... | == | 1 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:7:312:7 | a | < | 42 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:7:312:7 | a | >= | 42 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:7:312:12 | ... < ... | != | 0 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:312:7:312:12 | ... < ... | == | 0 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:318:7:318:7 | a | < | 42 | test.cpp:314:10:316:3 | { ... } | +| test.cpp:312:6:312:18 | ... == ... | test.cpp:318:7:318:7 | a | >= | 42 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:312:7:312:7 | a | < | 42 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:312:7:312:7 | a | >= | 42 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:6:318:18 | ... != ... | != | 0 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:6:318:18 | ... != ... | != | 1 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:6:318:18 | ... != ... | == | 0 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:6:318:18 | ... != ... | == | 1 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:7 | a | < | 42 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:7 | a | >= | 42 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:12 | ... < ... | != | 0 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:12 | ... < ... | == | 0 | test.cpp:320:10:322:3 | { ... } | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql index 59f8a399c6d4..975c1c1ac204 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.ql @@ -8,31 +8,23 @@ import cpp import semmle.code.cpp.controlflow.Guards query predicate binary( - GuardCondition guard, Expr left, string op, Expr right, int k, int start, int end + GuardCondition guard, Expr left, string op, Expr right, int k, BasicBlock block ) { - exists(BasicBlock block | - guard.ensuresLt(left, right, k, block, true) and op = "<" - or - guard.ensuresLt(left, right, k, block, false) and op = ">=" - or - guard.ensuresEq(left, right, k, block, true) and op = "==" - or - guard.ensuresEq(left, right, k, block, false) and op = "!=" - | - block.hasLocationInfo(_, start, _, end, _) - ) + guard.ensuresLt(left, right, k, block, true) and op = "<" + or + guard.ensuresLt(left, right, k, block, false) and op = ">=" + or + guard.ensuresEq(left, right, k, block, true) and op = "==" + or + guard.ensuresEq(left, right, k, block, false) and op = "!=" } -query predicate unary(GuardCondition guard, Expr left, string op, int k, int start, int end) { - exists(BasicBlock block | - guard.ensuresLt(left, k, block, true) and op = "<" - or - guard.ensuresLt(left, k, block, false) and op = ">=" - or - guard.ensuresEq(left, k, block, true) and op = "==" - or - guard.ensuresEq(left, k, block, false) and op = "!=" - | - block.hasLocationInfo(_, start, _, end, _) - ) +query predicate unary(GuardCondition guard, Expr left, string op, int k, BasicBlock block) { + guard.ensuresLt(left, k, block, true) and op = "<" + or + guard.ensuresLt(left, k, block, false) and op = ">=" + or + guard.ensuresEq(left, k, block, true) and op = "==" + or + guard.ensuresEq(left, k, block, false) and op = "!=" } diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.c b/cpp/ql/test/library-tests/controlflow/guards/test.c index d453b0d643ca..beb3d8d60f5b 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.c +++ b/cpp/ql/test/library-tests/controlflow/guards/test.c @@ -206,4 +206,17 @@ void test14(int a, int b) { if (!c) { } -} \ No newline at end of file +} + +# define likely(x) __builtin_expect(!!(x), 1) + +void test15(int a, int b) +{ + if (likely(a > b)) { + + } + + if (likely(a > 42)) { + + } +} diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.cpp b/cpp/ql/test/library-tests/controlflow/guards/test.cpp index e2dd5477b545..2ef61734e69a 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.cpp +++ b/cpp/ql/test/library-tests/controlflow/guards/test.cpp @@ -242,3 +242,82 @@ int test_types(signed char sc, unsigned long ul, float f, double d, bool b, Myst ctr++; } } + +void test_cmp_implies(int a, int b) { + if((a == b) == 0) { + + } else { + + } + + if((a == b) != 0) { + + } else { + + } + + + if((a != b) == 0) { + + } else { + + } + + if((a != b) != 0) { + + } else { + + } + + + if((a < b) == 0) { + + } else { + + } + + if((a < b) != 0) { + + } else { + + } +} + +void test_cmp_implies_unary(int a) { + if((a == 42) == 0) { + + } else { + + } + + if((a == 42) != 0) { + + } else { + + } + + + if((a != 42) == 0) { + + } else { + + } + + if((a != 42) != 0) { + + } else { + + } + + if((a < 42) == 0) { + + } else { + + } + + if((a < 42) != 0) { + + } else { + + } +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index 9abcd6eeee78..cb25f1a21e39 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -43,6 +43,10 @@ argHasPostUpdate | test.cpp:813:19:813:35 | * ... | ArgumentNode is missing PostUpdateNode. | | test.cpp:848:23:848:25 | rpx | ArgumentNode is missing PostUpdateNode. | | test.cpp:1093:19:1093:21 | * ... | ArgumentNode is missing PostUpdateNode. | +| test.cpp:1206:19:1206:37 | * ... | ArgumentNode is missing PostUpdateNode. | +| test.cpp:1207:10:1207:28 | * ... | ArgumentNode is missing PostUpdateNode. | +| test.cpp:1224:19:1224:37 | * ... | ArgumentNode is missing PostUpdateNode. | +| test.cpp:1225:10:1225:28 | * ... | ArgumentNode is missing PostUpdateNode. | postWithInFlow | BarrierGuard.cpp:49:6:49:6 | x [post update] | PostUpdateNode should not be the target of local flow. | | BarrierGuard.cpp:60:7:60:7 | x [post update] | PostUpdateNode should not be the target of local flow. | @@ -193,6 +197,10 @@ postWithInFlow | test.cpp:1139:4:1139:7 | data [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:1153:5:1153:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:1153:6:1153:6 | p [inner post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:1165:5:1165:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:1165:6:1165:6 | p [inner post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:1195:5:1195:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:1195:6:1195:6 | p [inner post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition uniqueParameterNodePosition diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index 323ce2a43121..6e0b03be9c61 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -134,6 +134,11 @@ astFlow | test.cpp:1086:12:1086:12 | a | test.cpp:1088:8:1088:9 | & ... | | test.cpp:1137:7:1137:10 | data | test.cpp:1140:8:1140:18 | * ... | | test.cpp:1138:17:1138:22 | call to source | test.cpp:1140:8:1140:18 | * ... | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1170:19:1170:32 | global_int_ptr | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1234:19:1234:34 | global_int_array | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1239:10:1239:26 | * ... | +| test.cpp:1195:10:1195:24 | call to indirect_source | test.cpp:1200:19:1200:36 | global_int_ptr_ptr | +| test.cpp:1195:10:1195:24 | call to indirect_source | test.cpp:1201:10:1201:27 | global_int_ptr_ptr | | 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 | @@ -327,6 +332,20 @@ irFlow | test.cpp:1117:27:1117:34 | call to source | test.cpp:1117:27:1117:34 | call to source | | test.cpp:1132:11:1132:16 | call to source | test.cpp:1121:8:1121:8 | x | | test.cpp:1138:17:1138:22 | call to source | test.cpp:1140:8:1140:18 | * ... | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1170:19:1170:32 | *global_int_ptr | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1175:10:1175:24 | * ... | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1184:19:1184:32 | *global_int_ptr | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1189:10:1189:24 | * ... | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1234:19:1234:34 | *global_int_array | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1239:10:1239:26 | * ... | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1248:19:1248:34 | *global_int_array | +| test.cpp:1165:10:1165:15 | call to source | test.cpp:1253:10:1253:26 | * ... | +| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1200:19:1200:36 | **global_int_ptr_ptr | +| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1206:19:1206:37 | ** ... | +| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1209:10:1209:29 | * ... | +| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1218:19:1218:36 | **global_int_ptr_ptr | +| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1224:19:1224:37 | ** ... | +| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1227:10:1227:29 | * ... | | true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x | | true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x | | true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index b804159d8583..35e6a074cfd0 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -1155,4 +1155,101 @@ namespace conflation_regression { } } -int recursion = (sink(recursion), source()); // clean \ No newline at end of file +int recursion = (sink(recursion), source()); // clean + + +namespace globals_without_explicit_def { + int* global_int_ptr; + + void set(int* p) { // $ ast-def=p ir-def=*p + *p = source(); + } + + void test1() { + set(global_int_ptr); + indirect_sink(global_int_ptr); // $ ir,ast + } + + void test2() { + set(global_int_ptr); + sink(*global_int_ptr); // $ ir MISSING: ast + } + + void calls_set() { + set(global_int_ptr); + } + + void test3() { + calls_set(); + indirect_sink(global_int_ptr); // $ ir MISSING: ast + } + + void test4() { + calls_set(); + sink(*global_int_ptr); // $ ir MISSING: ast + } + + int** global_int_ptr_ptr; + + void set_indirect(int** p) { // $ ast-def=p ir-def=*p ir-def=**p + *p = indirect_source(); + } + + void test5() { + set_indirect(global_int_ptr_ptr); + indirect_sink(global_int_ptr_ptr); // $ ir,ast + sink(global_int_ptr_ptr); // $ SPURIOUS: ast + } + + void test6() { + set_indirect(global_int_ptr_ptr); + indirect_sink(*global_int_ptr_ptr); // $ ir MISSING: ast + sink(*global_int_ptr_ptr); + indirect_sink(**global_int_ptr_ptr); + sink(**global_int_ptr_ptr); // $ ir + } + + void calls_set_indirect() { + set_indirect(global_int_ptr_ptr); + } + + void test7() { + calls_set_indirect(); + indirect_sink(global_int_ptr_ptr); // $ ir MISSING: ast + sink(global_int_ptr_ptr); // $ MISSING: ast + } + + void test8() { + calls_set_indirect(); + indirect_sink(*global_int_ptr_ptr); // $ ir MISSING: ast + sink(*global_int_ptr_ptr); + indirect_sink(**global_int_ptr_ptr); + sink(**global_int_ptr_ptr); // $ ir MISSING: ast + } + + int global_int_array[10]; + + void test9() { + set(global_int_array); + indirect_sink(global_int_array); // $ ir,ast + } + + void test10() { + set(global_int_array); + sink(*global_int_array); // $ ir,ast + } + + void calls_set_array() { + set(global_int_array); + } + + void test11() { + calls_set_array(); + indirect_sink(global_int_array); // $ ir MISSING: ast + } + + void test12() { + calls_set_array(); + sink(*global_int_array); // $ ir MISSING: ast + } +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index bf9a4ed28d01..b1f984680ad6 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -21,14 +21,22 @@ models | 20 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual | | 21 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual | | 22 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual | -| 23 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual | -| 24 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual | -| 25 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated | -| 26 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual | -| 27 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual | -| 28 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual | +| 23 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual | +| 24 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual | +| 25 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual | +| 26 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual | +| 27 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual | +| 28 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual | +| 29 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual | +| 30 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual | +| 31 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual | +| 32 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual | +| 33 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated | +| 34 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual | +| 35 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual | +| 36 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual | edges -| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:28 | +| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:36 | | asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:17 | | asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:17 Sink:MaD:2 | | asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction | @@ -37,10 +45,10 @@ edges | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | | | asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 | | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | | -| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:28 | -| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:26 | -| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:25 | -| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:27 | +| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:36 | +| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:34 | +| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:33 | +| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:35 | | test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | | | test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | | | test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:16 | @@ -52,15 +60,15 @@ edges | test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | | | test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | | -| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:26 | +| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:34 | | test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | | | test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 | | test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | | -| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:25 | +| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:33 | | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | | | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 | | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | | -| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:27 | +| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:35 | | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | | | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | | @@ -68,16 +76,16 @@ edges | test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | | | test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | | | test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 | -| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:24 | +| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:32 | | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | | | test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | | | test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | | | test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:16 | | test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | | -| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 | -| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 | -| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 | -| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 | +| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 | +| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 | +| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 | +| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 | | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | | | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | | | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | | @@ -180,6 +188,59 @@ edges | windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | provenance | | | windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | provenance | | | windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | provenance | | +| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:27 | +| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:23 | +| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:24 | +| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:25 | +| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | provenance | | +| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:26 | +| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | provenance | | +| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | provenance | | +| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:29 | +| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:30 | +| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:28 | +| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | provenance | | +| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | provenance | | +| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | | +| windows.cpp:533:11:533:16 | call to source | windows.cpp:537:40:537:41 | *& ... | provenance | | +| windows.cpp:533:11:533:16 | call to source | windows.cpp:542:38:542:39 | *& ... | provenance | | +| windows.cpp:533:11:533:16 | call to source | windows.cpp:547:32:547:33 | *& ... | provenance | | +| windows.cpp:533:11:533:16 | call to source | windows.cpp:552:43:552:44 | *& ... | provenance | | +| windows.cpp:533:11:533:16 | call to source | windows.cpp:568:32:568:33 | *& ... | provenance | | +| windows.cpp:533:11:533:16 | call to source | windows.cpp:573:40:573:41 | *& ... | provenance | | +| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | windows.cpp:538:10:538:23 | access to array | provenance | | +| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | provenance | | +| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:27 | +| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | windows.cpp:543:10:543:23 | access to array | provenance | | +| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | provenance | | +| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:23 | +| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | windows.cpp:548:10:548:23 | access to array | provenance | | +| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | provenance | | +| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:24 | +| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | windows.cpp:553:10:553:23 | access to array | provenance | | +| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | provenance | | +| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:25 | +| windows.cpp:559:5:559:24 | ... = ... | windows.cpp:561:39:561:44 | *buffer | provenance | | +| windows.cpp:559:17:559:24 | call to source | windows.cpp:559:5:559:24 | ... = ... | provenance | | +| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:562:10:562:19 | *src_string [*Buffer] | provenance | | +| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:563:40:563:50 | *& ... [*Buffer] | provenance | | +| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | provenance | | +| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:28 | +| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:10:562:29 | access to array | provenance | | +| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:21:562:26 | *Buffer | provenance | | +| windows.cpp:562:21:562:26 | *Buffer | windows.cpp:562:10:562:29 | access to array | provenance | | +| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | windows.cpp:564:10:564:20 | *dest_string [*Buffer] | provenance | | +| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | provenance | | +| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:26 | +| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:10:564:30 | access to array | provenance | | +| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:22:564:27 | *Buffer | provenance | | +| windows.cpp:564:22:564:27 | *Buffer | windows.cpp:564:10:564:30 | access to array | provenance | | +| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | windows.cpp:569:10:569:23 | access to array | provenance | | +| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | provenance | | +| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:29 | +| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | windows.cpp:574:10:574:23 | access to array | provenance | | +| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | provenance | | +| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:30 | nodes | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer | | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer | @@ -352,6 +413,59 @@ nodes | windows.cpp:439:7:439:8 | *& ... [x] | semmle.label | *& ... [x] | | windows.cpp:451:7:451:8 | *& ... [x] | semmle.label | *& ... [x] | | windows.cpp:464:7:464:8 | *& ... [x] | semmle.label | *& ... [x] | +| windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | semmle.label | [summary param] *0 in RtlCopyVolatileMemory [Return] | +| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | semmle.label | [summary param] *1 in RtlCopyVolatileMemory | +| windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | semmle.label | [summary param] *0 in RtlCopyDeviceMemory [Return] | +| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | semmle.label | [summary param] *1 in RtlCopyDeviceMemory | +| windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | semmle.label | [summary param] *0 in RtlCopyMemory [Return] | +| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | semmle.label | [summary param] *1 in RtlCopyMemory | +| windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | semmle.label | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | +| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | semmle.label | [summary param] *1 in RtlCopyMemoryNonTemporal | +| windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | semmle.label | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | +| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | semmle.label | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | +| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | semmle.label | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | +| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | semmle.label | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | +| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | semmle.label | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | +| windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | semmle.label | [summary param] *0 in RtlMoveMemory [Return] | +| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | semmle.label | [summary param] *1 in RtlMoveMemory | +| windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | semmle.label | [summary param] *0 in RtlMoveVolatileMemory [Return] | +| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | semmle.label | [summary param] *1 in RtlMoveVolatileMemory | +| windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | semmle.label | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | +| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | semmle.label | [summary param] *1 in RtlInitUnicodeString | +| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | semmle.label | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | +| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | semmle.label | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | +| windows.cpp:533:11:533:16 | call to source | semmle.label | call to source | +| windows.cpp:533:11:533:16 | call to source | semmle.label | call to source | +| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | semmle.label | RtlCopyVolatileMemory output argument | +| windows.cpp:537:40:537:41 | *& ... | semmle.label | *& ... | +| windows.cpp:538:10:538:23 | access to array | semmle.label | access to array | +| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | semmle.label | RtlCopyDeviceMemory output argument | +| windows.cpp:542:38:542:39 | *& ... | semmle.label | *& ... | +| windows.cpp:543:10:543:23 | access to array | semmle.label | access to array | +| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | semmle.label | RtlCopyMemory output argument | +| windows.cpp:547:32:547:33 | *& ... | semmle.label | *& ... | +| windows.cpp:548:10:548:23 | access to array | semmle.label | access to array | +| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | semmle.label | RtlCopyMemoryNonTemporal output argument | +| windows.cpp:552:43:552:44 | *& ... | semmle.label | *& ... | +| windows.cpp:553:10:553:23 | access to array | semmle.label | access to array | +| windows.cpp:559:5:559:24 | ... = ... | semmle.label | ... = ... | +| windows.cpp:559:17:559:24 | call to source | semmle.label | call to source | +| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | semmle.label | RtlInitUnicodeString output argument [*Buffer] | +| windows.cpp:561:39:561:44 | *buffer | semmle.label | *buffer | +| windows.cpp:562:10:562:19 | *src_string [*Buffer] | semmle.label | *src_string [*Buffer] | +| windows.cpp:562:10:562:29 | access to array | semmle.label | access to array | +| windows.cpp:562:21:562:26 | *Buffer | semmle.label | *Buffer | +| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | semmle.label | RtlCopyUnicodeString output argument [*Buffer] | +| windows.cpp:563:40:563:50 | *& ... [*Buffer] | semmle.label | *& ... [*Buffer] | +| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | semmle.label | *dest_string [*Buffer] | +| windows.cpp:564:10:564:30 | access to array | semmle.label | access to array | +| windows.cpp:564:22:564:27 | *Buffer | semmle.label | *Buffer | +| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | semmle.label | RtlMoveMemory output argument | +| windows.cpp:568:32:568:33 | *& ... | semmle.label | *& ... | +| windows.cpp:569:10:569:23 | access to array | semmle.label | access to array | +| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | semmle.label | RtlMoveVolatileMemory output argument | +| windows.cpp:573:40:573:41 | *& ... | semmle.label | *& ... | +| windows.cpp:574:10:574:23 | access to array | semmle.label | access to array | subpaths | asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer | | test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | @@ -359,4 +473,12 @@ subpaths | test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | | test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | | windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | +| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | +| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | +| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | +| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | +| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | +| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | +| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | +| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | testFailures diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected index 6fdbe067e171..aeb2362ef339 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected @@ -5556,12 +5556,24 @@ | Dubious signature "(z_streamp,int *)" in summary model. | | Dubious signature "(z_streamp,unsigned int *,int *)" in summary model. | | Dubious signature "(z_streamp,unsigned int)" in summary model. | +| Unrecognized input specification "Argument[***0]" in summary model. | +| Unrecognized input specification "Argument[***1]" in summary model. | | Unrecognized input specification "Argument[***3]" in summary model. | | Unrecognized input specification "Argument[***4]" in summary model. | +| Unrecognized input specification "Argument[****0]" in summary model. | +| Unrecognized input specification "Argument[****1]" in summary model. | | Unrecognized input specification "Argument[****3]" in summary model. | | Unrecognized input specification "Argument[****4]" in summary model. | +| Unrecognized input specification "Argument[*****0]" in summary model. | +| Unrecognized input specification "Argument[*****1]" in summary model. | | Unrecognized input specification "Field[****hEvent]" in summary model. | | Unrecognized input specification "Field[***hEvent]" in summary model. | +| Unrecognized output specification "Argument[***0]" in summary model. | +| Unrecognized output specification "Argument[***1]" in summary model. | +| Unrecognized output specification "Argument[****0]" in summary model. | +| Unrecognized output specification "Argument[****1]" in summary model. | +| Unrecognized output specification "Argument[*****0]" in summary model. | +| Unrecognized output specification "Argument[*****1]" in summary model. | | Unrecognized output specification "Field[****hEvent]" in summary model. | | Unrecognized output specification "Field[***hEvent]" in summary model. | | Unrecognized output specification "Parameter[***0]" in summary model. | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp index 2554dc9fd46c..3e03c1a69a5b 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp +++ b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp @@ -466,4 +466,111 @@ void test_create_thread() &attrList, &threadId); } +} + +using size_t = decltype(sizeof(0)); + +volatile void * RtlCopyVolatileMemory( + volatile void *Destination, + volatile const void *Source, + size_t Length +); + +volatile void * RtlCopyDeviceMemory( + volatile void *Destination, + volatile const void *Source, + size_t Length +); + +void RtlCopyMemory( + void* Destination, + const void* Source, + size_t Length +); + +using VOID = void; + +VOID RtlCopyMemoryNonTemporal( + VOID *Destination, + const VOID *Source, + SIZE_T Length +); + +using USHORT = unsigned short; +using PWSTR = wchar_t*; +using PCWSTR = const wchar_t*; +using PCUNICODE_STRING = const struct _UNICODE_STRING*; + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING, *PUNICODE_STRING; + +VOID RtlCopyUnicodeString( + PUNICODE_STRING DestinationString, + PCUNICODE_STRING SourceString +); + +void RtlMoveMemory( + void* Destination, + const void* Source, + size_t Length +); + +volatile void * RtlMoveVolatileMemory( + volatile void *Destination, + volatile const void *Source, + size_t Length +); + +void RtlInitUnicodeString( + PUNICODE_STRING DestinationString, + PCWSTR SourceString +); + +void test_copy_and_move_memory() { + int x = source(); + + { + char dest_buffer[1024]; + RtlCopyVolatileMemory(dest_buffer, &x, sizeof(x)); + sink(dest_buffer[0]); // $ ir + } + { + char dest_buffer[1024]; + RtlCopyDeviceMemory(dest_buffer, &x, sizeof(x)); + sink(dest_buffer[0]); // $ ir + } + { + char dest_buffer[1024]; + RtlCopyMemory(dest_buffer, &x, sizeof(x)); + sink(dest_buffer[0]); // $ ir + } + { + char dest_buffer[1024]; + RtlCopyMemoryNonTemporal(dest_buffer, &x, sizeof(x)); + sink(dest_buffer[0]); // $ ir + } + { + UNICODE_STRING dest_string; + UNICODE_STRING src_string; + wchar_t buffer[1024]; + buffer[0] = source(); + + RtlInitUnicodeString(&src_string, buffer); + sink(src_string.Buffer[0]); // $ ir + RtlCopyUnicodeString(&dest_string, &src_string); + sink(dest_string.Buffer[0]); // $ ir + } + { + char dest_buffer[1024]; + RtlMoveMemory(dest_buffer, &x, sizeof(x)); + sink(dest_buffer[0]); // $ ir + } + { + volatile char dest_buffer[1024]; + RtlMoveVolatileMemory(dest_buffer, &x, sizeof(x)); + sink(dest_buffer[0]); // $ ir + } } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/fields/aliasing.cpp b/cpp/ql/test/library-tests/dataflow/fields/aliasing.cpp index 71bfc62b3ba2..bf5e941cc3bb 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/aliasing.cpp +++ b/cpp/ql/test/library-tests/dataflow/fields/aliasing.cpp @@ -204,4 +204,65 @@ void deep_member_field_arrow(S2 *ps2) { void deep_member_field_arrow_different_fields(S2 *ps2) { taint_a_ptr(&ps2->s.m1); sink(ps2->s.m2); +} + + +namespace GlobalFieldFlow { + S global_s; + S2 global_s2; + + void set_field() { + global_s.m1 = user_input(); + } + + void read_field() { + sink(global_s.m1); // $ ir MISSING: ast + } + + void set_nested_field() { + global_s2.s.m1 = user_input(); + } + + void read_nested_field() { + sink(global_s2.s.m1); // $ ir MISSING: ast + } + + S* global_s_ptr; + S2* global_s2_ptr; + + void set_field_ptr() { + global_s_ptr->m1 = user_input(); + } + + void read_field_ptr() { + sink(global_s_ptr->m1); // $ ir MISSING: ast + } + + void set_nested_field_ptr() { + global_s2_ptr->s.m1 = user_input(); + } + + void read_nested_field_ptr() { + sink(global_s2_ptr->s.m1); // $ ir MISSING: ast + } + + S_with_pointer global_s_with_pointer; + + void set_field_indirect() { + *global_s_with_pointer.data = user_input(); + } + + void read_field_indirect() { + sink(*global_s_with_pointer.data); // $ ir MISSING: ast + } + + S_with_array global_s_with_array; + + void set_field_array() { + *global_s_with_array.data = user_input(); + } + + void read_field_array() { + sink(*global_s_with_array.data); // $ ir MISSING: ast + } } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected index 29daff363033..88dd9751f27e 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected @@ -95,6 +95,14 @@ postWithInFlow | aliasing.cpp:194:21:194:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. | | aliasing.cpp:200:23:200:24 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. | | aliasing.cpp:205:23:205:24 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. | +| aliasing.cpp:215:14:215:15 | m1 [post update] | PostUpdateNode should not be the target of local flow. | +| aliasing.cpp:223:17:223:18 | m1 [post update] | PostUpdateNode should not be the target of local flow. | +| aliasing.cpp:234:19:234:20 | m1 [post update] | PostUpdateNode should not be the target of local flow. | +| aliasing.cpp:242:22:242:23 | m1 [post update] | PostUpdateNode should not be the target of local flow. | +| aliasing.cpp:252:5:252:31 | * ... [post update] | PostUpdateNode should not be the target of local flow. | +| aliasing.cpp:252:28:252:31 | data [inner post update] | PostUpdateNode should not be the target of local flow. | +| aliasing.cpp:262:5:262:29 | * ... [post update] | PostUpdateNode should not be the target of local flow. | +| aliasing.cpp:262:26:262:29 | data [inner post update] | PostUpdateNode should not be the target of local flow. | | arrays.cpp:6:3:6:5 | arr [inner post update] | PostUpdateNode should not be the target of local flow. | | arrays.cpp:6:3:6:8 | access to array [post update] | PostUpdateNode should not be the target of local flow. | | arrays.cpp:15:3:15:10 | * ... [post update] | PostUpdateNode should not be the target of local flow. | diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected index 6852a5dd3cd4..bf725830b323 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected @@ -346,6 +346,46 @@ edges | aliasing.cpp:200:21:200:21 | *s [post update] [m1] | aliasing.cpp:200:16:200:18 | *ps2 [post update] [s, m1] | provenance | | | aliasing.cpp:201:8:201:10 | *ps2 [s, m1] | aliasing.cpp:201:13:201:13 | *s [m1] | provenance | | | aliasing.cpp:201:13:201:13 | *s [m1] | aliasing.cpp:201:15:201:16 | m1 | provenance | | +| aliasing.cpp:211:5:211:12 | *global_s [m1] | aliasing.cpp:211:5:211:12 | *global_s [m1] | provenance | | +| aliasing.cpp:211:5:211:12 | *global_s [m1] | aliasing.cpp:219:10:219:17 | *global_s [m1] | provenance | | +| aliasing.cpp:212:6:212:14 | *global_s2 [s, m1] | aliasing.cpp:212:6:212:14 | *global_s2 [s, m1] | provenance | | +| aliasing.cpp:212:6:212:14 | *global_s2 [s, m1] | aliasing.cpp:227:10:227:18 | *global_s2 [s, m1] | provenance | | +| aliasing.cpp:215:5:215:12 | *global_s [post update] [m1] | aliasing.cpp:211:5:211:12 | *global_s [m1] | provenance | | +| aliasing.cpp:215:5:215:30 | ... = ... | aliasing.cpp:215:5:215:12 | *global_s [post update] [m1] | provenance | | +| aliasing.cpp:215:19:215:28 | call to user_input | aliasing.cpp:215:5:215:30 | ... = ... | provenance | | +| aliasing.cpp:219:10:219:17 | *global_s [m1] | aliasing.cpp:219:19:219:20 | m1 | provenance | | +| aliasing.cpp:223:5:223:13 | *global_s2 [post update] [s, m1] | aliasing.cpp:212:6:212:14 | *global_s2 [s, m1] | provenance | | +| aliasing.cpp:223:5:223:33 | ... = ... | aliasing.cpp:223:15:223:15 | *s [post update] [m1] | provenance | | +| aliasing.cpp:223:15:223:15 | *s [post update] [m1] | aliasing.cpp:223:5:223:13 | *global_s2 [post update] [s, m1] | provenance | | +| aliasing.cpp:223:22:223:31 | call to user_input | aliasing.cpp:223:5:223:33 | ... = ... | provenance | | +| aliasing.cpp:227:10:227:18 | *global_s2 [s, m1] | aliasing.cpp:227:20:227:20 | *s [m1] | provenance | | +| aliasing.cpp:227:20:227:20 | *s [m1] | aliasing.cpp:227:22:227:23 | m1 | provenance | | +| aliasing.cpp:230:6:230:17 | **global_s_ptr [m1] | aliasing.cpp:230:6:230:17 | **global_s_ptr [m1] | provenance | | +| aliasing.cpp:230:6:230:17 | **global_s_ptr [m1] | aliasing.cpp:238:10:238:21 | *global_s_ptr [m1] | provenance | | +| aliasing.cpp:231:7:231:19 | **global_s2_ptr [s, m1] | aliasing.cpp:231:7:231:19 | **global_s2_ptr [s, m1] | provenance | | +| aliasing.cpp:231:7:231:19 | **global_s2_ptr [s, m1] | aliasing.cpp:246:10:246:22 | *global_s2_ptr [s, m1] | provenance | | +| aliasing.cpp:234:5:234:16 | *global_s_ptr [post update] [m1] | aliasing.cpp:230:6:230:17 | **global_s_ptr [m1] | provenance | | +| aliasing.cpp:234:5:234:35 | ... = ... | aliasing.cpp:234:5:234:16 | *global_s_ptr [post update] [m1] | provenance | | +| aliasing.cpp:234:24:234:33 | call to user_input | aliasing.cpp:234:5:234:35 | ... = ... | provenance | | +| aliasing.cpp:238:10:238:21 | *global_s_ptr [m1] | aliasing.cpp:238:24:238:25 | m1 | provenance | | +| aliasing.cpp:242:5:242:17 | *global_s2_ptr [post update] [s, m1] | aliasing.cpp:231:7:231:19 | **global_s2_ptr [s, m1] | provenance | | +| aliasing.cpp:242:5:242:38 | ... = ... | aliasing.cpp:242:20:242:20 | *s [post update] [m1] | provenance | | +| aliasing.cpp:242:20:242:20 | *s [post update] [m1] | aliasing.cpp:242:5:242:17 | *global_s2_ptr [post update] [s, m1] | provenance | | +| aliasing.cpp:242:27:242:36 | call to user_input | aliasing.cpp:242:5:242:38 | ... = ... | provenance | | +| aliasing.cpp:246:10:246:22 | *global_s2_ptr [s, m1] | aliasing.cpp:246:25:246:25 | *s [m1] | provenance | | +| aliasing.cpp:246:25:246:25 | *s [m1] | aliasing.cpp:246:27:246:28 | m1 | provenance | | +| aliasing.cpp:249:18:249:38 | *global_s_with_pointer [*data] | aliasing.cpp:249:18:249:38 | *global_s_with_pointer [*data] | provenance | | +| aliasing.cpp:249:18:249:38 | *global_s_with_pointer [*data] | aliasing.cpp:256:11:256:31 | *global_s_with_pointer [*data] | provenance | | +| aliasing.cpp:252:5:252:46 | ... = ... | aliasing.cpp:252:6:252:26 | *global_s_with_pointer [post update] [*data] | provenance | | +| aliasing.cpp:252:6:252:26 | *global_s_with_pointer [post update] [*data] | aliasing.cpp:249:18:249:38 | *global_s_with_pointer [*data] | provenance | | +| aliasing.cpp:252:35:252:44 | call to user_input | aliasing.cpp:252:5:252:46 | ... = ... | provenance | | +| aliasing.cpp:256:11:256:31 | *global_s_with_pointer [*data] | aliasing.cpp:256:10:256:36 | * ... | provenance | | +| aliasing.cpp:259:16:259:34 | *global_s_with_array [data] | aliasing.cpp:259:16:259:34 | *global_s_with_array [data] | provenance | | +| aliasing.cpp:259:16:259:34 | *global_s_with_array [data] | aliasing.cpp:266:11:266:29 | *global_s_with_array [data] | provenance | | +| aliasing.cpp:262:5:262:44 | ... = ... | aliasing.cpp:262:6:262:24 | *global_s_with_array [post update] [data] | provenance | | +| aliasing.cpp:262:6:262:24 | *global_s_with_array [post update] [data] | aliasing.cpp:259:16:259:34 | *global_s_with_array [data] | provenance | | +| aliasing.cpp:262:33:262:42 | call to user_input | aliasing.cpp:262:5:262:44 | ... = ... | provenance | | +| aliasing.cpp:266:11:266:29 | *global_s_with_array [data] | aliasing.cpp:266:10:266:34 | * ... | provenance | | | arrays.cpp:6:3:6:23 | ... = ... | arrays.cpp:7:8:7:13 | access to array | provenance | | | arrays.cpp:6:3:6:23 | ... = ... | arrays.cpp:8:8:8:13 | access to array | provenance | | | arrays.cpp:6:3:6:23 | ... = ... | arrays.cpp:9:8:9:11 | * ... | provenance | | @@ -1244,6 +1284,46 @@ nodes | aliasing.cpp:201:8:201:10 | *ps2 [s, m1] | semmle.label | *ps2 [s, m1] | | aliasing.cpp:201:13:201:13 | *s [m1] | semmle.label | *s [m1] | | aliasing.cpp:201:15:201:16 | m1 | semmle.label | m1 | +| aliasing.cpp:211:5:211:12 | *global_s [m1] | semmle.label | *global_s [m1] | +| aliasing.cpp:212:6:212:14 | *global_s2 [s, m1] | semmle.label | *global_s2 [s, m1] | +| aliasing.cpp:215:5:215:12 | *global_s [post update] [m1] | semmle.label | *global_s [post update] [m1] | +| aliasing.cpp:215:5:215:30 | ... = ... | semmle.label | ... = ... | +| aliasing.cpp:215:19:215:28 | call to user_input | semmle.label | call to user_input | +| aliasing.cpp:219:10:219:17 | *global_s [m1] | semmle.label | *global_s [m1] | +| aliasing.cpp:219:19:219:20 | m1 | semmle.label | m1 | +| aliasing.cpp:223:5:223:13 | *global_s2 [post update] [s, m1] | semmle.label | *global_s2 [post update] [s, m1] | +| aliasing.cpp:223:5:223:33 | ... = ... | semmle.label | ... = ... | +| aliasing.cpp:223:15:223:15 | *s [post update] [m1] | semmle.label | *s [post update] [m1] | +| aliasing.cpp:223:22:223:31 | call to user_input | semmle.label | call to user_input | +| aliasing.cpp:227:10:227:18 | *global_s2 [s, m1] | semmle.label | *global_s2 [s, m1] | +| aliasing.cpp:227:20:227:20 | *s [m1] | semmle.label | *s [m1] | +| aliasing.cpp:227:22:227:23 | m1 | semmle.label | m1 | +| aliasing.cpp:230:6:230:17 | **global_s_ptr [m1] | semmle.label | **global_s_ptr [m1] | +| aliasing.cpp:231:7:231:19 | **global_s2_ptr [s, m1] | semmle.label | **global_s2_ptr [s, m1] | +| aliasing.cpp:234:5:234:16 | *global_s_ptr [post update] [m1] | semmle.label | *global_s_ptr [post update] [m1] | +| aliasing.cpp:234:5:234:35 | ... = ... | semmle.label | ... = ... | +| aliasing.cpp:234:24:234:33 | call to user_input | semmle.label | call to user_input | +| aliasing.cpp:238:10:238:21 | *global_s_ptr [m1] | semmle.label | *global_s_ptr [m1] | +| aliasing.cpp:238:24:238:25 | m1 | semmle.label | m1 | +| aliasing.cpp:242:5:242:17 | *global_s2_ptr [post update] [s, m1] | semmle.label | *global_s2_ptr [post update] [s, m1] | +| aliasing.cpp:242:5:242:38 | ... = ... | semmle.label | ... = ... | +| aliasing.cpp:242:20:242:20 | *s [post update] [m1] | semmle.label | *s [post update] [m1] | +| aliasing.cpp:242:27:242:36 | call to user_input | semmle.label | call to user_input | +| aliasing.cpp:246:10:246:22 | *global_s2_ptr [s, m1] | semmle.label | *global_s2_ptr [s, m1] | +| aliasing.cpp:246:25:246:25 | *s [m1] | semmle.label | *s [m1] | +| aliasing.cpp:246:27:246:28 | m1 | semmle.label | m1 | +| aliasing.cpp:249:18:249:38 | *global_s_with_pointer [*data] | semmle.label | *global_s_with_pointer [*data] | +| aliasing.cpp:252:5:252:46 | ... = ... | semmle.label | ... = ... | +| aliasing.cpp:252:6:252:26 | *global_s_with_pointer [post update] [*data] | semmle.label | *global_s_with_pointer [post update] [*data] | +| aliasing.cpp:252:35:252:44 | call to user_input | semmle.label | call to user_input | +| aliasing.cpp:256:10:256:36 | * ... | semmle.label | * ... | +| aliasing.cpp:256:11:256:31 | *global_s_with_pointer [*data] | semmle.label | *global_s_with_pointer [*data] | +| aliasing.cpp:259:16:259:34 | *global_s_with_array [data] | semmle.label | *global_s_with_array [data] | +| aliasing.cpp:262:5:262:44 | ... = ... | semmle.label | ... = ... | +| aliasing.cpp:262:6:262:24 | *global_s_with_array [post update] [data] | semmle.label | *global_s_with_array [post update] [data] | +| aliasing.cpp:262:33:262:42 | call to user_input | semmle.label | call to user_input | +| aliasing.cpp:266:10:266:34 | * ... | semmle.label | * ... | +| aliasing.cpp:266:11:266:29 | *global_s_with_array [data] | semmle.label | *global_s_with_array [data] | | arrays.cpp:6:3:6:23 | ... = ... | semmle.label | ... = ... | | arrays.cpp:6:12:6:21 | call to user_input | semmle.label | call to user_input | | arrays.cpp:7:8:7:13 | access to array | semmle.label | access to array | @@ -1902,6 +1982,12 @@ subpaths | aliasing.cpp:176:13:176:14 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:176:13:176:14 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input | | aliasing.cpp:189:15:189:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:189:15:189:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input | | aliasing.cpp:201:15:201:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:201:15:201:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input | +| aliasing.cpp:219:19:219:20 | m1 | aliasing.cpp:215:19:215:28 | call to user_input | aliasing.cpp:219:19:219:20 | m1 | m1 flows from $@ | aliasing.cpp:215:19:215:28 | call to user_input | call to user_input | +| aliasing.cpp:227:22:227:23 | m1 | aliasing.cpp:223:22:223:31 | call to user_input | aliasing.cpp:227:22:227:23 | m1 | m1 flows from $@ | aliasing.cpp:223:22:223:31 | call to user_input | call to user_input | +| aliasing.cpp:238:24:238:25 | m1 | aliasing.cpp:234:24:234:33 | call to user_input | aliasing.cpp:238:24:238:25 | m1 | m1 flows from $@ | aliasing.cpp:234:24:234:33 | call to user_input | call to user_input | +| aliasing.cpp:246:27:246:28 | m1 | aliasing.cpp:242:27:242:36 | call to user_input | aliasing.cpp:246:27:246:28 | m1 | m1 flows from $@ | aliasing.cpp:242:27:242:36 | call to user_input | call to user_input | +| aliasing.cpp:256:10:256:36 | * ... | aliasing.cpp:252:35:252:44 | call to user_input | aliasing.cpp:256:10:256:36 | * ... | * ... flows from $@ | aliasing.cpp:252:35:252:44 | call to user_input | call to user_input | +| aliasing.cpp:266:10:266:34 | * ... | aliasing.cpp:262:33:262:42 | call to user_input | aliasing.cpp:266:10:266:34 | * ... | * ... flows from $@ | aliasing.cpp:262:33:262:42 | call to user_input | call to user_input | | arrays.cpp:7:8:7:13 | access to array | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array | access to array flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input | | arrays.cpp:8:8:8:13 | access to array | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array | access to array flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input | | arrays.cpp:9:8:9:11 | * ... | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... | * ... flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input | diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected index 91b22f8d13ad..8137e350d853 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected @@ -141,6 +141,20 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (par | aliasing.cpp:201:13:201:13 | s | IR only | | aliasing.cpp:206:8:206:10 | ps2 | IR only | | aliasing.cpp:206:13:206:13 | s | IR only | +| aliasing.cpp:215:14:215:15 | m1 | AST only | +| aliasing.cpp:219:10:219:17 | global_s | IR only | +| aliasing.cpp:223:17:223:18 | m1 | AST only | +| aliasing.cpp:227:10:227:18 | global_s2 | IR only | +| aliasing.cpp:227:20:227:20 | s | IR only | +| aliasing.cpp:234:19:234:20 | m1 | AST only | +| aliasing.cpp:238:10:238:21 | global_s_ptr | IR only | +| aliasing.cpp:242:22:242:23 | m1 | AST only | +| aliasing.cpp:246:10:246:22 | global_s2_ptr | IR only | +| aliasing.cpp:246:25:246:25 | s | IR only | +| aliasing.cpp:252:5:252:31 | * ... | AST only | +| aliasing.cpp:256:11:256:31 | global_s_with_pointer | IR only | +| aliasing.cpp:262:5:262:29 | * ... | AST only | +| aliasing.cpp:266:11:266:29 | global_s_with_array | IR only | | arrays.cpp:6:3:6:8 | access to array | AST only | | arrays.cpp:7:8:7:13 | access to array | IR only | | arrays.cpp:7:8:7:13 | access to array | IR only | diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected index c12cc3c3c0f4..8df575d8e167 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected @@ -285,6 +285,22 @@ | aliasing.cpp:205:21:205:21 | s | | aliasing.cpp:206:8:206:10 | ps2 | | aliasing.cpp:206:13:206:13 | s | +| aliasing.cpp:215:5:215:12 | global_s | +| aliasing.cpp:219:10:219:17 | global_s | +| aliasing.cpp:223:5:223:13 | global_s2 | +| aliasing.cpp:223:15:223:15 | s | +| aliasing.cpp:227:10:227:18 | global_s2 | +| aliasing.cpp:227:20:227:20 | s | +| aliasing.cpp:234:5:234:16 | global_s_ptr | +| aliasing.cpp:238:10:238:21 | global_s_ptr | +| aliasing.cpp:242:5:242:17 | global_s2_ptr | +| aliasing.cpp:242:20:242:20 | s | +| aliasing.cpp:246:10:246:22 | global_s2_ptr | +| aliasing.cpp:246:25:246:25 | s | +| aliasing.cpp:252:6:252:26 | global_s_with_pointer | +| aliasing.cpp:256:11:256:31 | global_s_with_pointer | +| aliasing.cpp:262:6:262:24 | global_s_with_array | +| aliasing.cpp:266:11:266:29 | global_s_with_array | | arrays.cpp:7:8:7:13 | access to array | | arrays.cpp:8:8:8:13 | access to array | | arrays.cpp:9:8:9:11 | * ... | diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected index 00e84906b6cc..397e069c1669 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected @@ -225,6 +225,20 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (par | aliasing.cpp:205:15:205:24 | & ... | | aliasing.cpp:205:16:205:18 | ps2 | | aliasing.cpp:205:21:205:21 | s | +| aliasing.cpp:215:5:215:12 | global_s | +| aliasing.cpp:215:14:215:15 | m1 | +| aliasing.cpp:223:5:223:13 | global_s2 | +| aliasing.cpp:223:15:223:15 | s | +| aliasing.cpp:223:17:223:18 | m1 | +| aliasing.cpp:234:5:234:16 | global_s_ptr | +| aliasing.cpp:234:19:234:20 | m1 | +| aliasing.cpp:242:5:242:17 | global_s2_ptr | +| aliasing.cpp:242:20:242:20 | s | +| aliasing.cpp:242:22:242:23 | m1 | +| aliasing.cpp:252:5:252:31 | * ... | +| aliasing.cpp:252:6:252:26 | global_s_with_pointer | +| aliasing.cpp:262:5:262:29 | * ... | +| aliasing.cpp:262:6:262:24 | global_s_with_array | | arrays.cpp:6:3:6:8 | access to array | | arrays.cpp:15:3:15:10 | * ... | | arrays.cpp:36:3:36:3 | o | diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index a3ee6b46bd53..6e62071e7d97 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -4932,7 +4932,20 @@ ir.c: # 103| Type = [IntType] int # 103| ValueCategory = prvalue(load) # 103| getThen(): [BlockStmt] { ... } -# 104| getStmt(16): [ReturnStmt] return ... +# 105| getStmt(16): [DeclStmt] declaration +# 105| getDeclarationEntry(0): [VariableDeclarationEntry] definition of double_negation +# 105| Type = [IntType] int +# 105| getVariable().getInitializer(): [Initializer] initializer for double_negation +# 105| getExpr(): [NotExpr] ! ... +# 105| Type = [IntType] int +# 105| ValueCategory = prvalue +# 105| getOperand(): [NotExpr] ! ... +# 105| Type = [IntType] int +# 105| ValueCategory = prvalue +# 105| getOperand(): [VariableAccess] x1 +# 105| Type = [IntType] int +# 105| ValueCategory = prvalue(load) +# 106| getStmt(17): [ReturnStmt] return ... ir.cpp: # 1| [TopLevelFunction] void Constants() # 1| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 6d58656b55ff..6bf6801a48bd 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -3706,9 +3706,10 @@ ir.c: # 88| r88_3(int) = Load[x1] : &:r88_2, m84_6 # 88| r88_4(int) = Constant[0] : # 88| r88_5(bool) = CompareEQ : r88_3, r88_4 -# 88| m88_6(int) = Store[y] : &:r88_1, r88_5 +# 88| r88_6(int) = Convert : r88_5 +# 88| m88_7(int) = Store[y] : &:r88_1, r88_6 # 89| r89_1(glval) = VariableAddress[y] : -# 89| r89_2(int) = Load[y] : &:r89_1, m88_6 +# 89| r89_2(int) = Load[y] : &:r89_1, m88_7 # 89| r89_3(int) = Constant[0] : # 89| r89_4(bool) = CompareNE : r89_2, r89_3 # 89| v89_5(void) = ConditionalBranch : r89_4 @@ -3721,7 +3722,7 @@ ir.c: # 90| Block 6 # 90| r90_1(glval) = VariableAddress[y] : -# 90| r90_2(int) = Load[y] : &:r90_1, m88_6 +# 90| r90_2(int) = Load[y] : &:r90_1, m88_7 # 90| r90_3(int) = Constant[0] : # 90| r90_4(bool) = CompareEQ : r90_2, r90_3 # 90| v90_5(void) = ConditionalBranch : r90_4 @@ -3969,11 +3970,19 @@ ir.c: # 103| v103_6(void) = NoOp : #-----| Goto -> Block 40 -# 104| Block 40 -# 104| v104_1(void) = NoOp : -# 84| v84_9(void) = ReturnVoid : -# 84| v84_10(void) = AliasedUse : m84_3 -# 84| v84_11(void) = ExitFunction : +# 105| Block 40 +# 105| r105_1(glval) = VariableAddress[double_negation] : +# 105| r105_2(glval) = VariableAddress[x1] : +# 105| r105_3(int) = Load[x1] : &:r105_2, m84_6 +# 105| r105_4(int) = Constant[0] : +# 105| r105_5(bool) = CompareEQ : r105_3, r105_4 +# 105| r105_6(bool) = LogicalNot : r105_5 +# 105| r105_7(int) = Convert : r105_6 +# 105| m105_8(int) = Store[double_negation] : &:r105_1, r105_7 +# 106| v106_1(void) = NoOp : +# 84| v84_9(void) = ReturnVoid : +# 84| v84_10(void) = AliasedUse : m84_3 +# 84| v84_11(void) = ExitFunction : ir.cpp: # 1| void Constants() diff --git a/cpp/ql/test/library-tests/ir/ir/ir.c b/cpp/ql/test/library-tests/ir/ir/ir.c index 6e5b37743044..1d11ec6b596a 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.c +++ b/cpp/ql/test/library-tests/ir/ir/ir.c @@ -101,6 +101,8 @@ void branch_on_integral_in_c(int x1, int x2) { int x_1_and_2 = x1 && x2; if(x_1_and_2) {} if(!x_1_and_2) {} + + int double_negation = !!x1; } // semmle-extractor-options: --microsoft diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 8cdb5e8c351f..bf4cef8c3f49 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -3343,7 +3343,8 @@ ir.c: # 88| r88_3(int) = Load[x1] : &:r88_2, ~m? # 88| r88_4(int) = Constant[0] : # 88| r88_5(bool) = CompareEQ : r88_3, r88_4 -# 88| mu88_6(int) = Store[y] : &:r88_1, r88_5 +# 88| r88_6(int) = Convert : r88_5 +# 88| mu88_7(int) = Store[y] : &:r88_1, r88_6 # 89| r89_1(glval) = VariableAddress[y] : # 89| r89_2(int) = Load[y] : &:r89_1, ~m? # 89| r89_3(int) = Constant[0] : @@ -3605,11 +3606,19 @@ ir.c: # 103| v103_6(void) = NoOp : #-----| Goto -> Block 40 -# 104| Block 40 -# 104| v104_1(void) = NoOp : -# 84| v84_8(void) = ReturnVoid : -# 84| v84_9(void) = AliasedUse : ~m? -# 84| v84_10(void) = ExitFunction : +# 105| Block 40 +# 105| r105_1(glval) = VariableAddress[double_negation] : +# 105| r105_2(glval) = VariableAddress[x1] : +# 105| r105_3(int) = Load[x1] : &:r105_2, ~m? +# 105| r105_4(int) = Constant[0] : +# 105| r105_5(bool) = CompareEQ : r105_3, r105_4 +# 105| r105_6(bool) = LogicalNot : r105_5 +# 105| r105_7(int) = Convert : r105_6 +# 105| mu105_8(int) = Store[double_negation] : &:r105_1, r105_7 +# 106| v106_1(void) = NoOp : +# 84| v84_8(void) = ReturnVoid : +# 84| v84_9(void) = AliasedUse : ~m? +# 84| v84_10(void) = ExitFunction : ir.cpp: # 1| void Constants() diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected index ecf31ac87019..4688c5b75285 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected @@ -1145,3 +1145,43 @@ test.cpp: # 152| v152_7(void) = ReturnVoid : # 152| v152_8(void) = AliasedUse : ~m156_7 # 152| v152_9(void) = ExitFunction : + +# 166| void test_constMemberFunction() +# 166| Block 0 +# 166| v166_1(void) = EnterFunction : +# 166| m166_2(unknown) = AliasedDefinition : +# 166| valnum = unique +# 166| m166_3(unknown) = InitializeNonLocal : +# 166| valnum = unique +# 166| m166_4(unknown) = Chi : total:m166_2, partial:m166_3 +# 166| valnum = unique +# 167| r167_1(glval) = VariableAddress[s] : +# 167| valnum = r167_1, r168_2, r169_1, r169_2 +# 167| m167_2(StructWithConstMemberFunction) = Uninitialized[s] : &:r167_1 +# 167| valnum = m167_2, m168_4, r168_3 +# 167| m167_3(unknown) = Chi : total:m166_4, partial:m167_2 +# 167| valnum = unique +# 168| r168_1(glval) = VariableAddress[s2] : +# 168| valnum = unique +# 168| r168_2(glval) = VariableAddress[s] : +# 168| valnum = r167_1, r168_2, r169_1, r169_2 +# 168| r168_3(StructWithConstMemberFunction) = Load[s] : &:r168_2, m167_2 +# 168| valnum = m167_2, m168_4, r168_3 +# 168| m168_4(StructWithConstMemberFunction) = Store[s2] : &:r168_1, r168_3 +# 168| valnum = m167_2, m168_4, r168_3 +# 169| r169_1(glval) = VariableAddress[s] : +# 169| valnum = r167_1, r168_2, r169_1, r169_2 +# 169| r169_2(glval) = Convert : r169_1 +# 169| valnum = r167_1, r168_2, r169_1, r169_2 +# 169| r169_3(glval) = FunctionAddress[constMemberFunction] : +# 169| valnum = unique +# 169| v169_4(void) = Call[constMemberFunction] : func:r169_3, this:r169_2 +# 169| m169_5(unknown) = ^CallSideEffect : ~m167_3 +# 169| valnum = unique +# 169| m169_6(unknown) = Chi : total:m167_3, partial:m169_5 +# 169| valnum = unique +# 169| v169_7(void) = ^IndirectReadSideEffect[-1] : &:r169_2, ~m169_6 +# 170| v170_1(void) = NoOp : +# 166| v166_5(void) = ReturnVoid : +# 166| v166_6(void) = AliasedUse : ~m169_6 +# 166| v166_7(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp index dfef91006e38..ed98bad30578 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/test.cpp @@ -156,4 +156,15 @@ void test_read_global_different(int n) { global_a->y = n; int d = global_a->x; +} + +struct StructWithConstMemberFunction { + int x; + void constMemberFunction() const; +}; + +void test_constMemberFunction() { + StructWithConstMemberFunction s; + StructWithConstMemberFunction s2 = s; + s.constMemberFunction(); } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/SloppyGlobal.expected b/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/SloppyGlobal.expected index 692f7d81cd6c..ceccd95ea3c4 100644 --- a/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/SloppyGlobal.expected +++ b/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/SloppyGlobal.expected @@ -1,2 +1,7 @@ | main.cpp:3:5:3:5 | x | Poor global variable name 'x'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | | main.cpp:4:5:4:6 | ys | Poor global variable name 'ys'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | +| main.cpp:9:5:9:6 | v1 | Poor global variable name 'v1'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | +| main.cpp:10:5:10:6 | v2 | Poor global variable name 'v2'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | +| main.cpp:12:5:12:5 | v3 | Poor global variable name 'v3'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | +| main.cpp:14:5:14:5 | v4 | Poor global variable name 'v4'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | +| main.cpp:16:5:16:5 | v5 | Poor global variable name 'v5'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | diff --git a/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/main.cpp b/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/main.cpp index 1b1b7ee0280b..e279fbf02579 100644 --- a/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/main.cpp +++ b/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/main.cpp @@ -5,3 +5,19 @@ int ys[1000000]; // BAD: too short int descriptive_name; // GOOD: sufficient static int z; // GOOD: not a global + +int v1; // BAD: too short +int v2; // BAD: too short +template +T v3; // BAD: too short +template +T v4; // BAD: too short +template +T v5; // BAD: too short + +void use_some_fs() { + v2 = 100; + v4 = 200; + v5 = 300; + v5 = "string"; +} diff --git a/cpp/ql/test/query-tests/Critical/InitialisationNotRun/InitialisationNotRun.expected b/cpp/ql/test/query-tests/Critical/InitialisationNotRun/InitialisationNotRun.expected new file mode 100644 index 000000000000..fdb53a2a4689 --- /dev/null +++ b/cpp/ql/test/query-tests/Critical/InitialisationNotRun/InitialisationNotRun.expected @@ -0,0 +1,2 @@ +| test.cpp:12:16:12:17 | g1 | Initialization code for 'g1' is never run. | +| test.cpp:14:23:14:24 | g3 | Initialization code for 'g3' is never run. | diff --git a/cpp/ql/test/query-tests/Critical/InitialisationNotRun/InitialisationNotRun.qlref b/cpp/ql/test/query-tests/Critical/InitialisationNotRun/InitialisationNotRun.qlref new file mode 100644 index 000000000000..7012169e8945 --- /dev/null +++ b/cpp/ql/test/query-tests/Critical/InitialisationNotRun/InitialisationNotRun.qlref @@ -0,0 +1 @@ +Critical/InitialisationNotRun.ql diff --git a/cpp/ql/test/query-tests/Critical/InitialisationNotRun/test.cpp b/cpp/ql/test/query-tests/Critical/InitialisationNotRun/test.cpp new file mode 100644 index 000000000000..ee0d070df088 --- /dev/null +++ b/cpp/ql/test/query-tests/Critical/InitialisationNotRun/test.cpp @@ -0,0 +1,36 @@ +// --- stubs --- + +char *strcpy(char *dest, const char *src); + +// --- tests --- + +class GlobalStorage { +public: + char name[1000]; +}; + +GlobalStorage *g1; // BAD +static GlobalStorage g2; // GOOD +static GlobalStorage *g3; // BAD +// static variables are initialized by compilers +static int a; // GOOD +static int b = 0; // GOOD + +void init() { //initializes g_storage, but is never run from main + g1 = new GlobalStorage(); + g3 = new GlobalStorage(); +} + +void init2(int b) { + for (int i = 0; i < b; ++i) + a *= -1; +} + +int main(int argc, char *argv[]) { + //init not called + strcpy(g1->name, argv[1]); // g1 is used before init() is called + strcpy(g2.name, argv[1]); // g2 is initialised by compiler + strcpy(g3->name, argv[1]); + b++; + return 0; +} diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected index 1edf3b1ae99f..6dfe60dcb8ca 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected @@ -1,4 +1,5 @@ edges +| test.c:10:31:10:32 | sscanf output argument | test.c:11:7:11:7 | x | provenance | | | test.cpp:34:15:34:16 | scanf output argument | test.cpp:35:7:35:7 | i | provenance | | | test.cpp:41:19:41:20 | scanf output argument | test.cpp:43:8:43:8 | i | provenance | | | test.cpp:58:19:58:20 | scanf output argument | test.cpp:60:8:60:8 | i | provenance | | @@ -56,6 +57,8 @@ edges | test.cpp:567:35:567:36 | scanf output argument | test.cpp:569:9:569:9 | i | provenance | | | test.cpp:575:30:575:31 | scanf output argument | test.cpp:577:9:577:9 | i | provenance | | nodes +| test.c:10:31:10:32 | sscanf output argument | semmle.label | sscanf output argument | +| test.c:11:7:11:7 | x | semmle.label | x | | test.cpp:34:15:34:16 | scanf output argument | semmle.label | scanf output argument | | test.cpp:35:7:35:7 | i | semmle.label | i | | test.cpp:41:19:41:20 | scanf output argument | semmle.label | scanf output argument | @@ -186,5 +189,3 @@ subpaths | test.cpp:484:9:484:9 | i | test.cpp:480:25:480:26 | scanf output argument | test.cpp:484:9:484:9 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:480:13:480:17 | call to scanf | call to scanf | | test.cpp:495:8:495:8 | i | test.cpp:491:25:491:26 | scanf output argument | test.cpp:495:8:495:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:491:13:491:17 | call to scanf | call to scanf | | test.cpp:545:8:545:8 | f | test.cpp:541:43:541:44 | sscanf output argument | test.cpp:545:8:545:8 | f | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 3. | test.cpp:541:10:541:15 | call to sscanf | call to sscanf | -| test.cpp:569:9:569:9 | i | test.cpp:567:35:567:36 | scanf output argument | test.cpp:569:9:569:9 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:567:23:567:27 | call to scanf | call to scanf | -| test.cpp:577:9:577:9 | i | test.cpp:575:30:575:31 | scanf output argument | test.cpp:577:9:577:9 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:575:18:575:22 | call to scanf | call to scanf | diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.c b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.c new file mode 100644 index 000000000000..dd1836949ff0 --- /dev/null +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.c @@ -0,0 +1,13 @@ +# define likely(x) __builtin_expect(!!(x), 1) +int sscanf(const char *s, const char *format, ...); + +void use(int i); + +void test_likely(const char* s, const char* format) +{ + int x; + + if (likely(sscanf(s, format, &x) == 1)) { + use(x); // GOOD + } +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp index 9cfad40a1480..92f5d10ddd9e 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp @@ -566,7 +566,7 @@ void test_scanf_compared_in_conjunct_right(bool b) { int i; bool success = b && scanf("%d", &i) == 1; if(success) { - use(i); // GOOD [FALSE POSITIVE] + use(i); // GOOD } } @@ -574,6 +574,6 @@ void test_scanf_compared_in_conjunct_left(bool b) { int i; bool success = scanf("%d", &i) == 1 && b; if(success) { - use(i); // GOOD [FALSE POSITIVE] + use(i); // GOOD } } diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/StrncpyFlippedArgs/StrncpyFlippedArgs.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/StrncpyFlippedArgs/StrncpyFlippedArgs.expected index 1fe46acbdde6..19fe89a78c16 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/StrncpyFlippedArgs/StrncpyFlippedArgs.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/StrncpyFlippedArgs/StrncpyFlippedArgs.expected @@ -13,7 +13,6 @@ | test.cpp:49:2:49:9 | call to strcpy_s | Potentially unsafe call to strcpy_s; second argument should be size of destination. | | test.cpp:62:3:62:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. | | test.cpp:65:3:65:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. | -| test.cpp:70:2:70:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. | | test.cpp:81:3:81:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. | | test.cpp:84:3:84:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. | | test.cpp:105:2:105:10 | call to wcsxfrm_l | Potentially unsafe call to wcsxfrm_l; third argument should be size of destination. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected index 2f24a9a27cb5..3a2b7372831d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected @@ -12,19 +12,6 @@ edges | test.cpp:42:13:42:15 | *str [string] | test.cpp:42:18:42:23 | string | provenance | | | test.cpp:72:17:72:19 | *str [string] | test.cpp:72:22:72:27 | string | provenance | | | test.cpp:80:17:80:19 | *str [string] | test.cpp:80:22:80:27 | string | provenance | | -| test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | provenance | | -| test.cpp:90:5:90:7 | *str [post update] [string] | test.cpp:91:5:91:7 | *str [string] | provenance | | -| test.cpp:90:5:90:34 | ... = ... | test.cpp:90:5:90:7 | *str [post update] [string] | provenance | | -| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... | provenance | | -| test.cpp:91:5:91:7 | *str [string] | test.cpp:92:12:92:14 | *str [string] | provenance | | -| test.cpp:92:12:92:14 | *str [string] | test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | provenance | | -| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | provenance | | -| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:99:13:99:15 | *str [string] | provenance | | -| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:129:17:129:19 | *str [string] | provenance | | -| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:137:17:137:19 | *str [string] | provenance | | -| test.cpp:99:13:99:15 | *str [string] | test.cpp:99:18:99:23 | string | provenance | | -| test.cpp:129:17:129:19 | *str [string] | test.cpp:129:22:129:27 | string | provenance | | -| test.cpp:137:17:137:19 | *str [string] | test.cpp:137:22:137:27 | string | provenance | | | test.cpp:147:5:147:7 | *str [post update] [string] | test.cpp:148:5:148:7 | *str [string] | provenance | | | test.cpp:147:5:147:34 | ... = ... | test.cpp:147:5:147:7 | *str [post update] [string] | provenance | | | test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... | provenance | | @@ -46,12 +33,6 @@ edges | test.cpp:199:17:199:19 | *str [string] | test.cpp:199:22:199:27 | string | provenance | | | test.cpp:203:17:203:19 | *str [string] | test.cpp:203:22:203:27 | string | provenance | | | test.cpp:207:17:207:19 | *str [string] | test.cpp:207:22:207:27 | string | provenance | | -| test.cpp:214:24:214:24 | p | test.cpp:216:10:216:10 | p | provenance | | -| test.cpp:220:27:220:54 | call to malloc | test.cpp:220:27:220:54 | call to malloc | provenance | | -| test.cpp:220:27:220:54 | call to malloc | test.cpp:222:15:222:20 | buffer | provenance | | -| test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p | provenance | | -| test.cpp:228:27:228:54 | call to malloc | test.cpp:228:27:228:54 | call to malloc | provenance | | -| test.cpp:228:27:228:54 | call to malloc | test.cpp:232:10:232:15 | buffer | provenance | | | test.cpp:235:40:235:45 | buffer | test.cpp:236:5:236:26 | ... = ... | provenance | | | test.cpp:236:5:236:9 | *p_str [post update] [string] | test.cpp:235:27:235:31 | *p_str [Return] [string] | provenance | | | test.cpp:236:5:236:9 | *p_str [post update] [string] | test.cpp:235:27:235:31 | *p_str [string] | provenance | | @@ -64,8 +45,6 @@ edges | test.cpp:243:12:243:14 | *str [string] | test.cpp:243:12:243:21 | string | provenance | | | test.cpp:249:14:249:33 | call to my_alloc | test.cpp:249:14:249:33 | call to my_alloc | provenance | | | test.cpp:249:14:249:33 | call to my_alloc | test.cpp:250:12:250:12 | p | provenance | | -| test.cpp:256:5:256:25 | ... = ... | test.cpp:257:12:257:12 | p | provenance | | -| test.cpp:256:9:256:25 | call to malloc | test.cpp:256:5:256:25 | ... = ... | provenance | | | test.cpp:262:15:262:30 | call to malloc | test.cpp:262:15:262:30 | call to malloc | provenance | | | test.cpp:262:15:262:30 | call to malloc | test.cpp:266:12:266:12 | p | provenance | | | test.cpp:264:9:264:30 | ... = ... | test.cpp:266:12:266:12 | p | provenance | | @@ -85,20 +64,6 @@ nodes | test.cpp:72:22:72:27 | string | semmle.label | string | | test.cpp:80:17:80:19 | *str [string] | semmle.label | *str [string] | | test.cpp:80:22:80:27 | string | semmle.label | string | -| test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | semmle.label | **mk_string_t_plus_one [string] | -| test.cpp:90:5:90:7 | *str [post update] [string] | semmle.label | *str [post update] [string] | -| test.cpp:90:5:90:34 | ... = ... | semmle.label | ... = ... | -| test.cpp:90:19:90:24 | call to malloc | semmle.label | call to malloc | -| test.cpp:91:5:91:7 | *str [string] | semmle.label | *str [string] | -| test.cpp:92:12:92:14 | *str [string] | semmle.label | *str [string] | -| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | semmle.label | *call to mk_string_t_plus_one [string] | -| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | semmle.label | *call to mk_string_t_plus_one [string] | -| test.cpp:99:13:99:15 | *str [string] | semmle.label | *str [string] | -| test.cpp:99:18:99:23 | string | semmle.label | string | -| test.cpp:129:17:129:19 | *str [string] | semmle.label | *str [string] | -| test.cpp:129:22:129:27 | string | semmle.label | string | -| test.cpp:137:17:137:19 | *str [string] | semmle.label | *str [string] | -| test.cpp:137:22:137:27 | string | semmle.label | string | | test.cpp:147:5:147:7 | *str [post update] [string] | semmle.label | *str [post update] [string] | | test.cpp:147:5:147:34 | ... = ... | semmle.label | ... = ... | | test.cpp:147:19:147:24 | call to malloc | semmle.label | call to malloc | @@ -121,14 +86,6 @@ nodes | test.cpp:203:22:203:27 | string | semmle.label | string | | test.cpp:207:17:207:19 | *str [string] | semmle.label | *str [string] | | test.cpp:207:22:207:27 | string | semmle.label | string | -| test.cpp:214:24:214:24 | p | semmle.label | p | -| test.cpp:216:10:216:10 | p | semmle.label | p | -| test.cpp:220:27:220:54 | call to malloc | semmle.label | call to malloc | -| test.cpp:220:27:220:54 | call to malloc | semmle.label | call to malloc | -| test.cpp:222:15:222:20 | buffer | semmle.label | buffer | -| test.cpp:228:27:228:54 | call to malloc | semmle.label | call to malloc | -| test.cpp:228:27:228:54 | call to malloc | semmle.label | call to malloc | -| test.cpp:232:10:232:15 | buffer | semmle.label | buffer | | test.cpp:235:27:235:31 | *p_str [Return] [string] | semmle.label | *p_str [Return] [string] | | test.cpp:235:27:235:31 | *p_str [string] | semmle.label | *p_str [string] | | test.cpp:235:40:235:45 | buffer | semmle.label | buffer | @@ -143,9 +100,6 @@ nodes | test.cpp:249:14:249:33 | call to my_alloc | semmle.label | call to my_alloc | | test.cpp:249:14:249:33 | call to my_alloc | semmle.label | call to my_alloc | | test.cpp:250:12:250:12 | p | semmle.label | p | -| test.cpp:256:5:256:25 | ... = ... | semmle.label | ... = ... | -| test.cpp:256:9:256:25 | call to malloc | semmle.label | call to malloc | -| test.cpp:257:12:257:12 | p | semmle.label | p | | test.cpp:262:15:262:30 | call to malloc | semmle.label | call to malloc | | test.cpp:262:15:262:30 | call to malloc | semmle.label | call to malloc | | test.cpp:264:9:264:30 | ... = ... | semmle.label | ... = ... | @@ -158,9 +112,6 @@ subpaths | test.cpp:42:5:42:11 | call to strncpy | test.cpp:18:19:18:24 | call to malloc | test.cpp:42:18:42:23 | string | This write may overflow $@ by 1 element. | test.cpp:42:18:42:23 | string | string | | test.cpp:72:9:72:15 | call to strncpy | test.cpp:18:19:18:24 | call to malloc | test.cpp:72:22:72:27 | string | This write may overflow $@ by 1 element. | test.cpp:72:22:72:27 | string | string | | test.cpp:80:9:80:15 | call to strncpy | test.cpp:18:19:18:24 | call to malloc | test.cpp:80:22:80:27 | string | This write may overflow $@ by 2 elements. | test.cpp:80:22:80:27 | string | string | -| test.cpp:99:5:99:11 | call to strncpy | test.cpp:90:19:90:24 | call to malloc | test.cpp:99:18:99:23 | string | This write may overflow $@ by 1 element. | test.cpp:99:18:99:23 | string | string | -| test.cpp:129:9:129:15 | call to strncpy | test.cpp:90:19:90:24 | call to malloc | test.cpp:129:22:129:27 | string | This write may overflow $@ by 1 element. | test.cpp:129:22:129:27 | string | string | -| test.cpp:137:9:137:15 | call to strncpy | test.cpp:90:19:90:24 | call to malloc | test.cpp:137:22:137:27 | string | This write may overflow $@ by 2 elements. | test.cpp:137:22:137:27 | string | string | | test.cpp:152:5:152:11 | call to strncpy | test.cpp:147:19:147:24 | call to malloc | test.cpp:152:18:152:23 | string | This write may overflow $@ by 1 element. | test.cpp:152:18:152:23 | string | string | | test.cpp:154:5:154:11 | call to strncpy | test.cpp:147:19:147:24 | call to malloc | test.cpp:154:18:154:23 | string | This write may overflow $@ by 1 element. | test.cpp:154:18:154:23 | string | string | | test.cpp:156:5:156:11 | call to strncpy | test.cpp:147:19:147:24 | call to malloc | test.cpp:156:18:156:23 | string | This write may overflow $@ by 2 elements. | test.cpp:156:18:156:23 | string | string | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/test.cpp index 253ac4fe2925..ca6ca9a5c5a8 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/test.cpp @@ -264,4 +264,15 @@ void test7(unsigned n) { p = (char*)malloc(++n); } memset(p, 0, n); // GOOD [FALSE POSITIVE] +} + +void test8(unsigned size, unsigned src_pos) +{ + char *xs = new char[size]; + if (src_pos > size) { + src_pos = size; + } + if (src_pos < size - 1) { + memset(xs, 0, src_pos + 1); // GOOD + } } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected index 30b78aa875ca..5c10f6e059d1 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected @@ -27,8 +27,8 @@ edges | main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | | | main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | **argv | provenance | | | main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | *argv | provenance | | -| main.cpp:10:20:10:23 | **argv | tests.cpp:1060:32:1060:35 | **argv | provenance | | -| main.cpp:10:20:10:23 | *argv | tests.cpp:1060:32:1060:35 | *argv | provenance | | +| main.cpp:10:20:10:23 | **argv | tests.cpp:1074:32:1074:35 | **argv | provenance | | +| main.cpp:10:20:10:23 | *argv | tests.cpp:1074:32:1074:35 | *argv | provenance | | | overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | | | overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | *argv | provenance | | | test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | provenance | | @@ -41,12 +41,12 @@ edges | tests.cpp:649:14:649:14 | *s [*home] | tests.cpp:649:14:649:19 | *home | provenance | | | tests.cpp:649:14:649:14 | *s [*home] | tests.cpp:649:16:649:19 | *home | provenance | | | tests.cpp:649:16:649:19 | *home | tests.cpp:649:14:649:19 | *home | provenance | | -| tests.cpp:1060:32:1060:35 | **argv | tests.cpp:1085:9:1085:15 | *access to array | provenance | | -| tests.cpp:1060:32:1060:35 | **argv | tests.cpp:1086:9:1086:15 | *access to array | provenance | | -| tests.cpp:1060:32:1060:35 | *argv | tests.cpp:1085:9:1085:15 | *access to array | provenance | | -| tests.cpp:1060:32:1060:35 | *argv | tests.cpp:1086:9:1086:15 | *access to array | provenance | | -| tests.cpp:1085:9:1085:15 | *access to array | tests.cpp:634:19:634:24 | *source | provenance | | -| tests.cpp:1086:9:1086:15 | *access to array | tests.cpp:643:19:643:24 | *source | provenance | | +| tests.cpp:1074:32:1074:35 | **argv | tests.cpp:1099:9:1099:15 | *access to array | provenance | | +| tests.cpp:1074:32:1074:35 | **argv | tests.cpp:1100:9:1100:15 | *access to array | provenance | | +| tests.cpp:1074:32:1074:35 | *argv | tests.cpp:1099:9:1099:15 | *access to array | provenance | | +| tests.cpp:1074:32:1074:35 | *argv | tests.cpp:1100:9:1100:15 | *access to array | provenance | | +| tests.cpp:1099:9:1099:15 | *access to array | tests.cpp:634:19:634:24 | *source | provenance | | +| tests.cpp:1100:9:1100:15 | *access to array | tests.cpp:643:19:643:24 | *source | provenance | | | tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | provenance | | | tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | | nodes @@ -80,10 +80,10 @@ nodes | tests.cpp:649:14:649:14 | *s [*home] | semmle.label | *s [*home] | | tests.cpp:649:14:649:19 | *home | semmle.label | *home | | tests.cpp:649:16:649:19 | *home | semmle.label | *home | -| tests.cpp:1060:32:1060:35 | **argv | semmle.label | **argv | -| tests.cpp:1060:32:1060:35 | *argv | semmle.label | *argv | -| tests.cpp:1085:9:1085:15 | *access to array | semmle.label | *access to array | -| tests.cpp:1086:9:1086:15 | *access to array | semmle.label | *access to array | +| tests.cpp:1074:32:1074:35 | **argv | semmle.label | **argv | +| tests.cpp:1074:32:1074:35 | *argv | semmle.label | *argv | +| tests.cpp:1099:9:1099:15 | *access to array | semmle.label | *access to array | +| tests.cpp:1100:9:1100:15 | *access to array | semmle.label | *access to array | | tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv | | tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv | | tests_restrict.c:15:41:15:44 | *argv | semmle.label | *argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp index cdef965314b0..555c8e25fb50 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp @@ -1057,6 +1057,20 @@ void test30() { strncpy(us.buffer2, "", sizeof(us) - 1); // BAD } +struct S_Size16 { + unsigned short uint16; + unsigned char uint8; + unsigned char raw[13]; +}; + +void test31() { + S_Size16 e; + + [&e](void* data){ + memcpy(&e, data, sizeof(e)); // GOOD + }; +} + int tests_main(int argc, char *argv[]) { long long arr17[19]; diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected index 40ffd8d4bdde..7408d8360ef5 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected @@ -1,14 +1,17 @@ edges +| globalVars.c:8:7:8:10 | **copy | globalVars.c:8:7:8:10 | **copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:27:9:27:12 | *copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:30:15:30:18 | *copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:30:15:30:18 | *copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:35:11:35:14 | *copy | provenance | | +| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:9:7:9:11 | **copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:38:9:38:13 | *copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:41:15:41:19 | *copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:41:15:41:19 | *copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:50:9:50:13 | *copy2 | provenance | | | globalVars.c:11:22:11:25 | **argv | globalVars.c:12:2:12:15 | *... = ... | provenance | | | globalVars.c:12:2:12:15 | *... = ... | globalVars.c:8:7:8:10 | **copy | provenance | | +| globalVars.c:15:21:15:23 | *val | globalVars.c:15:21:15:23 | *val | provenance | | | globalVars.c:15:21:15:23 | *val | globalVars.c:16:2:16:12 | *... = ... | provenance | | | globalVars.c:16:2:16:12 | *... = ... | globalVars.c:9:7:9:11 | **copy2 | provenance | | | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | *str | provenance | | @@ -16,10 +19,14 @@ edges | globalVars.c:24:11:24:14 | **argv | globalVars.c:11:22:11:25 | **argv | provenance | | | globalVars.c:30:15:30:18 | *copy | globalVars.c:19:25:19:27 | *str | provenance | | | globalVars.c:30:15:30:18 | *copy | globalVars.c:30:15:30:18 | printWrapper output argument | provenance | | +| globalVars.c:30:15:30:18 | printWrapper output argument | globalVars.c:8:7:8:10 | **copy | provenance | | | globalVars.c:30:15:30:18 | printWrapper output argument | globalVars.c:35:11:35:14 | *copy | provenance | | | globalVars.c:35:11:35:14 | *copy | globalVars.c:15:21:15:23 | *val | provenance | | +| globalVars.c:35:11:35:14 | *copy | globalVars.c:35:11:35:14 | setCopy2 output argument | provenance | | +| globalVars.c:35:11:35:14 | setCopy2 output argument | globalVars.c:8:7:8:10 | **copy | provenance | | | globalVars.c:41:15:41:19 | *copy2 | globalVars.c:19:25:19:27 | *str | provenance | | | globalVars.c:41:15:41:19 | *copy2 | globalVars.c:41:15:41:19 | printWrapper output argument | provenance | | +| globalVars.c:41:15:41:19 | printWrapper output argument | globalVars.c:9:7:9:11 | **copy2 | provenance | | | globalVars.c:41:15:41:19 | printWrapper output argument | globalVars.c:50:9:50:13 | *copy2 | provenance | | nodes | globalVars.c:8:7:8:10 | **copy | semmle.label | **copy | @@ -27,6 +34,7 @@ nodes | globalVars.c:11:22:11:25 | **argv | semmle.label | **argv | | globalVars.c:12:2:12:15 | *... = ... | semmle.label | *... = ... | | globalVars.c:15:21:15:23 | *val | semmle.label | *val | +| globalVars.c:15:21:15:23 | *val | semmle.label | *val | | globalVars.c:16:2:16:12 | *... = ... | semmle.label | *... = ... | | globalVars.c:19:25:19:27 | *str | semmle.label | *str | | globalVars.c:19:25:19:27 | *str | semmle.label | *str | @@ -37,6 +45,7 @@ nodes | globalVars.c:30:15:30:18 | *copy | semmle.label | *copy | | globalVars.c:30:15:30:18 | printWrapper output argument | semmle.label | printWrapper output argument | | globalVars.c:35:11:35:14 | *copy | semmle.label | *copy | +| globalVars.c:35:11:35:14 | setCopy2 output argument | semmle.label | setCopy2 output argument | | globalVars.c:38:9:38:13 | *copy2 | semmle.label | *copy2 | | globalVars.c:41:15:41:19 | *copy2 | semmle.label | *copy2 | | globalVars.c:41:15:41:19 | *copy2 | semmle.label | *copy2 | @@ -44,6 +53,7 @@ nodes | globalVars.c:50:9:50:13 | *copy2 | semmle.label | *copy2 | subpaths | globalVars.c:30:15:30:18 | *copy | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | *str | globalVars.c:30:15:30:18 | printWrapper output argument | +| globalVars.c:35:11:35:14 | *copy | globalVars.c:15:21:15:23 | *val | globalVars.c:15:21:15:23 | *val | globalVars.c:35:11:35:14 | setCopy2 output argument | | globalVars.c:41:15:41:19 | *copy2 | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | *str | globalVars.c:41:15:41:19 | printWrapper output argument | #select | globalVars.c:27:9:27:12 | *copy | globalVars.c:23:27:23:30 | **argv | globalVars.c:27:9:27:12 | *copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:23:27:23:30 | **argv | a command-line argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-295/SSLResultConflation.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-295/SSLResultConflation.expected index 5c304e0ea4f1..9e88dba48877 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-295/SSLResultConflation.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-295/SSLResultConflation.expected @@ -6,3 +6,4 @@ | test.cpp:83:7:83:40 | ... \|\| ... | This expression conflates OK and non-OK results from $@. | test.cpp:78:16:78:36 | call to SSL_get_verify_result | call to SSL_get_verify_result | | test.cpp:87:7:87:38 | ... \|\| ... | This expression conflates OK and non-OK results from $@. | test.cpp:7:57:7:77 | call to SSL_get_verify_result | call to SSL_get_verify_result | | test.cpp:107:13:107:42 | ... \|\| ... | This expression conflates OK and non-OK results from $@. | test.cpp:105:16:105:36 | call to SSL_get_verify_result | call to SSL_get_verify_result | +| test.cpp:109:7:109:8 | ok | This expression conflates OK and non-OK results from $@. | test.cpp:105:16:105:36 | call to SSL_get_verify_result | call to SSL_get_verify_result | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.cpp new file mode 100644 index 000000000000..57298515793b --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.cpp @@ -0,0 +1,121 @@ +typedef unsigned long size_t; +typedef struct sqlite3 sqlite3; +typedef struct sqlite3_stmt sqlite3_stmt; +typedef struct sqlite3_str sqlite3_str; + +int snprintf(char *str, size_t size, const char *format, ...); +int sqlite3_open(const char *filename, sqlite3 **ppDb); +int sqlite3_close(sqlite3*); +int sqlite3_exec(sqlite3*, const char *sql, int (*callback)(void*,int,char**,char**), void *, char **errmsg); +int sqlite3_prepare_v2(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **ppStmt, const char **pzTail); +int sqlite3_step(sqlite3_stmt*); +int sqlite3_finalize(sqlite3_stmt*); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +sqlite3_str* sqlite3_str_new(sqlite3*); +void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); +char* sqlite3_str_finish(sqlite3_str*); + +#define SQLITE_TRANSIENT ((void(*)(void*))-1) + +// Simulate a sensitive value +const char* getSensitivePassword() { + return "super_secret_password"; +} + +void storePasswordCleartext(sqlite3* db, const char* password) { + // BAD: Storing sensitive data in cleartext + char sql[256]; + // Unsafe: no escaping, for test purposes only + snprintf(sql, sizeof(sql), "INSERT INTO users(password) VALUES('%s');", password); // $ Source + char* errMsg = 0; + sqlite3_exec(db, sql, 0, 0, &errMsg); // $ Alert +} + +void storePasswordWithPrepare(sqlite3* db, const char* password) { + // BAD: Storing sensitive data in cleartext using sqlite3_prepare + char sql[256]; + snprintf(sql, sizeof(sql), "INSERT INTO users(password) VALUES('%s');", password); // $ Source + sqlite3_stmt* stmt = 0; + sqlite3_prepare_v2(db, sql, -1, &stmt, 0); // $ Alert + sqlite3_step(stmt); + sqlite3_finalize(stmt); +} + +void storePasswordWithBind(sqlite3* db, const char* password) { + // BAD: Storing sensitive data in cleartext using sqlite3_bind_text + const char* sql = "INSERT INTO users(password) VALUES(?);"; + sqlite3_stmt* stmt = 0; + sqlite3_prepare_v2(db, sql, -1, &stmt, 0); + sqlite3_bind_text(stmt, 1, password, -1, SQLITE_TRANSIENT); // $ Alert + sqlite3_step(stmt); + sqlite3_finalize(stmt); +} + +void storePasswordWithAppendf(sqlite3_str* pStr, const char* password) { + // BAD: Storing sensitive data in cleartext using sqlite3_str_appendf + sqlite3_str_appendf(pStr, "INSERT INTO users(password) VALUES('%s');", password); // $ Alert +} + +// Example sanitizer: hashes the sensitive value before storage +void hashSensitiveValue(const char* input, char* output, size_t outSize) { + // Dummy hash for illustration (not cryptographically secure) + unsigned int hash = 5381; + for (const char* p = input; *p; ++p) + hash = ((hash << 5) + hash) + (unsigned char)(*p); + snprintf(output, outSize, "%u", hash); +} + +void storeSanitizedPasswordCleartext(sqlite3* db, const char* password) { + // GOOD: Sanitizing sensitive data before storage + char hashed[64]; + hashSensitiveValue(password, hashed, sizeof(hashed)); + char sql[256]; + snprintf(sql, sizeof(sql), "INSERT INTO users(password) VALUES('%s');", hashed); + char* errMsg = 0; + sqlite3_exec(db, sql, 0, 0, &errMsg); +} + +void storeSanitizedPasswordWithBind(sqlite3* db, const char* password) { + // GOOD: Sanitizing sensitive data before storage with bind + char hashed[64]; + hashSensitiveValue(password, hashed, sizeof(hashed)); + const char* sql = "INSERT INTO users(password) VALUES(?);"; + sqlite3_stmt* stmt = 0; + sqlite3_prepare_v2(db, sql, -1, &stmt, 0); + sqlite3_bind_text(stmt, 1, hashed, -1, SQLITE_TRANSIENT); + sqlite3_step(stmt); + sqlite3_finalize(stmt); +} + +void storeSanitizedPasswordWithAppendf(sqlite3_str* pStr, const char* password) { + // GOOD: Sanitizing sensitive data before storage with appendf + char hashed[64]; + hashSensitiveValue(password, hashed, sizeof(hashed)); + sqlite3_str_appendf(pStr, "INSERT INTO users(password) VALUES('%s');", hashed); +} + +int main() { + sqlite3* db = 0; + sqlite3_open(":memory:", &db); + + // Create table + const char* createTableSQL = "CREATE TABLE users(id INTEGER PRIMARY KEY, password TEXT);"; + sqlite3_exec(db, createTableSQL, 0, 0, 0); + + const char* sensitive = getSensitivePassword(); + + storePasswordCleartext(db, sensitive); + storePasswordWithPrepare(db, sensitive); + storePasswordWithBind(db, sensitive); + storeSanitizedPasswordCleartext(db, sensitive); + storeSanitizedPasswordWithBind(db, sensitive); + + // If sqlite3_str is available + sqlite3_str* pStr = sqlite3_str_new(db); + storePasswordWithAppendf(pStr, sensitive); + storeSanitizedPasswordWithAppendf(pStr, sensitive); + sqlite3_str_finish(pStr); + + sqlite3_close(db); + return 0; +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.expected new file mode 100644 index 000000000000..89a7a2c58265 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.expected @@ -0,0 +1,16 @@ +#select +| CleartextSqliteDatabase.cpp:31:5:31:16 | call to sqlite3_exec | CleartextSqliteDatabase.cpp:29:77:29:84 | password | CleartextSqliteDatabase.cpp:31:22:31:24 | *sql | This SQLite call may store $@ in a non-encrypted SQLite database. | CleartextSqliteDatabase.cpp:29:77:29:84 | password | sensitive information | +| CleartextSqliteDatabase.cpp:39:5:39:22 | call to sqlite3_prepare_v2 | CleartextSqliteDatabase.cpp:37:77:37:84 | password | CleartextSqliteDatabase.cpp:39:28:39:30 | *sql | This SQLite call may store $@ in a non-encrypted SQLite database. | CleartextSqliteDatabase.cpp:37:77:37:84 | password | sensitive information | +| CleartextSqliteDatabase.cpp:49:5:49:21 | call to sqlite3_bind_text | CleartextSqliteDatabase.cpp:49:32:49:39 | password | CleartextSqliteDatabase.cpp:49:32:49:39 | password | This SQLite call may store $@ in a non-encrypted SQLite database. | CleartextSqliteDatabase.cpp:49:32:49:39 | password | sensitive information | +| CleartextSqliteDatabase.cpp:56:5:56:23 | call to sqlite3_str_appendf | CleartextSqliteDatabase.cpp:56:76:56:83 | password | CleartextSqliteDatabase.cpp:56:76:56:83 | password | This SQLite call may store $@ in a non-encrypted SQLite database. | CleartextSqliteDatabase.cpp:56:76:56:83 | password | sensitive information | +edges +| CleartextSqliteDatabase.cpp:29:77:29:84 | password | CleartextSqliteDatabase.cpp:31:22:31:24 | *sql | provenance | TaintFunction | +| CleartextSqliteDatabase.cpp:37:77:37:84 | password | CleartextSqliteDatabase.cpp:39:28:39:30 | *sql | provenance | TaintFunction | +nodes +| CleartextSqliteDatabase.cpp:29:77:29:84 | password | semmle.label | password | +| CleartextSqliteDatabase.cpp:31:22:31:24 | *sql | semmle.label | *sql | +| CleartextSqliteDatabase.cpp:37:77:37:84 | password | semmle.label | password | +| CleartextSqliteDatabase.cpp:39:28:39:30 | *sql | semmle.label | *sql | +| CleartextSqliteDatabase.cpp:49:32:49:39 | password | semmle.label | password | +| CleartextSqliteDatabase.cpp:56:76:56:83 | password | semmle.label | password | +subpaths diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.qlref new file mode 100644 index 000000000000..d5adb06122dd --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-313/CleartextSqliteDatabase.qlref @@ -0,0 +1,4 @@ +query: Security/CWE/CWE-313/CleartextSqliteDatabase.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected index 53be20ab7ac8..9756dde70dd3 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected @@ -1,4 +1,5 @@ edges +| tests.cpp:62:7:62:18 | **global_token | tests.cpp:62:7:62:18 | **global_token | provenance | | | tests.cpp:62:7:62:18 | **global_token | tests.cpp:69:2:69:43 | *... = ... | provenance | | | tests.cpp:62:7:62:18 | **global_token | tests.cpp:71:27:71:38 | *global_token | provenance | | | tests.cpp:62:22:62:27 | *call to getenv | tests.cpp:62:7:62:18 | **global_token | provenance | | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected index 28f2b8335320..1376a03ce889 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected @@ -7,9 +7,11 @@ edges | tests2.cpp:49:12:49:12 | call to SAXParser | tests2.cpp:51:2:51:2 | *p | provenance | | | tests3.cpp:23:21:23:53 | *call to createXMLReader | tests3.cpp:23:21:23:53 | *call to createXMLReader | provenance | | | tests3.cpp:23:21:23:53 | *call to createXMLReader | tests3.cpp:25:2:25:2 | *p | provenance | | +| tests3.cpp:35:16:35:20 | **p_3_3 | tests3.cpp:35:16:35:20 | **p_3_3 | provenance | | | tests3.cpp:35:16:35:20 | **p_3_3 | tests3.cpp:38:2:38:6 | *p_3_3 | provenance | | | tests3.cpp:35:24:35:56 | *call to createXMLReader | tests3.cpp:35:16:35:20 | **p_3_3 | provenance | | | tests3.cpp:35:24:35:56 | *call to createXMLReader | tests3.cpp:35:24:35:56 | *call to createXMLReader | provenance | | +| tests3.cpp:48:16:48:20 | **p_3_5 | tests3.cpp:48:16:48:20 | **p_3_5 | provenance | | | tests3.cpp:48:16:48:20 | **p_3_5 | tests3.cpp:56:2:56:6 | *p_3_5 | provenance | | | tests3.cpp:48:24:48:56 | *call to createXMLReader | tests3.cpp:48:16:48:20 | **p_3_5 | provenance | | | tests3.cpp:48:24:48:56 | *call to createXMLReader | tests3.cpp:48:24:48:56 | *call to createXMLReader | provenance | | @@ -26,6 +28,7 @@ edges | tests5.cpp:55:25:55:38 | *call to createLSParser | tests5.cpp:55:25:55:38 | *call to createLSParser | provenance | | | tests5.cpp:55:25:55:38 | *call to createLSParser | tests5.cpp:59:2:59:2 | *p | provenance | | | tests5.cpp:55:25:55:38 | *call to createLSParser | tests5.cpp:59:2:59:2 | *p | provenance | Config | +| tests5.cpp:63:21:63:24 | **g_p2 | tests5.cpp:63:21:63:24 | **g_p2 | provenance | | | tests5.cpp:63:21:63:24 | **g_p2 | tests5.cpp:77:2:77:5 | *g_p2 | provenance | | | tests5.cpp:70:2:70:32 | *... = ... | tests5.cpp:63:21:63:24 | **g_p2 | provenance | | | tests5.cpp:70:17:70:30 | *call to createLSParser | tests5.cpp:70:2:70:32 | *... = ... | provenance | | diff --git a/csharp/actions/create-extractor-pack/action.yml b/csharp/actions/create-extractor-pack/action.yml index 2386fe151019..6c6b3af82b02 100644 --- a/csharp/actions/create-extractor-pack/action.yml +++ b/csharp/actions/create-extractor-pack/action.yml @@ -17,7 +17,7 @@ runs: run: | CODEQL_PATH=$(gh codeql version --format=json | jq -r .unpackedLocation) # The legacy ASP extractor is not in this repo, so take the one from the nightly build - mv "$CODEQL_PATH/csharp/tools/extractor-asp.jar" "${{ github.workspace }}/csharp/extractor-pack/tools" + mv "$CODEQL_PATH/csharp/tools/extractor-asp.jar" "$GITHUB_WORKSPACE/csharp/extractor-pack/tools" # Safe guard against using the bundled extractor rm -rf "$CODEQL_PATH/csharp" env: diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index f46a19790d63..1b3c69fd4d05 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.45 + +No user-facing changes. + ## 1.7.44 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.45.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.45.md new file mode 100644 index 000000000000..3e891d822fb9 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.45.md @@ -0,0 +1,3 @@ +## 1.7.45 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index a392bdc2592e..5a84df101839 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.44 +lastReleaseVersion: 1.7.45 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 4da11e525e6c..c6e17a64adcd 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.44 +version: 1.7.46-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index f46a19790d63..1b3c69fd4d05 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.45 + +No user-facing changes. + ## 1.7.44 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.45.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.45.md new file mode 100644 index 000000000000..3e891d822fb9 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.45.md @@ -0,0 +1,3 @@ +## 1.7.45 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index a392bdc2592e..5a84df101839 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.44 +lastReleaseVersion: 1.7.45 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index b59805aa902f..529cd400b6c3 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.44 +version: 1.7.46-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index e8540d22ba84..1bce7a7f8031 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.2.1 + +No user-facing changes. + ## 5.2.0 ### New Features diff --git a/csharp/ql/lib/change-notes/released/5.2.1.md b/csharp/ql/lib/change-notes/released/5.2.1.md new file mode 100644 index 000000000000..8d65db4e16d0 --- /dev/null +++ b/csharp/ql/lib/change-notes/released/5.2.1.md @@ -0,0 +1,3 @@ +## 5.2.1 + +No user-facing changes. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 9e57a36a7dce..1684d0e72a28 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.2.0 +lastReleaseVersion: 5.2.1 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index d425970a3141..b99e5b5be642 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 5.2.0 +version: 5.2.2-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/lib/semmle/code/csharp/Type.qll b/csharp/ql/lib/semmle/code/csharp/Type.qll index d11b5618e806..e417f393b94a 100644 --- a/csharp/ql/lib/semmle/code/csharp/Type.qll +++ b/csharp/ql/lib/semmle/code/csharp/Type.qll @@ -201,7 +201,7 @@ class ValueOrRefType extends Type, Attributable, @value_or_ref_type { */ pragma[inline] predicate hasCallable(Callable c) { - this.hasMethod(c) + this.hasMember(c) or this.hasMember(c.(Accessor).getDeclaration()) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll index 6d59c0579860..d1490c849163 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -975,7 +975,8 @@ private module Cached { cached // nothing is actually cached module BarrierGuard { private predicate guardChecksAdjTypes( - DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch + DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, + DataFlowIntegrationInput::GuardValue branch ) { exists(Guards::AbstractValues::BooleanValue v | guardChecks(g, e.getAstNode(), v) and @@ -1016,6 +1017,7 @@ string getToStringPrefix(Definition def) { private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig { private import csharp as Cs private import semmle.code.csharp.controlflow.BasicBlocks + private import codeql.util.Boolean class Expr extends ControlFlow::Node { predicate hasCfgNode(ControlFlow::BasicBlock bb, int i) { this = bb.getNode(i) } @@ -1042,12 +1044,14 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu ) } + class GuardValue = Boolean; + class Guard extends Guards::Guard { /** * Holds if the evaluation of this guard to `branch` corresponds to the edge * from `bb1` to `bb2`. */ - predicate hasBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) { + predicate hasValueBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) { exists(ControlFlow::SuccessorTypes::ConditionalSuccessor s | this.getAControlFlowNode() = bb1.getLastNode() and bb2 = bb1.getASuccessorByType(s) and @@ -1060,13 +1064,13 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu * branch edge from `bb1` to `bb2`. That is, following the edge from * `bb1` to `bb2` implies that this guard evaluated to `branch`. */ - predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) { - this.hasBranchEdge(bb1, bb2, branch) + predicate valueControlsBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue branch) { + this.hasValueBranchEdge(bb1, bb2, branch) } } /** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */ - predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) { + predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, GuardValue branch) { exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s | guard.getAControlFlowNode() = conditionBlock.getLastNode() and s.getValue() = branch and diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll index f92bb0d2f44a..ee345780654d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll @@ -39,6 +39,15 @@ private module ConditionalBypassConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof Sink } predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.getLocation() + or + // from ConditionalBypass.ql + result = sink.(Sink).getSensitiveMethodCall().getLocation() + } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll index 5d9d18dcbac6..27f6ab6935f7 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/UnsafeDeserializationQuery.qll @@ -59,6 +59,10 @@ private module TaintToObjectMethodTrackingConfig implements DataFlow::ConfigSig predicate isSink(DataFlow::Node sink) { sink instanceof InstanceMethodSink } predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate observeDiffInformedIncrementalMode() { + any() // used in one of the disjuncts in UnsafeDeserializationUntrustedInput.ql + } } /** @@ -77,6 +81,10 @@ private module JsonConvertTrackingConfig implements DataFlow::ConfigSig { } predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate observeDiffInformedIncrementalMode() { + any() // used in one of the disjuncts in UnsafeDeserializationUntrustedInput.ql + } } /** @@ -133,6 +141,10 @@ private module TypeNameTrackingConfig implements DataFlow::ConfigSig { ) ) } + + predicate observeDiffInformedIncrementalMode() { + none() // Only used as secondary config in UnsafeDeserializationUntrustedInput.ql + } } /** @@ -149,6 +161,10 @@ private module TaintToConstructorOrStaticMethodTrackingConfig implements DataFlo predicate isSink(DataFlow::Node sink) { sink instanceof ConstructorOrStaticMethodSink } predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate observeDiffInformedIncrementalMode() { + any() // used in one of the disjuncts in UnsafeDeserializationUntrustedInput.ql + } } /** @@ -186,6 +202,10 @@ private module TaintToObjectTypeTrackingConfig implements DataFlow::ConfigSig { oc.getObjectType() instanceof StrongTypeDeserializer ) } + + predicate observeDiffInformedIncrementalMode() { + none() // only used as secondary config in UnsafeDeserializationUntrustedInput.ql + } } /** @@ -210,6 +230,10 @@ private module WeakTypeCreationToUsageTrackingConfig implements DataFlow::Config sink.asExpr() = mc.getQualifier() ) } + + predicate observeDiffInformedIncrementalMode() { + none() // only used as secondary config in UnsafeDeserializationUntrustedInput.ql + } } /** diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 888800c5021d..7209d4cfb81e 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.2 + +No user-facing changes. + ## 1.3.1 ### Minor Analysis Improvements diff --git a/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransformLambda.ql b/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransformLambda.ql index 9f70760ba602..8fcef4d4744f 100644 --- a/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransformLambda.ql +++ b/csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransformLambda.ql @@ -24,6 +24,8 @@ module NotThreadSafeCryptoUsageIntoParallelInvokeConfig implements DataFlow::Con } predicate isSink(DataFlow::Node sink) { sink instanceof ParallelSink } + + predicate observeDiffInformedIncrementalMode() { any() } } module NotThreadSafeCryptoUsageIntoParallelInvoke = diff --git a/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql b/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql index 32508fa9d3fb..1e33ed6a1fde 100644 --- a/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql +++ b/csharp/ql/src/Security Features/CWE-798/HardcodedConnectionString.ql @@ -38,6 +38,12 @@ module ConnectionStringConfig implements DataFlow::ConfigSig { } predicate isBarrier(DataFlow::Node node) { node instanceof StringFormatSanitizer } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + any(Call call | call.getAnArgument() = sink.asExpr()).getLocation() = result + } } /** diff --git a/csharp/ql/src/change-notes/released/1.3.2.md b/csharp/ql/src/change-notes/released/1.3.2.md new file mode 100644 index 000000000000..14f14807ef51 --- /dev/null +++ b/csharp/ql/src/change-notes/released/1.3.2.md @@ -0,0 +1,3 @@ +## 1.3.2 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index e71b6d081f15..86a9cb32d86b 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.3.1 +lastReleaseVersion: 1.3.2 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index c3963f711e69..ec0fab1f1114 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.3.1 +version: 1.3.3-dev groups: - csharp - queries diff --git a/docs/codeql/_static/custom.css_t b/docs/codeql/_static/custom.css_t index e8667ede93ab..b05c51203980 100644 --- a/docs/codeql/_static/custom.css_t +++ b/docs/codeql/_static/custom.css_t @@ -1,7 +1,7 @@ /* * This Sphinx stylesheet adds some customizations to the default Alabaster theme. - * - * The source for the default stylesheet can be found at + * + * The source for the default stylesheet can be found at * https://github.com/bitprophet/alabaster/blob/master/alabaster/static/alabaster.css_t * * For the classes provided by the primer, see https://unpkg.com/@primer/css/dist/primer.css @@ -45,7 +45,7 @@ article ul, article ol { } .SideNav li { - margin: 10px 0 10px 0px; + margin: 10px 0 10px 0px; } .SideNav ul, .SideNav ol, .SideNav li { @@ -80,20 +80,20 @@ a.reference { } a.reference:hover { - text-decoration: none; + text-decoration: none; } /* -- ADMONITIONS ---------------------------------------------------------------------------- */ -/* - * Override default styling for "admonitions". +/* + * Override default styling for "admonitions". * This includes: note, tip, important, and caution. * */ - -div.admonition p.admonition-title { + +div.admonition p.admonition-title { /* Make title same size and font as body, but bold. */ - font-family: Lato, sans-serif; + font-family: Lato, sans-serif; font-size: 14px; font-weight: bold; } @@ -102,7 +102,7 @@ p.admonition-title:after { content: ""; /* Don't insert a colon after the title */ } -/* +/* * Don't use yellow for footnote background. * */ @@ -111,7 +111,7 @@ p.admonition-title:after { background-color: unset; } -/* +/* * Add a border with rounded corners around code blocks * (as in the QL language spec). * @@ -198,7 +198,7 @@ blockquote.pull-quote { background-color: #EEE; border: #CCC; border-radius: 5px; -} +} blockquote.pull-quote:first-line { font-weight: bold; @@ -230,6 +230,11 @@ blockquote.pull-quote > :last-child { font-family: "monospace"; } +/* Fixes a bug in "Supported languages and frameworks" where footnotes were incorrectly indented */ +aside .label { + border: 0; +} + /* -- PRINT VIEW ----------------------------------------------------------------------------*/ @media print { @@ -252,14 +257,14 @@ blockquote.pull-quote > :last-child { /* -- SMALL SCREEN ------------------------------------------------------------------------------- */ -@media screen and (max-width: 875px) { +@media screen and (max-width: 875px) { /* Overrides strange behaviour caused by default styles */ body { padding: 0; - } - + } + div.footer { display: block; } diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.19.4.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.19.4.rst index 51ff05b0c3b1..9235d63fe2cf 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.19.4.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.19.4.rst @@ -79,4 +79,4 @@ JavaScript/TypeScript * Added taint-steps for :code:`Array.prototype.toReversed`. * Added taint-steps for :code:`Array.prototype.toSorted`. * Added support for :code:`String.prototype.matchAll`. -* Added taint-steps for :code:`Array.prototype.reverse`. +* Added taint-steps for :code:`Array.prototype.reverse`\ diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.20.4.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.20.4.rst index a5c9c4f222f8..c3012e020c78 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.20.4.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.20.4.rst @@ -117,8 +117,8 @@ Java/Kotlin * Deleted the deprecated :code:`isLValue` and :code:`isRValue` predicates from the :code:`VarAccess` class, use :code:`isVarWrite` and :code:`isVarRead` respectively instead. * Deleted the deprecated :code:`getRhs` predicate from the :code:`VarWrite` class, use :code:`getASource` instead. * Deleted the deprecated :code:`LValue` and :code:`RValue` classes, use :code:`VarWrite` and :code:`VarRead` respectively instead. -* Deleted a lot of deprecated classes ending in ``*Access``, use the corresponding ``*Call`` classes instead. -* Deleted a lot of deprecated predicates ending in ``*Access``, use the corresponding ``*Call`` predicates instead. +* Deleted a lot of deprecated classes ending in :code:`*Access`, use the corresponding :code:`*Call` classes instead. +* Deleted a lot of deprecated predicates ending in :code:`*Access`, use the corresponding :code:`*Call` predicates instead. * Deleted the deprecated :code:`EnvInput` and :code:`DatabaseInput` classes from :code:`FlowSources.qll`, use the threat models feature instead. * Deleted some deprecated API predicates from :code:`SensitiveApi.qll`, use the Sink classes from that file instead. @@ -144,7 +144,7 @@ Ruby * Deleted the deprecated :code:`ModelClass` and :code:`ModelInstance` classes from :code:`ActiveResource.qll`, use :code:`ModelClassNode` and :code:`ModelClassNode.getAnInstanceReference()` instead. * Deleted the deprecated :code:`Collection` class from :code:`ActiveResource.qll`, use :code:`CollectionSource` instead. * Deleted the deprecated :code:`ServiceInstantiation` and :code:`ClientInstantiation` classes from :code:`Twirp.qll`. -* Deleted a lot of deprecated dataflow modules from ``*Query.qll`` files. +* Deleted a lot of deprecated dataflow modules from :code:`*Query.qll` files. * Deleted the old deprecated TypeTracking library. Swift diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.21.0.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.21.0.rst index aa604d702e75..b6396b2be4e2 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.21.0.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.21.0.rst @@ -207,5 +207,5 @@ JavaScript/TypeScript * Intersection :code:`&&` * Subtraction :code:`--` - * :code:`\\q` quoted string + * :code:`\q` quoted string diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.21.4.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.21.4.rst index 3603d345d71b..c21a9940b4b5 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.21.4.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.21.4.rst @@ -38,7 +38,7 @@ Minor Analysis Improvements C/C++ """"" -* Added flow model for the :code:`SQLite` and :code:`OpenSSL` libraries. This may result in more alerts when running queries on codebases that use these libraries. +* Added flow models for the :code:`SQLite` and :code:`OpenSSL` libraries. This may result in more alerts when running queries on codebases that use these libraries. C# "" diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.0.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.0.rst index 04920497e4ea..d60b0e957694 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.0.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.0.rst @@ -50,7 +50,7 @@ New Queries Golang """""" -* Query (:code:`go/html-template-escaping-bypass-xss`) has been promoted to the main query suite. This query finds potential cross-site scripting (XSS) vulnerabilities when using the :code:`html/template` package, caused by user input being cast to a type which bypasses the HTML autoescaping. It was originally contributed to the experimental query pack by @gagliardetto in `https://github.com/github/codeql-go/pull/493 `_. +* Query (:code:`go/html-template-escaping-bypass-xss`) has been promoted to the main query suite. This query finds potential cross-site scripting (XSS) vulnerabilities when using the :code:`html/template` package, caused by user input being cast to a type which bypasses the HTML autoescaping. It was originally contributed to the experimental query pack by @gagliardetto in https://github.com/github/codeql-go/pull/493. Language Libraries ------------------ diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.1.rst index c1b1bb4b0a27..0b051d5473fb 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.1.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.1.rst @@ -14,7 +14,7 @@ This is an overview of changes in the CodeQL CLI and relevant CodeQL query and l Security Coverage ----------------- -CodeQL 2.22.1 runs a total of 449 security queries when configured with the Default suite (covering 165 CWE). The Extended suite enables an additional 129 queries (covering 33 more CWE). +CodeQL 2.22.1 runs a total of 476 security queries when configured with the Default suite (covering 166 CWE). The Extended suite enables an additional 129 queries (covering 32 more CWE). 27 security queries have been added with this release. CodeQL CLI ---------- @@ -38,7 +38,7 @@ Minor Analysis Improvements C/C++ """"" -* Added flow model for the following libraries: :code:`madler/zlib`, :code:`google/brotli`, :code:`libidn/libidn2`, :code:`libssh2/libssh2/`, :code:`nghttp2/nghttp2`, :code:`libuv/libuv/`, and :code:`curl/curl`. This may result in more alerts when running queries on codebases that use these libraries. +* Added flow models for the following libraries: :code:`madler/zlib`, :code:`google/brotli`, :code:`libidn/libidn2`, :code:`libssh2/libssh2`, :code:`nghttp2/nghttp2`, :code:`libuv/libuv`, and :code:`curl/curl`. This may result in more alerts when running queries on codebases that use these libraries. C# "" diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.2.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.2.rst new file mode 100644 index 000000000000..92c440a05afd --- /dev/null +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.2.rst @@ -0,0 +1,238 @@ +.. _codeql-cli-2.22.2: + +========================== +CodeQL 2.22.2 (2025-07-29) +========================== + +.. contents:: Contents + :depth: 2 + :local: + :backlinks: none + +This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog `__, `relevant GitHub Changelog updates `__, `changes in the CodeQL extension for Visual Studio Code `__, and the `CodeQL Action changelog `__. + +Security Coverage +----------------- + +CodeQL 2.22.2 runs a total of 474 security queries when configured with the Default suite (covering 166 CWE). The Extended suite enables an additional 130 queries (covering 32 more CWE). + +CodeQL CLI +---------- + +Bug Fixes +~~~~~~~~~ + +* Fixes a bug in query suites where the :code:`version` property of an :code:`import` instruction was ignored. Previously, the following query suite would *not* resolve to :code:`v1.0.19` of :code:`codeql/csharp-queries`. Instead it would resolve to the latest version. This is now fixed and the resolve pack version would be :code:`v1.0.19`. + + .. code-block:: text + + - from: codeql/csharp-queries + import: codeql-suites/csharp-security-and-quality.qls + version: 1.0.19 + +Query Packs +----------- + +Bug Fixes +~~~~~~~~~ + +C# +"" + +* :code:`web.config` and :code:`web.release.config` files are now recognized regardless of case. This means queries :code:`cs/web/debug-binary` and :code:`cs/web/missing-x-frame-options` may produce more results than before. + +Breaking Changes +~~~~~~~~~~~~~~~~ + +JavaScript/TypeScript +""""""""""""""""""""" + +* The :code:`Type` and :code:`Symbol` classes have been deprecated and will be empty in newly extracted databases, since the TypeScript extractor no longer populates them. + This is a breaking change for custom queries that explicitly relied on these classes. + Such queries will still compile, but with deprecation warnings, and may have different query results due to type information no longer being available. + We expect most custom queries will not be affected, however. If a custom query has no deprecation warnings, it should not be affected by this change. + Uses of :code:`getType()` should be rewritten to use the new :code:`getTypeBinding()` or :code:`getNameBinding()` APIs instead. + If the new API is not sufficient, please consider opening an issue in :code:`github/codeql` describing your use-case. + +Major Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +JavaScript/TypeScript +""""""""""""""""""""" + +* The TypeScript extractor no longer relies on the TypeScript compiler for extracting type information. + Instead, the information we need from types is now derived by an algorithm written in QL. + This results in more robust extraction with faster extraction times, in some cases significantly faster. +* Taint is now tracked through the React :code:`use` function. +* Parameters of React server functions, marked with the :code:`"use server"` directive, are now seen as taint sources. + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* Due to changes in the :code:`FunctionWithWrappers` library (:code:`semmle.code.cpp.security.FunctionWithWrappers`) the primary alert location generated by the queries :code:`cpp/path-injection`, :code:`cpp/sql-injection`, :code:`cpp/tainted-format-string`, and :code:`cpp/command-line-injection` may have changed. +* Added flow models for the Win32 API functions :code:`CreateThread`, :code:`CreateRemoteThread`, and :code:`CreateRemoteThreadEx`. +* Improved support for dataflow through function objects and lambda expressions. +* Added flow models for :code:`pthread_create` and :code:`std::thread`. +* The :code:`cpp/incorrect-string-type-conversion` query no longer alerts on incorrect type conversions that occur in unreachable code. +* Added flow models for the GNU C Library. +* Fixed a number of false positives and false negatives in :code:`cpp/global-use-before-init`. Note that this query is not part of any of the default query suites. +* The query :code:`cpp/sql-injection` now can be extended using the :code:`sql-injection` Models as Data (MaD) sink kind. + +C# +"" + +* Explicitly added summary models for all overloads of :code:`System.Xml.XmlDictionaryReader.CreateBinaryReader`. Added models for some of the methods and properties in :code:`System.Runtime.Serialization.SerializationInfo` and :code:`System.Runtime.Serialization.SerializationInfoEnumerator`. Updated models for :code:`System.Text.Encoding.GetBytes`, :code:`System.Text.Encoding.GetChars` and the constructor for :code:`System.IO.MemoryStream`. This generally improves the library modelling and thus reduces the number of false negatives. +* Added explicit SQL injection Models as Data models for :code:`Microsoft.Data.SqlClient.SqlCommand` and :code:`Microsoft.Data.SqlClient.SqlDataAdapter`. This reduces false negatives for the query :code:`cs/sql-injection`. + +Golang +"""""" + +* :code:`filepath.IsLocal` is now recognized as a sanitizer against path-traversal and related vulnerabilities. + +Java/Kotlin +""""""""""" + +* Java analysis of guards has been switched to use the new and improved shared guards library. This improves precision of a number of queries, in particular :code:`java/dereferenced-value-may-be-null`, which now has fewer false positives, and :code:`java/useless-null-check` and :code:`java/constant-comparison`, which gain additional true positives. + +JavaScript/TypeScript +""""""""""""""""""""" + +* Removed three queries from the JS qlpack, which have been superseded by newer queries that are part of the Actions qlpack: + + * :code:`js/actions/pull-request-target` has been superseded by :code:`actions/untrusted-checkout/{medium,high,critical}` + * :code:`js/actions/actions-artifact-leak` has been superseded by :code:`actions/secrets-in-artifacts` + * :code:`js/actions/command-injection` has been superseded by :code:`actions/command-injection/{medium,critical}` + +New Queries +~~~~~~~~~~~ + +Rust +"""" + +* Added a new query, :code:`rust/access-after-lifetime-ended`, for detecting pointer dereferences after the lifetime of the pointed-to object has ended. + +Language Libraries +------------------ + +Bug Fixes +~~~~~~~~~ + +JavaScript/TypeScript +""""""""""""""""""""" + +* The JavaScript extractor no longer ignores source files specified in the :code:`tsconfig.json` compiler options :code:`outDir` if doing so would result in excluding all source code. + +Python +"""""" + +* The Python parser is now able to correctly parse expressions such as :code:`match[1]` and :code:`match()` where :code:`match` is not used as a keyword. + +GitHub Actions +"""""""""""""" + +* The :code:`actions/artifact-poisoning/critical` and :code:`actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to :code:`$[{ runner.temp }}` in addition to :code:`/tmp`. + +Breaking Changes +~~~~~~~~~~~~~~~~ + +Ruby +"""" + +* Most classes and predicates in the AST, SSA, and control-flow-graph libraries are now annotated with :code:`overlay[local]`, in preparation for incremental analysis. This could result in compiler errors for custom queries if they extend these classes. To mitigate such errors, look for ways to restructure custom QL code so it doesn't depend on changing the behavior of standard-library classes. + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* The :code:`FunctionWithWrappers` library (:code:`semmle.code.cpp.security.FunctionWithWrappers`) no longer considers calls through function pointers as wrapper functions. +* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the :code:`arm_neon.h` header and Neon vector types, and support for the :code:`fp8` scalar type. The :code:`arm_sve.h` header and scalable vectors are only partially supported at this point. +* Added support for :code:`__fp16 _Complex` and :code:`__bf16 _Complex` types +* Added :code:`sql-injection` sink models for the Oracle Call Interface (OCI) database library functions :code:`OCIStmtPrepare` and :code:`OCIStmtPrepare2`. + +Golang +"""""" + +* Added models for the :code:`Head` function and the :code:`Client.Head` method, from the :code:`net/http` package, to the :code:`Http::ClientRequest` class. This means that they will be recognized as sinks for the query :code:`go/request-forgery` and the experimental query :code:`go/ssrf`. +* Previously, :code:`DefinedType.getBaseType` gave the underlying type. It now gives the right hand side of the type declaration, as the documentation indicated that it should. + +Java/Kotlin +""""""""""" + +* The qualifiers of a calls to :code:`readObject` on any classes that implement :code:`java.io.ObjectInput` are now recognised as sinks for :code:`java/unsafe-deserialization`. Previously this was only the case for classes which extend :code:`java.io.ObjectInputStream`. + +JavaScript/TypeScript +""""""""""""""""""""" + +* Enhanced modeling for the :code:`execa` library, adding support for command execution methods :code:`execaCommand`, :code:`execaCommandSync`, :code:`$`, and :code:`$.sync`, as well as file system operations through :code:`inputFile`, :code:`pipeStdout`, :code:`pipeAll`, and :code:`pipeStderr`. + +Python +"""""" + +* Type annotations such as :code:`foo : Bar` are now treated by the call graph as an indication that :code:`foo` may be an instance of :code:`Bar`. + +Rust +"""" + +* Type inference has been extended to support pattern matching. +* Call resolution for calls to associated functions has been improved, so it now disambiguates the targets based on type information at the call sites (either type information about the arguments or about the expected return types). +* Type inference has been improved for :code:`for` loops and range expressions, which improves call resolution and may ultimately lead to more query results. +* Implemented support for data flow through trait functions. For the purpose of data flow, calls to trait functions dispatch to all possible implementations. +* :code:`AssocItem` and :code:`ExternItem` are now proper subclasses of :code:`Item`. +* Added type inference for :code:`for` loops and array expressions. + +Deprecated APIs +~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* The :code:`UnknownDefaultLocation`, :code:`UnknownExprLocation`, and :code:`UnknownStmtLocation` classes have been deprecated. Use :code:`UnknownLocation` instead. + +Golang +"""""" + +* The class :code:`BuiltinType` is now deprecated. Use the new replacement :code:`BuiltinTypeEntity` instead. +* The class :code:`DeclaredType` is now deprecated. Use the new replacement :code:`DeclaredTypeEntity` instead. + +Java/Kotlin +""""""""""" + +* The module :code:`semmle.code.java.frameworks.Castor` has been deprecated and will be removed in a future release. +* The module :code:`semmle.code.java.frameworks.JYaml` has been deprecated and will be removed in a future release. +* The classes :code:`UnsafeHessianInputReadObjectMethod` and :code:`BurlapInputReadObjectMethod` in the module :code:`semmle.code.java.frameworks.HessianBurlap` have been deprecated and will be removed in a future release. +* The class :code:`YamlBeansReaderReadMethod` in the module :code:`semmle.code.java.frameworks.YamlBeans` has been deprecated and will be removed in a future release. +* The class :code:`MethodApacheSerializationUtilsDeserialize` in the module :code:`semmle.code.java.frameworks.apache.Lang` has been deprecated and will be removed in a future release. + +New Features +~~~~~~~~~~~~ + +C/C++ +""""" + +* Added a :code:`isFinalValueOfParameter` predicate to :code:`DataFlow::Node` which holds when a dataflow node represents the final value of an output parameter of a function. + +C# +"" + +* Added a new predicate, :code:`getASuperType()`, to get a direct supertype of this type. + +Java/Kotlin +""""""""""" + +* You can now add sinks for the query "Deserialization of user-controlled data" (:code:`java/unsafe-deserialization`) using `data extensions `__ by extending :code:`sinkModel` and using the kind "unsafe-deserialization". The existing sinks that do not require extra logic to determine if they are unsafe are now defined in this way. + +Shared Libraries +---------------- + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Concepts +"""""""" + +* Initial release. Moves the shared concepts library into its own qlpack. diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.3.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.3.rst new file mode 100644 index 000000000000..7a1d554855de --- /dev/null +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.3.rst @@ -0,0 +1,101 @@ +.. _codeql-cli-2.22.3: + +========================== +CodeQL 2.22.3 (2025-08-06) +========================== + +.. contents:: Contents + :depth: 2 + :local: + :backlinks: none + +This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog `__, `relevant GitHub Changelog updates `__, `changes in the CodeQL extension for Visual Studio Code `__, and the `CodeQL Action changelog `__. + +Security Coverage +----------------- + +CodeQL 2.22.3 runs a total of 476 security queries when configured with the Default suite (covering 169 CWE). The Extended suite enables an additional 130 queries (covering 32 more CWE). 2 security queries have been added with this release. + +CodeQL CLI +---------- + +New Features +~~~~~~~~~~~~ + +* The :code:`codeql database cleanup` command now takes the :code:`--cache-cleanup=overlay` option, which trims the cache to just the data that will be useful when evaluating against an overlay. + +Query Packs +----------- + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* The "Initialization code not run" query (:code:`cpp/initialization-not-run`) no longer reports an alert on static global variables that have no dereference. + +Rust +"""" + +* Type inference now supports closures, calls to closures, and trait bounds using the :code:`FnOnce` trait. +* Type inference now supports trait objects, i.e., :code:`dyn Trait` types. +* Type inference now supports tuple types. + +New Queries +~~~~~~~~~~~ + +Rust +"""" + +* Added a new query, :code:`rust/hard-coded-cryptographic-value`, for detecting use of hardcoded keys, passwords, salts and initialization vectors. + +Language Libraries +------------------ + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* The :code:`cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives. + +JavaScript/TypeScript +""""""""""""""""""""" + +* The regular expressions in :code:`SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information. + +Python +"""""" + +* The regular expressions in :code:`SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information. + +Ruby +"""" + +* The regular expressions in :code:`SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information. + +Swift +""""" + +* The regular expressions in :code:`SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information. + +Rust +"""" + +* Removed deprecated dataflow extensible predicates :code:`sourceModelDeprecated`, :code:`sinkModelDeprecated`, and :code:`summaryModelDeprecated`, along with their associated classes. +* The regular expressions in :code:`SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information. + +New Features +~~~~~~~~~~~~ + +C/C++ +""""" + +* Exposed various SSA-related classes (:code:`Definition`, :code:`PhiNode`, :code:`ExplicitDefinition`, :code:`DirectExplicitDefinition`, and :code:`IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory. + +Java/Kotlin +""""""""""" + +* Kotlin versions up to 2.2.2\ *x* are now supported. diff --git a/docs/codeql/codeql-overview/codeql-changelog/index.rst b/docs/codeql/codeql-overview/codeql-changelog/index.rst index 53603bb44a34..dcf6c7bcba02 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/index.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/index.rst @@ -11,6 +11,8 @@ A list of queries for each suite and language `is available here ; diff --git a/go/ql/src/change-notes/released/1.4.2.md b/go/ql/src/change-notes/released/1.4.2.md new file mode 100644 index 000000000000..37be01f40d98 --- /dev/null +++ b/go/ql/src/change-notes/released/1.4.2.md @@ -0,0 +1,3 @@ +## 1.4.2 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 43ccf4467bed..a76cacdf7997 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.4.1 +lastReleaseVersion: 1.4.2 diff --git a/go/ql/src/experimental/CWE-1004/AuthCookie.qll b/go/ql/src/experimental/CWE-1004/AuthCookie.qll index 411da5a79fa0..b16f09ac1858 100644 --- a/go/ql/src/experimental/CWE-1004/AuthCookie.qll +++ b/go/ql/src/experimental/CWE-1004/AuthCookie.qll @@ -116,6 +116,12 @@ private module BoolToGinSetCookieTrackingConfig implements DataFlow::ConfigSig { ) ) } + + predicate observeDiffInformedIncrementalMode() { + any() // Merged with other flows in CookieWithoutHttpOnly.ql + } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } } /** diff --git a/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll b/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll index 2f2ca94fa87f..33e6c6c01440 100644 --- a/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll +++ b/go/ql/src/experimental/CWE-807/SensitiveConditionBypass.qll @@ -59,6 +59,14 @@ private module Config implements DataFlow::ConfigSig { not c.isPotentialFalsePositive() ) } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + exists(ComparisonExpr comp | result = comp.getLocation() | sink.asExpr() = comp.getAnOperand()) + } } /** diff --git a/go/ql/src/experimental/CWE-840/ConditionalBypass.ql b/go/ql/src/experimental/CWE-840/ConditionalBypass.ql index b70be1ff42db..64f7c3c9ac21 100644 --- a/go/ql/src/experimental/CWE-840/ConditionalBypass.ql +++ b/go/ql/src/experimental/CWE-840/ConditionalBypass.ql @@ -22,6 +22,10 @@ module Config implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { exists(ComparisonExpr c | c.getAnOperand() = sink.asExpr()) } + + predicate observeDiffInformedIncrementalMode() { + none() // can't override the locations accurately because of secondary use of config. + } } /** Tracks taint flow for reasoning about conditional bypass. */ diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index b1374da8a5f7..05abe7bf8e47 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -30,6 +30,14 @@ module ServerSideRequestForgery { predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } predicate isBarrierOut(DataFlow::Node node) { node instanceof SanitizerEdge } + + predicate observeDiffInformedIncrementalMode() { any() } + + Location getASelectedSourceLocation(DataFlow::Node source) { none() } + + Location getASelectedSinkLocation(DataFlow::Node sink) { + result = sink.(Sink).getARequest().getLocation() + } } /** Tracks taint flow for reasoning about request forgery vulnerabilities. */ diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 67b9ff12d462..d3c411a74f79 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.4.1 +version: 1.4.3-dev groups: - go - queries diff --git a/java/kotlin-extractor/BUILD.bazel b/java/kotlin-extractor/BUILD.bazel index 575b9788e8c5..a714e06d4111 100644 --- a/java/kotlin-extractor/BUILD.bazel +++ b/java/kotlin-extractor/BUILD.bazel @@ -83,7 +83,7 @@ kt_javac_options( "kotlin.RequiresOptIn", "org.jetbrains.kotlin.ir.symbols.%s" % ("IrSymbolInternals" if version_less(v, "2.0.0") else "UnsafeDuringIrConstructionAPI"), - ], + ] + ([] if version_less(v, "2.2.20") else ["org.jetbrains.kotlin.DeprecatedForRemovalCompilerApi"]), x_suppress_version_warnings = True, ), # * extractor.name is different for each version, so we need to put it in different output dirs diff --git a/java/kotlin-extractor/deps/kotlin-compiler-2.2.20-Beta2.jar b/java/kotlin-extractor/deps/kotlin-compiler-2.2.20-Beta2.jar new file mode 100644 index 000000000000..8e720a86a1d4 --- /dev/null +++ b/java/kotlin-extractor/deps/kotlin-compiler-2.2.20-Beta2.jar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7f4befaac8055b86f648e82c13b86e2775d7ace4eb896e2d7a5b8669a0f29a7 +size 58317000 diff --git a/java/kotlin-extractor/deps/kotlin-compiler-embeddable-2.2.20-Beta2.jar b/java/kotlin-extractor/deps/kotlin-compiler-embeddable-2.2.20-Beta2.jar new file mode 100644 index 000000000000..db9a090c35be --- /dev/null +++ b/java/kotlin-extractor/deps/kotlin-compiler-embeddable-2.2.20-Beta2.jar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6017df3eca219e1c970468631f81333bfd8739482a5de4d33688949b5a1af376 +size 56885422 diff --git a/java/kotlin-extractor/deps/kotlin-stdlib-2.2.20-Beta2.jar b/java/kotlin-extractor/deps/kotlin-stdlib-2.2.20-Beta2.jar new file mode 100644 index 000000000000..a6b812f7cea2 --- /dev/null +++ b/java/kotlin-extractor/deps/kotlin-stdlib-2.2.20-Beta2.jar @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d01259e6090de3ff8e938144970980978eb4e764d755a70d4cd077552315a39c +size 1761449 diff --git a/java/kotlin-extractor/dev/wrapper.py b/java/kotlin-extractor/dev/wrapper.py index 08969528c926..aeef81e5c1d2 100755 --- a/java/kotlin-extractor/dev/wrapper.py +++ b/java/kotlin-extractor/dev/wrapper.py @@ -27,7 +27,7 @@ import io import os -DEFAULT_VERSION = "2.1.20" +DEFAULT_VERSION = "2.2.0" def options(): diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 56deb81da012..2f87c77f8ee1 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -37,7 +37,6 @@ import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability -import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.name.SpecialNames diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_0/getJvmModuleNameForDeserializedDescriptor.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_0/getJvmModuleNameForDeserializedDescriptor.kt new file mode 100644 index 000000000000..003be521ce0e --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_0/getJvmModuleNameForDeserializedDescriptor.kt @@ -0,0 +1,9 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor + +fun getJvmModuleNameForDeserializedDescriptor(descriptor: CallableMemberDescriptor): String? { + return org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor(descriptor) +} + diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_2_20-Beta2/getJvmModuleNameForDeserializedDescriptor.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_2_20-Beta2/getJvmModuleNameForDeserializedDescriptor.kt new file mode 100644 index 000000000000..7a29d2dd4fc3 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_2_20-Beta2/getJvmModuleNameForDeserializedDescriptor.kt @@ -0,0 +1,32 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource +import org.jetbrains.kotlin.metadata.deserialization.* +import org.jetbrains.kotlin.metadata.jvm.deserialization.* +import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf +import org.jetbrains.kotlin.resolve.DescriptorUtils.* +import org.jetbrains.kotlin.serialization.deserialization.descriptors.* + +fun getJvmModuleNameForDeserializedDescriptor(descriptor: CallableMemberDescriptor): String? { + val parent = getParentOfType(descriptor, ClassOrPackageFragmentDescriptor::class.java, false) + + when { + parent is DeserializedClassDescriptor -> { + val classProto = parent.classProto + val nameResolver = parent.c.nameResolver + return classProto.getExtensionOrNull(JvmProtoBuf.classModuleName) + ?.let(nameResolver::getString) + ?: JvmProtoBufUtil.DEFAULT_MODULE_NAME + } + descriptor is DeserializedMemberDescriptor -> { + val source = descriptor.containerSource + if (source is JvmPackagePartSource) { + return source.moduleName + } + } + } + + return null +} + diff --git a/java/kotlin-extractor/versions.bzl b/java/kotlin-extractor/versions.bzl index e389bfd9514d..95897f49cc81 100644 --- a/java/kotlin-extractor/versions.bzl +++ b/java/kotlin-extractor/versions.bzl @@ -12,6 +12,7 @@ VERSIONS = [ "2.1.0-Beta1", "2.1.20-Beta1", "2.2.0-Beta1", + "2.2.20-Beta2", ] def _version_to_tuple(v): diff --git a/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/test.py b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/test.py index e3a791a59f3d..67b5dde772eb 100644 --- a/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/test.py +++ b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/test.py @@ -1,2 +1,2 @@ -def test(codeql, use_java_11, java, android_sdk): +def test(codeql, use_java_17, java, android_sdk): codeql.database.create() diff --git a/java/ql/integration-tests/java/android-sample-no-wrapper/test.py b/java/ql/integration-tests/java/android-sample-no-wrapper/test.py index e3a791a59f3d..67b5dde772eb 100644 --- a/java/ql/integration-tests/java/android-sample-no-wrapper/test.py +++ b/java/ql/integration-tests/java/android-sample-no-wrapper/test.py @@ -1,2 +1,2 @@ -def test(codeql, use_java_11, java, android_sdk): +def test(codeql, use_java_17, java, android_sdk): codeql.database.create() diff --git a/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py index ca4ae04350fe..5730f55d9819 100644 --- a/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py +++ b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py @@ -1,2 +1,2 @@ -def test(codeql, use_java_11, java, android_sdk, actions_toolchains_file): +def test(codeql, use_java_17, java, android_sdk, actions_toolchains_file): codeql.database.create(_env={"LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": str(actions_toolchains_file)}) diff --git a/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/test.py b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/test.py index ca4ae04350fe..5730f55d9819 100644 --- a/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/test.py +++ b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/test.py @@ -1,2 +1,2 @@ -def test(codeql, use_java_11, java, android_sdk, actions_toolchains_file): +def test(codeql, use_java_17, java, android_sdk, actions_toolchains_file): codeql.database.create(_env={"LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": str(actions_toolchains_file)}) diff --git a/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/diagnostics.expected b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/diagnostics.expected index 39e1f6e6b984..50cbd2609f26 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/diagnostics.expected +++ b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/diagnostics.expected @@ -1,5 +1,5 @@ { - "markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 2.2.10.", + "markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 2.2.30.", "severity": "error", "source": { "extractorName": "java", diff --git a/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.ext.yml b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.ext.yml index 3b6ffa4a3771..e4f5148ee404 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.ext.yml +++ b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-queries + pack: codeql/java-all extensible: extractorInformationSkipKey data: # These will have unstable values, as they are dependent on the diff --git a/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.ext.yml b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.ext.yml index be02d9554f81..6d95b68726ae 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.ext.yml +++ b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-queries + pack: codeql/java-all extensible: extractorInformationSkipKey data: # These will have unstable values, as they are dependent on the diff --git a/java/ql/integration-tests/kotlin/linux/custom_plugin/test.py b/java/ql/integration-tests/kotlin/linux/custom_plugin/test.py-disabled similarity index 91% rename from java/ql/integration-tests/kotlin/linux/custom_plugin/test.py rename to java/ql/integration-tests/kotlin/linux/custom_plugin/test.py-disabled index f9da92683868..2b3a104ed0b1 100644 --- a/java/ql/integration-tests/kotlin/linux/custom_plugin/test.py +++ b/java/ql/integration-tests/kotlin/linux/custom_plugin/test.py-disabled @@ -3,6 +3,8 @@ import commands +# This test is temporarily disabled until it is updated to work with Kotlin 2.2 + @runs_on.linux def test(codeql, java_full, cwd, semmle_code_dir, test_dir): build_dir = cwd / "build" diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index d48e225f5a0d..e15d695efea6 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 7.5.0 + +### New Features + +* Kotlin versions up to 2.2.2\ *x* are now supported. + ## 7.4.0 ### Deprecated APIs @@ -10,7 +16,7 @@ ### New Features -* You can now add sinks for the query "Deserialization of user-controlled data" (`java/unsafe-deserialization`) using [data extensions](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/#extensible-predicates-used-to-create-custom-models-in-java-and-kotlin) by extending `sinkModel` and using the kind "unsafe-deserialization". The existing sinks which do not require extra logic to determine if they are unsafe are now defined in this way. +* You can now add sinks for the query "Deserialization of user-controlled data" (`java/unsafe-deserialization`) using [data extensions](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-java-and-kotlin/#extensible-predicates-used-to-create-custom-models-in-java-and-kotlin) by extending `sinkModel` and using the kind "unsafe-deserialization". The existing sinks that do not require extra logic to determine if they are unsafe are now defined in this way. ### Minor Analysis Improvements diff --git a/java/ql/lib/change-notes/2025-07-28-guardwrappers.md b/java/ql/lib/change-notes/2025-07-28-guardwrappers.md new file mode 100644 index 000000000000..cf976fe77896 --- /dev/null +++ b/java/ql/lib/change-notes/2025-07-28-guardwrappers.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Guard implication logic involving wrapper methods has been improved. In particular, this means fewer false positives for `java/dereferenced-value-may-be-null`. diff --git a/java/ql/lib/change-notes/2025-08-15-lib-models-remotesource.md b/java/ql/lib/change-notes/2025-08-15-lib-models-remotesource.md new file mode 100644 index 000000000000..3cb81f840197 --- /dev/null +++ b/java/ql/lib/change-notes/2025-08-15-lib-models-remotesource.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* Added library models for the relevant method calls under `jakarta.servlet.ServletRequest` and `jakarta.servlet.http.HttpServletRequest` as remote flow sources. diff --git a/java/ql/lib/change-notes/released/7.5.0.md b/java/ql/lib/change-notes/released/7.5.0.md new file mode 100644 index 000000000000..415dab5dfe4f --- /dev/null +++ b/java/ql/lib/change-notes/released/7.5.0.md @@ -0,0 +1,5 @@ +## 7.5.0 + +### New Features + +* Kotlin versions up to 2.2.2\ *x* are now supported. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index be55351642c4..7ed5cb290ca0 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.4.0 +lastReleaseVersion: 7.5.0 diff --git a/java/ql/lib/ext/jakarta.servlet.http.model.yml b/java/ql/lib/ext/jakarta.servlet.http.model.yml index 5a83b1ac08d8..fabbe4a3eb0e 100644 --- a/java/ql/lib/ext/jakarta.servlet.http.model.yml +++ b/java/ql/lib/ext/jakarta.servlet.http.model.yml @@ -4,3 +4,15 @@ extensions: extensible: sourceModel data: - ["jakarta.servlet.http", "HttpServletRequest", True, "getServletPath", "", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getHeader", "(String)", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getHeaderNames", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getHeaders", "(String)", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getParameter", "(String)", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getParameterValues", "(String)", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getPathInfo", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getQueryString", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getRemoteUser", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getRequestURI", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet.http", "HttpServletRequest", False, "getRequestURL", "()", "", "ReturnValue", "remote", "manual"] diff --git a/java/ql/lib/ext/jakarta.servlet.model.yml b/java/ql/lib/ext/jakarta.servlet.model.yml index be2feeb3c375..ad1a38bb4bfe 100644 --- a/java/ql/lib/ext/jakarta.servlet.model.yml +++ b/java/ql/lib/ext/jakarta.servlet.model.yml @@ -1,4 +1,14 @@ extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["jakarta.servlet", "ServletRequest", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet", "ServletRequest", False, "getParameter", "(String)", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet", "ServletRequest", False, "getParameterMap", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet", "ServletRequest", False, "getParameterNames", "()", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet", "ServletRequest", False, "getParameterValues", "(String)", "", "ReturnValue", "remote", "manual"] + - ["jakarta.servlet", "ServletRequest", False, "getReader", "()", "", "ReturnValue", "remote", "manual"] - addsTo: pack: codeql/java-all extensible: sinkModel diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 6bbd17fda1d6..0e69cc38681c 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 7.4.0 +version: 7.5.1-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll index 612bca35a600..c1c19fa44508 100644 --- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll @@ -347,12 +347,28 @@ private module ControlFlowGraphImpl { ) } + private predicate methodMayThrow(Method m, ThrowableType t) { + exists(AstNode n | + t = n.(ThrowStmt).getThrownExceptionType() and + not n.(ThrowStmt).getParent() = any(Method m0).getBody() + or + uncheckedExceptionFromMethod(n, t) + | + n.getEnclosingStmt().getEnclosingCallable() = m and + not exists(TryStmt try | + exists(try.getACatchClause()) and try.getBlock() = n.getEnclosingStmt().getEnclosingStmt*() + ) + ) + } + /** - * Bind `t` to an unchecked exception that may occur in a precondition check. + * Bind `t` to an unchecked exception that may occur in a precondition check or guard wrapper. */ private predicate uncheckedExceptionFromMethod(MethodCall ma, ThrowableType t) { conditionCheckArgument(ma, _, _) and (t instanceof TypeError or t instanceof TypeRuntimeException) + or + methodMayThrow(ma.getMethod(), t) } /** diff --git a/java/ql/lib/semmle/code/java/Diagnostics.qll b/java/ql/lib/semmle/code/java/Diagnostics.qll index c93e6850b3de..8a4b543aa4a1 100644 --- a/java/ql/lib/semmle/code/java/Diagnostics.qll +++ b/java/ql/lib/semmle/code/java/Diagnostics.qll @@ -61,3 +61,9 @@ class Diagnostic extends @diagnostic { /** Gets a textual representation of this diagnostic. */ string toString() { result = this.getMessage() } } + +/** + * Holds for extraction information keys that should be skipped from telemetry reports. + * This predicate can be extended by other packs to filter out specific telemetry keys. + */ +extensible predicate extractorInformationSkipKey(string key); diff --git a/java/ql/lib/semmle/code/java/Member.qll b/java/ql/lib/semmle/code/java/Member.qll index 1e814117e9ee..7d84dbd379d0 100644 --- a/java/ql/lib/semmle/code/java/Member.qll +++ b/java/ql/lib/semmle/code/java/Member.qll @@ -256,7 +256,15 @@ class Callable extends StmtParent, Member, @callable { Exception getAnException() { exceptions(result, _, this) } /** Gets an exception type that occurs in the `throws` clause of this callable. */ - RefType getAThrownExceptionType() { result = this.getAnException().getType() } + RefType getAThrownExceptionType() { + result = this.getAnException().getType() + or + exists(Annotation a | + this.getAnAnnotation() = a and + a.getType().hasQualifiedName("kotlin.jvm", "Throws") and + a.getATypeArrayValue(_) = result + ) + } /** Gets a call site that references this callable. */ Call getAReference() { result.getCallee() = this } diff --git a/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll b/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll index 844371da36b8..e974f711ec45 100644 --- a/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll +++ b/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll @@ -57,7 +57,7 @@ private module Input implements BB::InputSig { * Holds if `node` represents an exit node to be used when calculating * post dominance. */ - predicate nodeIsPostDominanceExit(Node node) { node instanceof ControlFlow::ExitNode } + predicate nodeIsPostDominanceExit(Node node) { node instanceof ControlFlow::NormalExitNode } } private module BbImpl = BB::Make; diff --git a/java/ql/lib/semmle/code/java/controlflow/Guards.qll b/java/ql/lib/semmle/code/java/controlflow/Guards.qll index 8cead5b666bb..778ebe6e8789 100644 --- a/java/ql/lib/semmle/code/java/controlflow/Guards.qll +++ b/java/ql/lib/semmle/code/java/controlflow/Guards.qll @@ -146,6 +146,8 @@ private module GuardsInput implements SharedGuards::InputSig { class ControlFlowNode = J::ControlFlowNode; + class NormalExitNode = ControlFlow::NormalExitNode; + class BasicBlock = J::BasicBlock; predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) { J::dominatingEdge(bb1, bb2) } @@ -322,6 +324,55 @@ private module GuardsInput implements SharedGuards::InputSig { Expr getElse() { result = super.getFalseExpr() } } + + class Parameter = J::Parameter; + + private int parameterPosition() { result in [-1, any(Parameter p).getPosition()] } + + /** A parameter position represented by an integer. */ + class ParameterPosition extends int { + ParameterPosition() { this = parameterPosition() } + } + + /** An argument position represented by an integer. */ + class ArgumentPosition extends int { + ArgumentPosition() { this = parameterPosition() } + } + + /** Holds if arguments at position `apos` match parameters at position `ppos`. */ + overlay[caller?] + pragma[inline] + predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } + + final private class FinalMethod = Method; + + class NonOverridableMethod extends FinalMethod { + NonOverridableMethod() { not super.isOverridable() } + + Parameter getParameter(ParameterPosition ppos) { + super.getParameter(ppos) = result and + not result.isVarargs() + } + + GuardsInput::Expr getAReturnExpr() { + exists(ReturnStmt ret | + this = ret.getEnclosingCallable() and + ret.getResult() = result + ) + } + } + + private predicate nonOverridableMethodCall(MethodCall call, NonOverridableMethod m) { + call.getMethod().getSourceDeclaration() = m + } + + class NonOverridableMethodCall extends GuardsInput::Expr instanceof MethodCall { + NonOverridableMethodCall() { nonOverridableMethodCall(this, _) } + + NonOverridableMethod getMethod() { nonOverridableMethodCall(this, result) } + + GuardsInput::Expr getArgument(ArgumentPosition apos) { result = super.getArgument(apos) } + } } private module GuardsImpl = SharedGuards::Make; @@ -340,6 +391,17 @@ private module LogicInputCommon { NullGuards::nullCheckMethod(call.getMethod(), val.asBooleanValue(), isNull) ) } + + predicate additionalImpliesStep( + GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2 + ) { + exists(MethodCall check, int argIndex | + g1 = check and + v1.getDualValue().isThrowsException() and + conditionCheckArgument(check, argIndex, v2.asBooleanValue()) and + g2 = check.getArgument(argIndex) + ) + } } private module LogicInput_v1 implements GuardsImpl::LogicInputSig { @@ -364,18 +426,13 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig { } } + predicate parameterDefinition(Parameter p, SsaDefinition def) { + def.(BaseSsaImplicitInit).isParameterDefinition(p) + } + predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4; - predicate additionalImpliesStep( - GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2 - ) { - exists(MethodCall check, int argIndex | - g1 = check and - v1.getDualValue().isThrowsException() and - conditionCheckArgument(check, argIndex, v2.asBooleanValue()) and - g2 = check.getArgument(argIndex) - ) - } + predicate additionalImpliesStep = LogicInputCommon::additionalImpliesStep/4; } private module LogicInput_v2 implements GuardsImpl::LogicInputSig { @@ -400,15 +457,13 @@ private module LogicInput_v2 implements GuardsImpl::LogicInputSig { } } + predicate parameterDefinition(Parameter p, SsaDefinition def) { + def.(SSA::SsaImplicitInit).isParameterDefinition(p) + } + predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4; - predicate additionalImpliesStep( - GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2 - ) { - LogicInput_v1::additionalImpliesStep(g1, v1, g2, v2) - or - CustomGuard::additionalImpliesStep(g1, v1, g2, v2) - } + predicate additionalImpliesStep = LogicInputCommon::additionalImpliesStep/4; } private module LogicInput_v3 implements GuardsImpl::LogicInputSig { @@ -421,70 +476,11 @@ private module LogicInput_v3 implements GuardsImpl::LogicInputSig { predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4; - predicate additionalImpliesStep = LogicInput_v2::additionalImpliesStep/4; -} - -private module CustomGuardInput implements Guards_v2::CustomGuardInputSig { - private import semmle.code.java.dataflow.SSA - - private int parameterPosition() { result in [-1, any(Parameter p).getPosition()] } - - /** A parameter position represented by an integer. */ - class ParameterPosition extends int { - ParameterPosition() { this = parameterPosition() } - } - - /** An argument position represented by an integer. */ - class ArgumentPosition extends int { - ArgumentPosition() { this = parameterPosition() } - } - - /** Holds if arguments at position `apos` match parameters at position `ppos`. */ - overlay[caller?] - pragma[inline] - predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } - - final private class FinalMethod = Method; - - class BooleanMethod extends FinalMethod { - BooleanMethod() { - super.getReturnType().(PrimitiveType).hasName("boolean") and - not super.isOverridable() - } - - LogicInput_v2::SsaDefinition getParameter(ParameterPosition ppos) { - exists(Parameter p | - super.getParameter(ppos) = p and - not p.isVarargs() and - result.(SsaImplicitInit).isParameterDefinition(p) - ) - } - - GuardsInput::Expr getAReturnExpr() { - exists(ReturnStmt ret | - this = ret.getEnclosingCallable() and - ret.getResult() = result - ) - } - } - - private predicate booleanMethodCall(MethodCall call, BooleanMethod m) { - call.getMethod().getSourceDeclaration() = m - } - - class BooleanMethodCall extends GuardsInput::Expr instanceof MethodCall { - BooleanMethodCall() { booleanMethodCall(this, _) } - - BooleanMethod getMethod() { booleanMethodCall(this, result) } - - GuardsInput::Expr getArgument(ArgumentPosition apos) { result = super.getArgument(apos) } - } + predicate additionalImpliesStep = LogicInputCommon::additionalImpliesStep/4; } class GuardValue = GuardsImpl::GuardValue; -private module CustomGuard = Guards_v2::CustomGuard; - /** INTERNAL: Don't use. */ module Guards_v1 = GuardsImpl::Logic; @@ -494,12 +490,6 @@ module Guards_v2 = GuardsImpl::Logic; /** INTERNAL: Don't use. */ module Guards_v3 = GuardsImpl::Logic; -/** INTERNAL: Don't use. */ -predicate implies_v3(Guard g1, boolean b1, Guard g2, boolean b2) { - Guards_v3::boolImplies(g1, any(GuardValue v | v.asBooleanValue() = b1), g2, - any(GuardValue v | v.asBooleanValue() = b2)) -} - /** * A guard. This may be any expression whose value determines subsequent * control flow. It may also be a switch case, which as a guard is considered diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 164e2d8aa262..8b9087ecbdc5 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -348,6 +348,16 @@ predicate expectsContent(Node n, ContentSet c) { FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) } +pragma[nomagic] +private predicate numericRepresentative(RefType t) { + t.(BoxedType).getPrimitiveType().getName() = "double" +} + +pragma[nomagic] +private predicate booleanRepresentative(RefType t) { + t.(BoxedType).getPrimitiveType().getName() = "boolean" +} + /** * Gets a representative (boxed) type for `t` for the purpose of pruning * possible flow. A single type is used for all numeric types to account for @@ -356,10 +366,10 @@ predicate expectsContent(Node n, ContentSet c) { RefType getErasedRepr(Type t) { exists(Type e | e = t.getErasure() | if e instanceof NumericOrCharType - then result.(BoxedType).getPrimitiveType().getName() = "double" + then numericRepresentative(result) else if e instanceof BooleanType - then result.(BoxedType).getPrimitiveType().getName() = "boolean" + then booleanRepresentative(result) else result = e ) or diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll index 45ad9d0a73b7..51da69e9d64a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll @@ -562,14 +562,20 @@ private module Cached { cached // nothing is actually cached module BarrierGuard { - private predicate guardChecksAdjTypes( - DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch - ) { + private predicate guardChecksAdjTypes(Guards::Guards_v3::Guard g, Expr e, boolean branch) { guardChecks(g, e, branch) } + private predicate guardChecksWithWrappers( + DataFlowIntegrationInput::Guard g, Definition def, Guards::GuardValue val, Unit state + ) { + Guards::Guards_v3::ValidationWrapper::guardChecksDef(g, def, val) and + exists(state) + } + private Node getABarrierNodeImpl() { - result = DataFlowIntegrationImpl::BarrierGuard::getABarrierNode() + result = + DataFlowIntegrationImpl::BarrierGuardDefWithState::getABarrierNode(_) } predicate getABarrierNode = getABarrierNodeImpl/0; @@ -657,16 +663,18 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu def instanceof SsaUncertainImplicitUpdate } + class GuardValue = Guards::GuardValue; + class Guard = Guards::Guard; - /** Holds if the guard `guard` directly controls block `bb` upon evaluating to `branch`. */ - predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) { - guard.directlyControls(bb, branch) + /** Holds if the guard `guard` directly controls block `bb` upon evaluating to `val`. */ + predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, GuardValue val) { + guard.directlyValueControls(bb, val) } - /** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */ - predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) { - guard.controls(bb, branch) + /** Holds if the guard `guard` controls block `bb` upon evaluating to `val`. */ + predicate guardControlsBlock(Guard guard, BasicBlock bb, GuardValue val) { + guard.valueControls(bb, val) } predicate includeWriteDefsInFlowStep() { none() } diff --git a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll index 12fe1cba5e99..86915f802743 100644 --- a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll +++ b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll @@ -214,24 +214,35 @@ private predicate relevantNode(ObjNode n) { exists(ObjNode mid | relevantNode(mid) and objStep(mid, n) and relevantNodeBack(n)) } -pragma[noinline] -private predicate objStepPruned(ObjNode n1, ObjNode n2) { - objStep(n1, n2) and relevantNode(n1) and relevantNode(n2) +private newtype TObjFlowNode = + TObjNode(ObjNode n) { relevantNode(n) } or + TObjType(RefType t) { source(t, _) } + +private predicate objStepPruned(TObjFlowNode node1, TObjFlowNode node2) { + exists(ObjNode n1, ObjNode n2 | + node1 = TObjNode(n1) and + node2 = TObjNode(n2) and + objStep(n1, n2) + ) + or + exists(RefType t, ObjNode n | + node1 = TObjType(t) and + node2 = TObjNode(n) and + source(t, n) + ) } -private predicate stepPlus(Node n1, Node n2) = fastTC(objStepPruned/2)(n1, n2) +private predicate flowSrc(TObjFlowNode src) { src instanceof TObjType } + +private predicate flowSink(TObjFlowNode sink) { exists(ObjNode n | sink = TObjNode(n) and sink(n)) } + +private predicate stepPlus(TObjFlowNode n1, TObjFlowNode n2) = + doublyBoundedFastTC(objStepPruned/2, flowSrc/1, flowSink/1)(n1, n2) /** * Holds if the qualifier `n` of an `Object.toString()` call might have type `t`. */ -pragma[noopt] -private predicate objType(ObjNode n, RefType t) { - exists(ObjNode n2 | - sink(n) and - (stepPlus(n2, n) or n2 = n) and - source(t, n2) - ) -} +private predicate objType(ObjNode n, RefType t) { stepPlus(TObjType(t), TObjNode(n)) } private VirtualMethodCall objectToString(ObjNode n) { result.getQualifier() = n.asExpr() and sink(n) diff --git a/java/ql/lib/semmle/code/java/security/ArithmeticCommon.qll b/java/ql/lib/semmle/code/java/security/ArithmeticCommon.qll index e0d6ff305c30..4f4c20a5263b 100644 --- a/java/ql/lib/semmle/code/java/security/ArithmeticCommon.qll +++ b/java/ql/lib/semmle/code/java/security/ArithmeticCommon.qll @@ -20,16 +20,16 @@ predicate narrowerThanOrEqualTo(ArithExpr exp, NumType numType) { exists(CastingExpr cast | cast.getAChildExpr() = exp | numType.widerThanOrEqualTo(cast.getType())) } -private Guard sizeGuard(SsaVariable v, boolean branch, boolean upper) { +private Guard sizeGuard(Expr e, boolean branch, boolean upper) { exists(ComparisonExpr comp | comp = result | - comp.getLesserOperand() = ssaRead(v, 0) and + comp.getLesserOperand() = e and ( branch = true and upper = true or branch = false and upper = false ) or - comp.getGreaterOperand() = ssaRead(v, 0) and + comp.getGreaterOperand() = e and ( branch = true and upper = false or @@ -38,7 +38,7 @@ private Guard sizeGuard(SsaVariable v, boolean branch, boolean upper) { or exists(MethodCall ma | ma.getMethod() instanceof MethodAbs and - ma.getArgument(0) = ssaRead(v, 0) and + ma.getArgument(0) = e and ( comp.getLesserOperand() = ma and branch = true or @@ -49,7 +49,7 @@ private Guard sizeGuard(SsaVariable v, boolean branch, boolean upper) { or // overflow test exists(AddExpr add, VarRead use, Expr pos | - use = ssaRead(v, 0) and + use = e and add.hasOperands(use, pos) and positive(use) and positive(pos) and @@ -65,70 +65,38 @@ private Guard sizeGuard(SsaVariable v, boolean branch, boolean upper) { ) ) or - result.isEquality(ssaRead(v, 0), _, branch) and + result.isEquality(e, _, branch) and (upper = true or upper = false) - or - exists(MethodCall call, Method m, int ix | - call = result and - call.getArgument(ix) = ssaRead(v, 0) and - call.getMethod().getSourceDeclaration() = m and - m = customSizeGuard(ix, branch, upper) - ) } -private Guard derivedSizeGuard(SsaVariable v, boolean branch, boolean upper) { - result = sizeGuard(v, branch, upper) or - exists(boolean branch0 | implies_v3(result, branch, derivedSizeGuard(v, branch0, upper), branch0)) +private predicate sizeGuardLessThan(Guard g, Expr e, boolean branch) { + g = sizeGuard(e, branch, true) } -private Method customSizeGuard(int index, boolean retval, boolean upper) { - exists(Parameter p, SsaImplicitInit v | - result.getReturnType().(PrimitiveType).hasName("boolean") and - not result.isOverridable() and - p.getCallable() = result and - not p.isVarargs() and - p.getType() instanceof NumericOrCharType and - p.getPosition() = index and - v.isParameterDefinition(p) and - forex(ReturnStmt ret | - ret.getEnclosingCallable() = result and - exists(Expr res | res = ret.getResult() | - not res.(BooleanLiteral).getBooleanValue() = retval.booleanNot() - ) - | - ret.getResult() = derivedSizeGuard(v, retval, upper) - ) - ) +private predicate sizeGuardGreaterThan(Guard g, Expr e, boolean branch) { + g = sizeGuard(e, branch, false) } /** - * Holds if `e` is bounded in a way that is likely to prevent overflow. + * Holds if `n` is bounded in a way that is likely to prevent overflow. */ -predicate guardedLessThanSomething(Expr e) { - exists(SsaVariable v, Guard guard, boolean branch | - e = v.getAUse() and - guard = sizeGuard(v.getAPhiInputOrPriorDef*(), branch, true) and - guard.controls(e.getBasicBlock(), branch) - ) +predicate guardedLessThanSomething(DataFlow::Node n) { + DataFlow::BarrierGuard::getABarrierNode() = n or - negative(e) + negative(n.asExpr()) or - e.(MethodCall).getMethod() instanceof MethodMathMin + n.asExpr().(MethodCall).getMethod() instanceof MethodMathMin } /** * Holds if `e` is bounded in a way that is likely to prevent underflow. */ -predicate guardedGreaterThanSomething(Expr e) { - exists(SsaVariable v, Guard guard, boolean branch | - e = v.getAUse() and - guard = sizeGuard(v.getAPhiInputOrPriorDef*(), branch, false) and - guard.controls(e.getBasicBlock(), branch) - ) +predicate guardedGreaterThanSomething(DataFlow::Node n) { + DataFlow::BarrierGuard::getABarrierNode() = n or - positive(e) + positive(n.asExpr()) or - e.(MethodCall).getMethod() instanceof MethodMathMax + n.asExpr().(MethodCall).getMethod() instanceof MethodMathMax } /** Holds if `e` occurs in a context where it will be upcast to a wider type. */ @@ -182,7 +150,7 @@ private predicate unlikelyNode(DataFlow::Node n) { /** Holds if `n` is likely guarded against overflow. */ predicate overflowBarrier(DataFlow::Node n) { n.getType() instanceof BooleanType or - guardedLessThanSomething(n.asExpr()) or + guardedLessThanSomething(n) or unlikelyNode(n) or upcastToWiderType(n.asExpr()) or overflowIrrelevant(n.asExpr()) @@ -191,7 +159,7 @@ predicate overflowBarrier(DataFlow::Node n) { /** Holds if `n` is likely guarded against underflow. */ predicate underflowBarrier(DataFlow::Node n) { n.getType() instanceof BooleanType or - guardedGreaterThanSomething(n.asExpr()) or + guardedGreaterThanSomething(n) or unlikelyNode(n) or upcastToWiderType(n.asExpr()) or overflowIrrelevant(n.asExpr()) @@ -210,7 +178,6 @@ predicate overflowSink(ArithExpr exp, VarAccess use) { exp instanceof PostIncExpr or exp instanceof MulExpr ) and - not guardedLessThanSomething(use) and // Exclude widening conversions of tainted values due to binary numeric promotion (JLS 5.6.2) // unless there is an enclosing cast down to a narrower type. narrowerThanOrEqualTo(exp, use.getType()) and @@ -230,7 +197,6 @@ predicate underflowSink(ArithExpr exp, VarAccess use) { exp instanceof PostDecExpr or exp instanceof MulExpr ) and - not guardedGreaterThanSomething(use) and // Exclude widening conversions of tainted values due to binary numeric promotion (JLS 5.6.2) // unless there is an enclosing cast down to a narrower type. narrowerThanOrEqualTo(exp, use.getType()) and diff --git a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll index e789d3c47785..da6f242bde52 100644 --- a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll @@ -13,33 +13,6 @@ private import semmle.code.java.dataflow.Nullness /** A sanitizer that protects against path injection vulnerabilities. */ abstract class PathInjectionSanitizer extends DataFlow::Node { } -/** - * Provides a set of nodes validated by a method that uses a validation guard. - */ -private module ValidationMethod { - /** Gets a node that is safely guarded by a method that uses the given guard check. */ - DataFlow::Node getAValidatedNode() { - exists(MethodCall ma, int pos, VarRead rv | - validationMethod(ma.getMethod(), pos) and - ma.getArgument(pos) = rv and - adjacentUseUseSameVar(rv, result.asExpr()) and - ma.getBasicBlock().dominates(result.asExpr().getBasicBlock()) - ) - } - - /** - * Holds if `m` validates its `arg`th parameter by using `validationGuard`. - */ - private predicate validationMethod(Method m, int arg) { - exists(Guard g, SsaImplicitInit var, ControlFlow::NormalExitNode normexit, boolean branch | - validationGuard(g, var.getAUse(), branch) and - var.isParameterDefinition(m.getParameter(arg)) and - normexit.getEnclosingCallable() = m and - g.controls(normexit.getBasicBlock(), branch) - ) - } -} - /** * Holds if `g` is guard that compares a path to a trusted value. */ @@ -68,8 +41,6 @@ private predicate exactPathMatchGuard(Guard g, Expr e, boolean branch) { class ExactPathMatchSanitizer extends PathInjectionSanitizer { ExactPathMatchSanitizer() { this = DataFlow::BarrierGuard::getABarrierNode() - or - this = ValidationMethod::getAValidatedNode() } } @@ -120,8 +91,7 @@ private predicate allowedPrefixGuard(Guard g, Expr e, boolean branch) { private class AllowedPrefixSanitizer extends PathInjectionSanitizer { AllowedPrefixSanitizer() { - this = DataFlow::BarrierGuard::getABarrierNode() or - this = ValidationMethod::getAValidatedNode() + this = DataFlow::BarrierGuard::getABarrierNode() } } @@ -139,10 +109,7 @@ private predicate dotDotCheckGuard(Guard g, Expr e, boolean branch) { } private class DotDotCheckSanitizer extends PathInjectionSanitizer { - DotDotCheckSanitizer() { - this = DataFlow::BarrierGuard::getABarrierNode() or - this = ValidationMethod::getAValidatedNode() - } + DotDotCheckSanitizer() { this = DataFlow::BarrierGuard::getABarrierNode() } } private class BlockListGuard extends PathGuard instanceof MethodCall { @@ -179,10 +146,7 @@ private predicate blockListGuard(Guard g, Expr e, boolean branch) { } private class BlockListSanitizer extends PathInjectionSanitizer { - BlockListSanitizer() { - this = DataFlow::BarrierGuard::getABarrierNode() or - this = ValidationMethod::getAValidatedNode() - } + BlockListSanitizer() { this = DataFlow::BarrierGuard::getABarrierNode() } } private class ConstantOrRegex extends Expr { @@ -368,7 +332,6 @@ private class FileConstructorChildArgumentStep extends AdditionalTaintStep { n2.asExpr() = constrCall | not n1 = DataFlow::BarrierGuard::getABarrierNode() and - not n1 = ValidationMethod::getAValidatedNode() and not TaintTracking::localExprTaint(any(PathNormalizeSanitizer p), n1.asExpr()) or DataFlow::localExprFlow(nullExpr(), constrCall.getArgument(0)) @@ -546,7 +509,6 @@ private predicate directoryCharactersGuard(Guard g, Expr e, boolean branch) { private class DirectoryCharactersSanitizer extends PathInjectionSanitizer { DirectoryCharactersSanitizer() { this.asExpr() instanceof ReplaceDirectoryCharactersSanitizer or - this = DataFlow::BarrierGuard::getABarrierNode() or - this = ValidationMethod::getAValidatedNode() + this = DataFlow::BarrierGuard::getABarrierNode() } } diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 50afa2ea9bfb..9d630f16f4bd 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.2 + +No user-facing changes. + ## 1.6.1 ### Minor Analysis Improvements diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseType.qll b/java/ql/src/Likely Bugs/Resource Leaks/CloseType.qll index 41239f249a27..aca95c9bc1f5 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseType.qll +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseType.qll @@ -212,33 +212,35 @@ private LocalVariableDecl getCloseableVariable(CloseableInitExpr cie) { /** * A variable on which a "close" method is called, implicitly or explicitly, directly or indirectly. */ -private predicate closeCalled(Variable v) { +private predicate closeCalled(LocalScopeVariable v) { // `close()` is implicitly called on variables declared or referenced // in the resources clause of try-with-resource statements. exists(TryStmt try | try.getAResourceVariable() = v) or // Otherwise, there should be an explicit call to a method whose name contains "close". exists(MethodCall e | - v = getCloseableVariable(_) or v instanceof Parameter or v instanceof LocalVariableDecl - | e.getMethod().getName().toLowerCase().matches("%close%") and exists(VarAccess va | va = v.getAnAccess() | e.getQualifier() = va or e.getAnArgument() = va ) - or - // The "close" call could happen indirectly inside a helper method of unknown name. - exists(int i | e.getArgument(i) = v.getAnAccess() | - exists(Parameter p, int j | p.getPosition() = j and p.getCallable() = e.getMethod() | - closeCalled(p) and i = j - or - // The helper method could be iterating over a varargs parameter. - exists(EnhancedForStmt for | for.getExpr() = p.getAnAccess() | - closeCalled(for.getVariable().getVariable()) - ) and - p.isVarargs() and - j <= i - ) + ) + or + // The "close" call could happen indirectly inside a helper method of unknown name. + exists(Parameter p | + closeCalled(p) and p.getAnArgument() = v.getAnAccess() and p.getCallable() instanceof Method + ) + or + exists(MethodCall e, int i | e.getArgument(i) = v.getAnAccess() | + exists(Parameter p, int j | + p.getPosition() = j and p.getCallable() = e.getMethod().getSourceDeclaration() + | + // The helper method could be iterating over a varargs parameter. + exists(EnhancedForStmt for | for.getExpr() = p.getAnAccess() | + closeCalled(for.getVariable().getVariable()) + ) and + p.isVarargs() and + j <= i ) ) } diff --git a/java/ql/src/Telemetry/ExtractorInformation.ql b/java/ql/src/Telemetry/ExtractorInformation.ql index ea6d6fc2d41e..f5bc8b426972 100644 --- a/java/ql/src/Telemetry/ExtractorInformation.ql +++ b/java/ql/src/Telemetry/ExtractorInformation.ql @@ -10,8 +10,6 @@ import java import semmle.code.java.Diagnostics import DatabaseQuality -extensible predicate extractorInformationSkipKey(string key); - predicate compilationInfo(string key, int value) { exists(Compilation c, string infoKey | key = infoKey + ": " + c.getInfo(infoKey) and diff --git a/java/ql/src/Telemetry/ExtractorInformation.yml b/java/ql/src/Telemetry/ExtractorInformation.yml index 74a7f99520b7..18e691a79e99 100644 --- a/java/ql/src/Telemetry/ExtractorInformation.yml +++ b/java/ql/src/Telemetry/ExtractorInformation.yml @@ -1,5 +1,5 @@ extensions: - addsTo: - pack: codeql/java-queries + pack: codeql/java-all extensible: extractorInformationSkipKey data: [] diff --git a/java/ql/src/change-notes/released/1.6.2.md b/java/ql/src/change-notes/released/1.6.2.md new file mode 100644 index 000000000000..bbe3747556fb --- /dev/null +++ b/java/ql/src/change-notes/released/1.6.2.md @@ -0,0 +1,3 @@ +## 1.6.2 + +No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index ef7a789e0cf1..5f5beb68311a 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.1 +lastReleaseVersion: 1.6.2 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 5e5e73ab721a..aa899419ad90 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.6.1 +version: 1.6.3-dev groups: - java - queries diff --git a/java/ql/test-kotlin1/library-tests/controlflow/basic/strictPostDominance.expected b/java/ql/test-kotlin1/library-tests/controlflow/basic/strictPostDominance.expected index 9971f41a3be2..625fde1c41e5 100644 --- a/java/ql/test-kotlin1/library-tests/controlflow/basic/strictPostDominance.expected +++ b/java/ql/test-kotlin1/library-tests/controlflow/basic/strictPostDominance.expected @@ -208,6 +208,12 @@ | Test.kt:101:5:103:5 | ... -> ... | Test.kt:101:5:103:5 | ; | | Test.kt:101:5:103:5 | ; | Test.kt:100:25:110:1 | { ... } | | Test.kt:102:9:102:25 | throw ... | Test.kt:101:33:103:5 | { ... } | +| Test.kt:105:5:109:5 | ; | Test.kt:100:25:110:1 | { ... } | +| Test.kt:105:5:109:5 | ; | Test.kt:101:5:103:5 | ... -> ... | +| Test.kt:105:5:109:5 | ; | Test.kt:101:5:103:5 | ; | +| Test.kt:105:9:107:5 | ... -> ... | Test.kt:100:25:110:1 | { ... } | +| Test.kt:105:9:107:5 | ... -> ... | Test.kt:101:5:103:5 | ... -> ... | +| Test.kt:105:9:107:5 | ... -> ... | Test.kt:101:5:103:5 | ; | | Test.kt:105:9:107:5 | ... -> ... | Test.kt:105:5:109:5 | ; | | Test.kt:106:9:106:29 | ; | Test.kt:105:20:107:5 | { ... } | | Test.kt:108:9:108:29 | ; | Test.kt:107:27:109:5 | { ... } | diff --git a/java/ql/test-kotlin2/library-tests/annotation_classes/PrintAst.expected b/java/ql/test-kotlin2/library-tests/annotation_classes/PrintAst.expected index dfec79078ce8..1153b13c3bf9 100644 --- a/java/ql/test-kotlin2/library-tests/annotation_classes/PrintAst.expected +++ b/java/ql/test-kotlin2/library-tests/annotation_classes/PrintAst.expected @@ -169,7 +169,18 @@ def.kt: # 33| 0: [SuperConstructorInvocationStmt] super(...) # 33| 1: [BlockStmt] { ... } # 34| 5: [Class] Y -# 34| 2: [Constructor] Y +# 0| 2: [Method] getEntries +# 0| 3: [TypeAccess] EnumEntries +# 0| 0: [TypeAccess] Y +# 0| 3: [Method] valueOf +# 0| 3: [TypeAccess] Y +#-----| 4: (Parameters) +# 34| 0: [Parameter] value +# 34| 0: [TypeAccess] String +# 0| 4: [Method] values +# 0| 3: [TypeAccess] Y[] +# 0| 0: [TypeAccess] Y +# 34| 5: [Constructor] Y # 34| 5: [BlockStmt] { ... } # 34| 0: [ExprStmt] ; # 34| 0: [ClassInstanceExpr] new Enum(...) @@ -178,17 +189,6 @@ def.kt: # 34| 0: [NullLiteral] null # 34| 1: [IntegerLiteral] 0 # 34| 1: [BlockStmt] { ... } -# 34| 3: [Method] getEntries -# 34| 3: [TypeAccess] EnumEntries -# 34| 0: [TypeAccess] Y -# 34| 4: [Method] valueOf -# 34| 3: [TypeAccess] Y -#-----| 4: (Parameters) -# 34| 0: [Parameter] value -# 34| 0: [TypeAccess] String -# 34| 5: [Method] values -# 34| 3: [TypeAccess] Y[] -# 34| 0: [TypeAccess] Y # 35| 6: [FieldDeclaration] Y A; # 35| -1: [TypeAccess] Y # 35| 0: [ClassInstanceExpr] new Y(...) diff --git a/java/ql/test-kotlin2/library-tests/classes/PrintAst.expected b/java/ql/test-kotlin2/library-tests/classes/PrintAst.expected index 4abfda927996..6fe2874402f8 100644 --- a/java/ql/test-kotlin2/library-tests/classes/PrintAst.expected +++ b/java/ql/test-kotlin2/library-tests/classes/PrintAst.expected @@ -160,7 +160,18 @@ classes.kt: # 42| -1: [TypeAccess] int # 42| 0: [IntegerLiteral] 3 # 49| 11: [Class] Direction -# 49| 2: [Constructor] Direction +# 0| 2: [Method] getEntries +# 0| 3: [TypeAccess] EnumEntries +# 0| 0: [TypeAccess] Direction +# 0| 3: [Method] valueOf +# 0| 3: [TypeAccess] Direction +#-----| 4: (Parameters) +# 49| 0: [Parameter] value +# 49| 0: [TypeAccess] String +# 0| 4: [Method] values +# 0| 3: [TypeAccess] Direction[] +# 0| 0: [TypeAccess] Direction +# 49| 5: [Constructor] Direction # 49| 5: [BlockStmt] { ... } # 49| 0: [ExprStmt] ; # 49| 0: [ClassInstanceExpr] new Enum(...) @@ -169,17 +180,6 @@ classes.kt: # 49| 0: [NullLiteral] null # 49| 1: [IntegerLiteral] 0 # 49| 1: [BlockStmt] { ... } -# 49| 3: [Method] getEntries -# 49| 3: [TypeAccess] EnumEntries -# 49| 0: [TypeAccess] Direction -# 49| 4: [Method] valueOf -# 49| 3: [TypeAccess] Direction -#-----| 4: (Parameters) -# 49| 0: [Parameter] value -# 49| 0: [TypeAccess] String -# 49| 5: [Method] values -# 49| 3: [TypeAccess] Direction[] -# 49| 0: [TypeAccess] Direction # 50| 6: [FieldDeclaration] Direction NORTH; # 50| -1: [TypeAccess] Direction # 50| 0: [ClassInstanceExpr] new Direction(...) @@ -197,17 +197,17 @@ classes.kt: # 50| 0: [ClassInstanceExpr] new Direction(...) # 50| -3: [TypeAccess] Direction # 53| 12: [Class] Color -# 53| 2: [Method] getEntries -# 53| 3: [TypeAccess] EnumEntries -# 53| 0: [TypeAccess] Color -# 53| 3: [Method] valueOf -# 53| 3: [TypeAccess] Color +# 0| 2: [Method] getEntries +# 0| 3: [TypeAccess] EnumEntries +# 0| 0: [TypeAccess] Color +# 0| 3: [Method] valueOf +# 0| 3: [TypeAccess] Color #-----| 4: (Parameters) # 53| 0: [Parameter] value # 53| 0: [TypeAccess] String -# 53| 4: [Method] values -# 53| 3: [TypeAccess] Color[] -# 53| 0: [TypeAccess] Color +# 0| 4: [Method] values +# 0| 3: [TypeAccess] Color[] +# 0| 0: [TypeAccess] Color # 53| 5: [Constructor] Color #-----| 4: (Parameters) # 53| 0: [Parameter] rgb diff --git a/java/ql/test-kotlin2/library-tests/controlflow/basic/strictPostDominance.expected b/java/ql/test-kotlin2/library-tests/controlflow/basic/strictPostDominance.expected index 257d82fc1a7f..df70e61a9785 100644 --- a/java/ql/test-kotlin2/library-tests/controlflow/basic/strictPostDominance.expected +++ b/java/ql/test-kotlin2/library-tests/controlflow/basic/strictPostDominance.expected @@ -208,6 +208,12 @@ | Test.kt:101:9:103:5 | ... -> ... | Test.kt:100:25:110:1 | { ... } | | Test.kt:101:9:103:5 | ... -> ... | Test.kt:101:5:103:5 | ; | | Test.kt:102:9:102:25 | throw ... | Test.kt:101:33:103:5 | { ... } | +| Test.kt:105:5:109:5 | ; | Test.kt:100:25:110:1 | { ... } | +| Test.kt:105:5:109:5 | ; | Test.kt:101:5:103:5 | ; | +| Test.kt:105:5:109:5 | ; | Test.kt:101:9:103:5 | ... -> ... | +| Test.kt:105:9:107:5 | ... -> ... | Test.kt:100:25:110:1 | { ... } | +| Test.kt:105:9:107:5 | ... -> ... | Test.kt:101:5:103:5 | ; | +| Test.kt:105:9:107:5 | ... -> ... | Test.kt:101:9:103:5 | ... -> ... | | Test.kt:105:9:107:5 | ... -> ... | Test.kt:105:5:109:5 | ; | | Test.kt:106:9:106:29 | ; | Test.kt:105:20:107:5 | { ... } | | Test.kt:108:9:108:29 | ; | Test.kt:107:27:109:5 | { ... } | diff --git a/java/ql/test-kotlin2/library-tests/exprs/PrintAst.expected b/java/ql/test-kotlin2/library-tests/exprs/PrintAst.expected index 6a4ac3cab31d..78fc858d028e 100644 --- a/java/ql/test-kotlin2/library-tests/exprs/PrintAst.expected +++ b/java/ql/test-kotlin2/library-tests/exprs/PrintAst.expected @@ -3340,7 +3340,18 @@ exprs.kt: # 154| 0: [SuperConstructorInvocationStmt] super(...) # 154| 1: [BlockStmt] { ... } # 174| 6: [Class] Direction -# 174| 2: [Constructor] Direction +# 0| 2: [Method] getEntries +# 0| 3: [TypeAccess] EnumEntries +# 0| 0: [TypeAccess] Direction +# 0| 3: [Method] valueOf +# 0| 3: [TypeAccess] Direction +#-----| 4: (Parameters) +# 174| 0: [Parameter] value +# 174| 0: [TypeAccess] String +# 0| 4: [Method] values +# 0| 3: [TypeAccess] Direction[] +# 0| 0: [TypeAccess] Direction +# 174| 5: [Constructor] Direction # 174| 5: [BlockStmt] { ... } # 174| 0: [ExprStmt] ; # 174| 0: [ClassInstanceExpr] new Enum(...) @@ -3349,17 +3360,6 @@ exprs.kt: # 174| 0: [NullLiteral] null # 174| 1: [IntegerLiteral] 0 # 174| 1: [BlockStmt] { ... } -# 174| 3: [Method] getEntries -# 174| 3: [TypeAccess] EnumEntries -# 174| 0: [TypeAccess] Direction -# 174| 4: [Method] valueOf -# 174| 3: [TypeAccess] Direction -#-----| 4: (Parameters) -# 174| 0: [Parameter] value -# 174| 0: [TypeAccess] String -# 174| 5: [Method] values -# 174| 3: [TypeAccess] Direction[] -# 174| 0: [TypeAccess] Direction # 175| 6: [FieldDeclaration] Direction NORTH; # 175| -1: [TypeAccess] Direction # 175| 0: [ClassInstanceExpr] new Direction(...) @@ -3377,17 +3377,17 @@ exprs.kt: # 175| 0: [ClassInstanceExpr] new Direction(...) # 175| -3: [TypeAccess] Direction # 178| 7: [Class] Color -# 178| 2: [Method] getEntries -# 178| 3: [TypeAccess] EnumEntries -# 178| 0: [TypeAccess] Color -# 178| 3: [Method] valueOf -# 178| 3: [TypeAccess] Color +# 0| 2: [Method] getEntries +# 0| 3: [TypeAccess] EnumEntries +# 0| 0: [TypeAccess] Color +# 0| 3: [Method] valueOf +# 0| 3: [TypeAccess] Color #-----| 4: (Parameters) # 178| 0: [Parameter] value # 178| 0: [TypeAccess] String -# 178| 4: [Method] values -# 178| 3: [TypeAccess] Color[] -# 178| 0: [TypeAccess] Color +# 0| 4: [Method] values +# 0| 3: [TypeAccess] Color[] +# 0| 0: [TypeAccess] Color # 178| 5: [Constructor] Color #-----| 4: (Parameters) # 178| 0: [Parameter] rgb diff --git a/java/ql/test-kotlin2/library-tests/exprs/exprs.expected b/java/ql/test-kotlin2/library-tests/exprs/exprs.expected index 0acb9c221430..001794509ffb 100644 --- a/java/ql/test-kotlin2/library-tests/exprs/exprs.expected +++ b/java/ql/test-kotlin2/library-tests/exprs/exprs.expected @@ -883,6 +883,16 @@ | delegatedProperties.kt:87:34:87:46 | this | delegatedProperties.kt:87:34:87:46 | invoke | ThisAccess | | delegatedProperties.kt:87:34:87:46 | this | delegatedProperties.kt:87:34:87:46 | invoke | ThisAccess | | delegatedProperties.kt:87:34:87:46 | this | delegatedProperties.kt:87:34:87:46 | invoke | ThisAccess | +| exprs.kt:0:0:0:0 | Color | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | Color | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | Color | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | Color[] | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | Direction | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | Direction | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | Direction | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | Direction[] | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | EnumEntries | file://:0:0:0:0 | | TypeAccess | +| exprs.kt:0:0:0:0 | EnumEntries | file://:0:0:0:0 | | TypeAccess | | exprs.kt:4:1:142:1 | int | file://:0:0:0:0 | | TypeAccess | | exprs.kt:4:20:4:25 | int | file://:0:0:0:0 | | TypeAccess | | exprs.kt:4:28:4:33 | int | file://:0:0:0:0 | | TypeAccess | @@ -1461,12 +1471,7 @@ | exprs.kt:170:21:170:21 | 3 | exprs.kt:165:1:172:1 | foo | IntegerLiteral | | exprs.kt:174:1:176:1 | 0 | exprs.kt:174:1:176:1 | Direction | IntegerLiteral | | exprs.kt:174:1:176:1 | Direction | exprs.kt:174:1:176:1 | Direction | TypeAccess | -| exprs.kt:174:1:176:1 | Direction | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:174:1:176:1 | Direction | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:174:1:176:1 | Direction | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:174:1:176:1 | Direction[] | file://:0:0:0:0 | | TypeAccess | | exprs.kt:174:1:176:1 | Enum | exprs.kt:174:1:176:1 | Direction | TypeAccess | -| exprs.kt:174:1:176:1 | EnumEntries | file://:0:0:0:0 | | TypeAccess | | exprs.kt:174:1:176:1 | String | file://:0:0:0:0 | | TypeAccess | | exprs.kt:174:1:176:1 | new Enum(...) | exprs.kt:174:1:176:1 | Direction | ClassInstanceExpr | | exprs.kt:174:1:176:1 | null | exprs.kt:174:1:176:1 | Direction | NullLiteral | @@ -1494,11 +1499,6 @@ | exprs.kt:175:25:175:28 | Direction | file://:0:0:0:0 | | TypeAccess | | exprs.kt:175:25:175:28 | Direction.EAST | exprs.kt:0:0:0:0 | | VarAccess | | exprs.kt:175:25:175:28 | new Direction(...) | exprs.kt:0:0:0:0 | | ClassInstanceExpr | -| exprs.kt:178:1:182:1 | Color | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:178:1:182:1 | Color | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:178:1:182:1 | Color | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:178:1:182:1 | Color[] | file://:0:0:0:0 | | TypeAccess | -| exprs.kt:178:1:182:1 | EnumEntries | file://:0:0:0:0 | | TypeAccess | | exprs.kt:178:1:182:1 | String | file://:0:0:0:0 | | TypeAccess | | exprs.kt:178:17:178:30 | 0 | exprs.kt:178:17:178:30 | Color | IntegerLiteral | | exprs.kt:178:17:178:30 | Color | exprs.kt:178:17:178:30 | Color | TypeAccess | diff --git a/java/ql/test-kotlin2/library-tests/exprs_typeaccess/PrintAst.expected b/java/ql/test-kotlin2/library-tests/exprs_typeaccess/PrintAst.expected index a9cce8a012fb..3a7af6919ed8 100644 --- a/java/ql/test-kotlin2/library-tests/exprs_typeaccess/PrintAst.expected +++ b/java/ql/test-kotlin2/library-tests/exprs_typeaccess/PrintAst.expected @@ -73,7 +73,18 @@ A.kt: # 20| 2: [ReturnStmt] return ... # 20| 0: [IntegerLiteral] 5 # 23| 11: [Class] Enu -# 23| 2: [Constructor] Enu +# 0| 2: [Method] getEntries +# 0| 3: [TypeAccess] EnumEntries +# 0| 0: [TypeAccess] Enu +# 0| 3: [Method] valueOf +# 0| 3: [TypeAccess] Enu +#-----| 4: (Parameters) +# 23| 0: [Parameter] value +# 23| 0: [TypeAccess] String +# 0| 4: [Method] values +# 0| 3: [TypeAccess] Enu[] +# 0| 0: [TypeAccess] Enu +# 23| 5: [Constructor] Enu # 23| 5: [BlockStmt] { ... } # 23| 0: [ExprStmt] ; # 23| 0: [ClassInstanceExpr] new Enum(...) @@ -82,17 +93,6 @@ A.kt: # 23| 0: [NullLiteral] null # 23| 1: [IntegerLiteral] 0 # 23| 1: [BlockStmt] { ... } -# 23| 3: [Method] getEntries -# 23| 3: [TypeAccess] EnumEntries -# 23| 0: [TypeAccess] Enu -# 23| 4: [Method] valueOf -# 23| 3: [TypeAccess] Enu -#-----| 4: (Parameters) -# 23| 0: [Parameter] value -# 23| 0: [TypeAccess] String -# 23| 5: [Method] values -# 23| 3: [TypeAccess] Enu[] -# 23| 0: [TypeAccess] Enu # 24| 6: [FieldDeclaration] Enu A; # 24| -1: [TypeAccess] Enu # 24| 0: [ClassInstanceExpr] new Enu(...) diff --git a/java/ql/test-kotlin2/library-tests/methods/exprs.expected b/java/ql/test-kotlin2/library-tests/methods/exprs.expected index 041ef562dfbd..accffb8beff8 100644 --- a/java/ql/test-kotlin2/library-tests/methods/exprs.expected +++ b/java/ql/test-kotlin2/library-tests/methods/exprs.expected @@ -223,11 +223,16 @@ | delegates.kt:10:23:10:25 | old | VarAccess | | delegates.kt:10:26:10:31 | ", now " | StringLiteral | | delegates.kt:10:33:10:35 | new | VarAccess | -| enumClass.kt:1:1:4:1 | EnumClass | TypeAccess | -| enumClass.kt:1:1:4:1 | EnumClass | TypeAccess | -| enumClass.kt:1:1:4:1 | EnumClass | TypeAccess | -| enumClass.kt:1:1:4:1 | EnumClass[] | TypeAccess | -| enumClass.kt:1:1:4:1 | EnumEntries | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumClass[] | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumEntries | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumEntries | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions[] | TypeAccess | | enumClass.kt:1:1:4:1 | String | TypeAccess | | enumClass.kt:1:21:1:32 | 0 | IntegerLiteral | | enumClass.kt:1:21:1:32 | Enum | TypeAccess | @@ -258,12 +263,7 @@ | enumClass.kt:3:11:3:11 | 1 | IntegerLiteral | | enumClass.kt:6:1:16:1 | 0 | IntegerLiteral | | enumClass.kt:6:1:16:1 | Enum | TypeAccess | -| enumClass.kt:6:1:16:1 | EnumEntries | TypeAccess | | enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess | -| enumClass.kt:6:1:16:1 | EnumWithFunctions[] | TypeAccess | | enumClass.kt:6:1:16:1 | String | TypeAccess | | enumClass.kt:6:1:16:1 | new Enum(...) | ClassInstanceExpr | | enumClass.kt:6:1:16:1 | null | NullLiteral | diff --git a/java/ql/test-kotlin2/library-tests/methods/methods.expected b/java/ql/test-kotlin2/library-tests/methods/methods.expected index 79f674e4d7c4..94c0d62e20b1 100644 --- a/java/ql/test-kotlin2/library-tests/methods/methods.expected +++ b/java/ql/test-kotlin2/library-tests/methods/methods.expected @@ -26,14 +26,14 @@ methods | delegates.kt:8:35:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:35:11:5 | set | set(MyClass,java.lang.String) | override, public | | | delegates.kt:8:66:11:5 | new Function3,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | invoke | invoke(kotlin.reflect.KProperty,java.lang.String,java.lang.String) | final, override, public | | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | | () | static | Compiler generated | -| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:1:4:1 | getEntries | getEntries() | final, public, static | Compiler generated | -| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:1:4:1 | valueOf | valueOf(java.lang.String) | final, public, static | Compiler generated | -| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:1:4:1 | values | values() | final, public, static | Compiler generated | +| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | getEntries | getEntries() | final, public, static | Compiler generated | +| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | final, public, static | Compiler generated | +| enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | values | values() | final, public, static | Compiler generated | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:22:1:31 | getV | getV() | final, public | Compiler generated | | enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | | () | static | Compiler generated | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:6:1:16:1 | getEntries | getEntries() | final, public, static | Compiler generated | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:6:1:16:1 | valueOf | valueOf(java.lang.String) | final, public, static | Compiler generated | -| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:6:1:16:1 | values | values() | final, public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | getEntries | getEntries() | final, public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | final, public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | values | values() | final, public, static | Compiler generated | | enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:13:3:13:29 | f | f(int) | abstract, public | | | enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:14:3:14:29 | g | g(int) | abstract, public | | | enumClass.kt:8:3:11:4 | VAL | enumClass.kt:9:5:9:30 | f | f(int) | override, public | | diff --git a/java/ql/test-kotlin2/library-tests/methods/parameters.expected b/java/ql/test-kotlin2/library-tests/methods/parameters.expected index f0c4ad719468..3e5485f27245 100644 --- a/java/ql/test-kotlin2/library-tests/methods/parameters.expected +++ b/java/ql/test-kotlin2/library-tests/methods/parameters.expected @@ -22,8 +22,8 @@ | delegates.kt:8:66:11:5 | invoke | delegates.kt:9:9:9:12 | prop | 0 | | delegates.kt:8:66:11:5 | invoke | delegates.kt:9:15:9:17 | old | 1 | | delegates.kt:8:66:11:5 | invoke | delegates.kt:9:20:9:22 | new | 2 | -| enumClass.kt:1:1:4:1 | valueOf | enumClass.kt:1:1:4:1 | value | 0 | -| enumClass.kt:6:1:16:1 | valueOf | enumClass.kt:6:1:16:1 | value | 0 | +| enumClass.kt:0:0:0:0 | valueOf | enumClass.kt:1:1:4:1 | value | 0 | +| enumClass.kt:0:0:0:0 | valueOf | enumClass.kt:6:1:16:1 | value | 0 | | enumClass.kt:9:5:9:30 | f | enumClass.kt:9:20:9:25 | i | 0 | | enumClass.kt:10:5:10:42 | g | enumClass.kt:10:20:10:25 | i | 0 | | enumClass.kt:13:3:13:29 | f | enumClass.kt:13:18:13:23 | i | 0 | diff --git a/java/ql/test/library-tests/guards/Guards.java b/java/ql/test/library-tests/guards/Guards.java index b75e549d1669..aca64d6f64da 100644 --- a/java/ql/test/library-tests/guards/Guards.java +++ b/java/ql/test/library-tests/guards/Guards.java @@ -143,4 +143,73 @@ void t7(int[] a) { chk(); // $ guarded=found:true guarded='i < a.length:false' } } + + public static boolean testNotNull1(String input) { + return input != null && input.length() > 0; + } + + public static boolean testNotNull2(String input) { + if (input == null) return false; + return input.length() > 0; + } + + public static int getNumOrDefault(Integer number) { + return number == null ? 0 : number; + } + + public static String concatNonNull(String s1, String s2) { + if (s1 == null || s2 == null) return null; + return s1 + s2; + } + + public static Status testEnumWrapper(boolean flag) { + return flag ? Status.SUCCESS : Status.FAILURE; + } + + enum Status { SUCCESS, FAILURE } + + void testWrappers(String s, Integer i) { + if (testNotNull1(s)) { + chk(); // $ guarded='s:not null' guarded=testNotNull1(...):true + } else { + chk(); // $ guarded=testNotNull1(...):false + } + + if (testNotNull2(s)) { + chk(); // $ guarded='s:not null' guarded=testNotNull2(...):true + } else { + chk(); // $ guarded=testNotNull2(...):false + } + + if (0 == getNumOrDefault(i)) { + chk(); // $ guarded='0 == getNumOrDefault(...):true' guarded='getNumOrDefault(...):0' + } else { + chk(); // $ guarded='0 == getNumOrDefault(...):false' guarded='getNumOrDefault(...):not 0' guarded='i:not 0' guarded='i:not null' + } + + if (null == concatNonNull(s, "suffix")) { + chk(); // $ guarded='concatNonNull(...):null' guarded='null == concatNonNull(...):true' + } else { + chk(); // $ guarded='concatNonNull(...):not null' guarded='null == concatNonNull(...):false' guarded='s:not null' + } + + switch (testEnumWrapper(g(1))) { + case SUCCESS: + chk(); // $ guarded='testEnumWrapper(...):SUCCESS' guarded='testEnumWrapper(...):match SUCCESS' guarded=g(1):true + break; + case FAILURE: + chk(); // $ guarded='testEnumWrapper(...):FAILURE' guarded='testEnumWrapper(...):match FAILURE' guarded=g(1):false + break; + } + } + + static void ensureNotNull(Object o) throws Exception { + if (o == null) throw new Exception(); + } + + void testExceptionWrapper(String s) throws Exception { + chk(); // nothing guards here + ensureNotNull(s); + chk(); // $ guarded='ensureNotNull(...):no exception' guarded='s:not null' + } } diff --git a/java/ql/test/library-tests/guards/GuardsInline.expected b/java/ql/test/library-tests/guards/GuardsInline.expected index c45d536b7e9a..a76e2629cde0 100644 --- a/java/ql/test/library-tests/guards/GuardsInline.expected +++ b/java/ql/test/library-tests/guards/GuardsInline.expected @@ -89,3 +89,28 @@ | Guards.java:139:9:139:13 | chk(...) | found:true | | Guards.java:143:7:143:11 | chk(...) | 'i < a.length:false' | | Guards.java:143:7:143:11 | chk(...) | found:true | +| Guards.java:173:7:173:11 | chk(...) | 's:not null' | +| Guards.java:173:7:173:11 | chk(...) | testNotNull1(...):true | +| Guards.java:175:7:175:11 | chk(...) | testNotNull1(...):false | +| Guards.java:179:7:179:11 | chk(...) | 's:not null' | +| Guards.java:179:7:179:11 | chk(...) | testNotNull2(...):true | +| Guards.java:181:7:181:11 | chk(...) | testNotNull2(...):false | +| Guards.java:185:7:185:11 | chk(...) | '0 == getNumOrDefault(...):true' | +| Guards.java:185:7:185:11 | chk(...) | 'getNumOrDefault(...):0' | +| Guards.java:187:7:187:11 | chk(...) | '0 == getNumOrDefault(...):false' | +| Guards.java:187:7:187:11 | chk(...) | 'getNumOrDefault(...):not 0' | +| Guards.java:187:7:187:11 | chk(...) | 'i:not 0' | +| Guards.java:187:7:187:11 | chk(...) | 'i:not null' | +| Guards.java:191:7:191:11 | chk(...) | 'concatNonNull(...):null' | +| Guards.java:191:7:191:11 | chk(...) | 'null == concatNonNull(...):true' | +| Guards.java:193:7:193:11 | chk(...) | 'concatNonNull(...):not null' | +| Guards.java:193:7:193:11 | chk(...) | 'null == concatNonNull(...):false' | +| Guards.java:193:7:193:11 | chk(...) | 's:not null' | +| Guards.java:198:9:198:13 | chk(...) | 'testEnumWrapper(...):SUCCESS' | +| Guards.java:198:9:198:13 | chk(...) | 'testEnumWrapper(...):match SUCCESS' | +| Guards.java:198:9:198:13 | chk(...) | g(1):true | +| Guards.java:201:9:201:13 | chk(...) | 'testEnumWrapper(...):FAILURE' | +| Guards.java:201:9:201:13 | chk(...) | 'testEnumWrapper(...):match FAILURE' | +| Guards.java:201:9:201:13 | chk(...) | g(1):false | +| Guards.java:213:5:213:9 | chk(...) | 'ensureNotNull(...):no exception' | +| Guards.java:213:5:213:9 | chk(...) | 's:not null' | diff --git a/java/ql/test/query-tests/Nullness/B.java b/java/ql/test/query-tests/Nullness/B.java index 0ab6d58dbaeb..99bd6f4a1bae 100644 --- a/java/ql/test/query-tests/Nullness/B.java +++ b/java/ql/test/query-tests/Nullness/B.java @@ -408,4 +408,32 @@ public void bitwise(Object x, boolean b) { x.hashCode(); // NPE } } + + public void corrCondLoop1(boolean a[]) { + Object x = new Object(); + for (int i = 0; i < a.length; i++) { + boolean b = a[i]; + if (b) { + x = null; + } + if (!b) { + x.hashCode(); // NPE - false negative + } + // flow can loop around from one iteration to the next + } + } + + public void corrCondLoop2(boolean a[]) { + for (int i = 0; i < a.length; i++) { + // x is local to the loop iteration and thus cannot loop around and reach the sink + Object x = new Object(); + boolean b = a[i]; + if (b) { + x = null; + } + if (!b) { + x.hashCode(); // OK + } + } + } } diff --git a/java/ql/test/query-tests/Nullness/C.java b/java/ql/test/query-tests/Nullness/C.java index d195eea6acb3..9424cbe71f22 100644 --- a/java/ql/test/query-tests/Nullness/C.java +++ b/java/ql/test/query-tests/Nullness/C.java @@ -204,7 +204,7 @@ public void ex14(int[] a) { obj = new Object(); } else if (a[i] == 2) { verifyNotNull(obj); - obj.hashCode(); // NPE - false positive + obj.hashCode(); // OK } } } diff --git a/java/ql/test/query-tests/Nullness/NullMaybe.expected b/java/ql/test/query-tests/Nullness/NullMaybe.expected index a19fae57e74e..9f2920293b07 100644 --- a/java/ql/test/query-tests/Nullness/NullMaybe.expected +++ b/java/ql/test/query-tests/Nullness/NullMaybe.expected @@ -29,7 +29,6 @@ | C.java:137:7:137:10 | obj2 | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:131:5:131:23 | Object obj2 | obj2 | C.java:132:9:132:20 | ... != ... | this | | C.java:144:15:144:15 | a | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:141:20:141:26 | a | a | C.java:142:13:142:21 | ... == ... | this | | C.java:188:9:188:11 | obj | Variable $@ may be null at this access because of $@ assignment. | C.java:181:5:181:22 | Object obj | obj | C.java:181:12:181:21 | obj | this | -| C.java:207:9:207:11 | obj | Variable $@ may be null at this access because of $@ assignment. | C.java:201:5:201:22 | Object obj | obj | C.java:201:12:201:21 | obj | this | | C.java:219:9:219:10 | o1 | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:212:20:212:28 | o1 | o1 | C.java:213:9:213:18 | ... == ... | this | | C.java:233:7:233:8 | xs | Variable $@ may be null at this access because of $@ assignment. | C.java:231:5:231:56 | int[] xs | xs | C.java:231:11:231:55 | xs | this | | F.java:11:5:11:7 | obj | Variable $@ may be null at this access as suggested by $@ null guard. | F.java:8:18:8:27 | obj | obj | F.java:9:9:9:19 | ... == ... | this | diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index ab12beb56981..93edd0d9f494 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.6.8 + +### Minor Analysis Improvements + +* The regular expressions in `SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information. + ## 2.6.7 ### Minor Analysis Improvements diff --git a/javascript/ql/lib/change-notes/2025-08-01-cli-code-injection.md b/javascript/ql/lib/change-notes/2025-08-01-cli-code-injection.md new file mode 100644 index 000000000000..20fa14da66f9 --- /dev/null +++ b/javascript/ql/lib/change-notes/2025-08-01-cli-code-injection.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Improved modeling of command-line argument parsing libraries [arg](https://www.npmjs.com/package/arg), [args](https://www.npmjs.com/package/args), [command-line-args](https://www.npmjs.com/package/command-line-args) and [commander](https://www.npmjs.com/package/commander) diff --git a/javascript/ql/lib/change-notes/released/2.6.8.md b/javascript/ql/lib/change-notes/released/2.6.8.md new file mode 100644 index 000000000000..23b383575842 --- /dev/null +++ b/javascript/ql/lib/change-notes/released/2.6.8.md @@ -0,0 +1,5 @@ +## 2.6.8 + +### Minor Analysis Improvements + +* The regular expressions in `SensitiveDataHeuristics.qll` have been extended to find more instances of sensitive data such as secrets used in authentication, finance and health information, and device data. The heuristics have also been refined to find fewer false positive matches. This will improve results for queries related to sensitive information. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 7be0a0fdb3c6..e3569f2b799b 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.6.7 +lastReleaseVersion: 2.6.8 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 03a691f02f53..39b1edfe98c9 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.6.7 +version: 2.6.9-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/lib/semmle/javascript/Concepts.qll b/javascript/ql/lib/semmle/javascript/Concepts.qll index 76c67156d1ca..70fe76ae5f13 100644 --- a/javascript/ql/lib/semmle/javascript/Concepts.qll +++ b/javascript/ql/lib/semmle/javascript/Concepts.qll @@ -212,15 +212,7 @@ abstract class PersistentWriteAccess extends DataFlow::Node { module Cryptography { private import ConceptsShared::Cryptography as SC - /** - * A data-flow node that is an application of a cryptographic algorithm. For example, - * encryption, decryption, signature-validation. - * - * Extend this class to refine existing API models. If you want to model new APIs, - * extend `CryptographicOperation::Range` instead. - */ - class CryptographicOperation extends SC::CryptographicOperation instanceof CryptographicOperation::Range - { } + class CryptographicOperation = SC::CryptographicOperation; class EncryptionAlgorithm = SC::EncryptionAlgorithm; diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll index d02728ef551c..0af57ec01869 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/BarrierGuards.qll @@ -193,6 +193,8 @@ private module ConditionGuardDominators { module MakeStateBarrierGuard< FlowStateSig FlowState, WithFlowState::BarrierGuardSig BaseGuard> { + private import codeql.util.Boolean + final private class FinalNode = DataFlow::Node; abstract private class BarrierGuard extends FinalNode { @@ -295,7 +297,7 @@ module MakeStateBarrierGuard< } private predicate ssa2GuardChecks( - Ssa2::SsaDataflowInput::Guard guard, Ssa2::SsaDataflowInput::Expr test, boolean branch, + Ssa2::SsaDataflowInput::Guard guard, Ssa2::SsaDataflowInput::Expr test, Boolean branch, FlowState state ) { exists(BarrierGuard g | diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll index 4bb07df9a875..548d06ef64f5 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/TaintTrackingPrivate.qll @@ -6,6 +6,7 @@ private import semmle.javascript.dataflow.internal.sharedlib.FlowSummaryImpl as private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate private import semmle.javascript.dataflow.internal.BarrierGuards private import semmle.javascript.dataflow.internal.sharedlib.Ssa as Ssa2 +private import codeql.util.Boolean cached predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { @@ -37,7 +38,7 @@ predicate defaultAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2, } private predicate guardChecksFalsy( - Ssa2::SsaDataflowInput::Guard g, Ssa2::SsaDataflowInput::Expr e, boolean outcome + Ssa2::SsaDataflowInput::Guard g, Ssa2::SsaDataflowInput::Expr e, Boolean outcome ) { exists(ConditionGuardNode guard | guard.getTest() = g and diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll index bea32b384371..eef4dc08318a 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll @@ -50,6 +50,8 @@ module SsaConfig implements InputSig { import Make module SsaDataflowInput implements DataFlowIntegrationInputSig { + private import codeql.util.Boolean + class Expr extends js::ControlFlowNode { Expr() { this = any(SsaConfig::SourceVariable v).getAUse() } @@ -71,6 +73,8 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig { ) } + class GuardValue = Boolean; + class Guard extends js::ControlFlowNode { Guard() { this = any(js::ConditionGuardNode g).getTest() } @@ -78,7 +82,7 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig { * Holds if the evaluation of this guard to `branch` corresponds to the edge * from `bb1` to `bb2`. */ - predicate hasBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, boolean branch) { + predicate hasValueBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, GuardValue branch) { exists(js::ConditionGuardNode g | g.getTest() = this and bb1 = this.getBasicBlock() and @@ -92,13 +96,13 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig { * branch edge from `bb1` to `bb2`. That is, following the edge from * `bb1` to `bb2` implies that this guard evaluated to `branch`. */ - predicate controlsBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, boolean branch) { - this.hasBranchEdge(bb1, bb2, branch) + predicate valueControlsBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, GuardValue branch) { + this.hasValueBranchEdge(bb1, bb2, branch) } } pragma[inline] - predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) { + predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, GuardValue branch) { exists(js::ConditionGuardNode g | g.getTest() = guard and g.dominates(bb) and diff --git a/javascript/ql/lib/semmle/javascript/frameworks/CommandLineArguments.qll b/javascript/ql/lib/semmle/javascript/frameworks/CommandLineArguments.qll index 50beb04b8879..cd8fa34a08eb 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/CommandLineArguments.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/CommandLineArguments.qll @@ -87,11 +87,43 @@ private class ArgsParseStep extends TaintTracking::SharedTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(DataFlow::CallNode call | call = DataFlow::moduleMember("args", "parse").getACall() or - call = DataFlow::moduleImport(["yargs-parser", "minimist", "subarg"]).getACall() + call = + DataFlow::moduleImport(["yargs-parser", "minimist", "subarg", "yargs/yargs", "yargs"]) + .getACall() | succ = call and pred = call.getArgument(0) ) + or + exists(API::Node commanderNode | commanderNode = commander() | + pred = commanderNode.getMember(["parse", "parseAsync"]).getACall().getAnArgument() and + succ = + [ + commanderNode.getMember("opts").getACall(), commanderNode.getAMember().asSource(), + commander() + .getMember("action") + .getACall() + .getArgument(0) + .(DataFlow::FunctionNode) + .getAParameter() + ] + ) + or + exists(DataFlow::MethodCallNode methodCall | methodCall = yargs() | + pred = methodCall.getReceiver() and + succ = methodCall + ) + or + exists(DataFlow::CallNode call, DataFlow::Node options | + call = DataFlow::moduleImport(["arg", "command-line-args"]).getACall() and + succ = call and + options = call.getArgument(1) and + exists(DataFlow::PropWrite write | + write.getBase() = options and + write.getPropertyName() = "argv" and + pred = write.getRhs() + ) + ) } } @@ -115,7 +147,9 @@ private API::Node commander() { * Either directly imported as a module, or through some chained method call. */ private DataFlow::SourceNode yargs() { - result = DataFlow::moduleImport("yargs") + result = DataFlow::moduleImport(["yargs", "yargs/yargs"]) + or + result = DataFlow::moduleImport(["yargs", "yargs/yargs"]).getACall() or // script used to generate list of chained methods: https://gist.github.com/erik-krogh/f8afe952c0577f4b563a993e613269ba exists(string method | diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll index 0e19e84b666f..82deb735c629 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll @@ -21,6 +21,8 @@ private import internal.ApiGraphModels as Shared private import internal.ApiGraphModelsSpecific as Specific private import semmle.javascript.dataflow.internal.FlowSummaryPrivate private import semmle.javascript.endpoints.EndpointNaming as EndpointNaming +private import semmle.javascript.dataflow.AdditionalFlowSteps +private import semmle.javascript.dataflow.AdditionalTaintSteps import Shared::ModelInput as ModelInput import Shared::ModelOutput as ModelOutput @@ -87,9 +89,6 @@ private predicate shouldInduceStepsFromSummary(string type, string path) { pragma[nomagic] private predicate relevantInputOutputPath(API::InvokeNode base, AccessPath inputOrOutput) { exists(string type, string input, string output, string path | - // If the summary for 'callable' could not be handled as a flow summary, we need to evaluate - // its inputs and outputs to a set of nodes, so we can generate steps instead. - shouldInduceStepsFromSummary(type, path) and ModelOutput::resolvedSummaryBase(type, path, base) and ModelOutput::relevantSummaryModel(type, path, input, output, _, _) and inputOrOutput = [input, output] @@ -118,22 +117,26 @@ private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPat result = getNodeFromInputOutputPath(baseNode, path, path.getNumToken()) } -private predicate summaryStep(API::Node pred, API::Node succ, string kind) { +private predicate summaryStep(API::Node pred, API::Node succ, string kind, boolean shouldInduceSteps) { exists(string type, string path, API::InvokeNode base, AccessPath input, AccessPath output | - shouldInduceStepsFromSummary(type, path) and ModelOutput::relevantSummaryModel(type, path, input, output, kind, _) and ModelOutput::resolvedSummaryBase(type, path, base) and pred = getNodeFromInputOutputPath(base, input) and - succ = getNodeFromInputOutputPath(base, output) + succ = getNodeFromInputOutputPath(base, output) and + if shouldInduceStepsFromSummary(type, path) + then shouldInduceSteps = true + else shouldInduceSteps = false ) } /** * Like `ModelOutput::summaryStep` but with API nodes mapped to data-flow nodes. */ -private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, string kind) { +private predicate summaryStepNodes( + DataFlow::Node pred, DataFlow::Node succ, string kind, boolean shouldInduceSteps +) { exists(API::Node predNode, API::Node succNode | - summaryStep(predNode, succNode, kind) and + summaryStep(predNode, succNode, kind, shouldInduceSteps) and pred = predNode.asSink() and succ = succNode.asSource() ) @@ -142,14 +145,26 @@ private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, str /** Data flow steps induced by summary models of kind `value`. */ private class DataFlowStepFromSummary extends DataFlow::SharedFlowStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { - summaryStepNodes(pred, succ, "value") + summaryStepNodes(pred, succ, "value", true) + } +} + +private class LegacyDataFlowStepFromSummary extends LegacyFlowStep { + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + summaryStepNodes(pred, succ, "value", false) } } /** Taint steps induced by summary models of kind `taint`. */ private class TaintStepFromSummary extends TaintTracking::SharedTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { - summaryStepNodes(pred, succ, "taint") + summaryStepNodes(pred, succ, "taint", true) + } +} + +private class LegacyTaintStepFromSummary extends LegacyTaintStep { + override predicate step(DataFlow::Node pred, DataFlow::Node succ) { + summaryStepNodes(pred, succ, "taint", false) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll index 1c056935d407..5ee39219d260 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/RegExpInjectionCustomizations.qll @@ -5,6 +5,7 @@ */ import javascript +private import codeql.threatmodels.ThreatModels module RegExpInjection { /** @@ -32,19 +33,32 @@ module RegExpInjection { /** * An active threat-model source, considered as a flow source. + * Excludes environment variables by default - they require the "environment" threat model. */ private class ActiveThreatModelSourceAsSource extends Source instanceof ActiveThreatModelSource { - ActiveThreatModelSourceAsSource() { not this.isClientSideSource() } + ActiveThreatModelSourceAsSource() { + not this.isClientSideSource() and + not this.(ThreatModelSource).getThreatModel() = "environment" + } } - private import IndirectCommandInjectionCustomizations + /** + * Environment variables as a source when the "environment" threat model is active. + */ + private class EnvironmentVariableAsSource extends Source instanceof ThreatModelSource { + EnvironmentVariableAsSource() { + this.getThreatModel() = "environment" and + currentThreatModel("environment") + } + + override string describe() { result = "environment variable" } + } /** - * A read of `process.env`, `process.argv`, and similar, considered as a flow source for regular - * expression injection. + * Command line arguments as a source for regular expression injection. */ - class ArgvAsSource extends Source instanceof IndirectCommandInjection::Source { - override string describe() { result = IndirectCommandInjection::Source.super.describe() } + private class CommandLineArgumentAsSource extends Source instanceof CommandLineArguments { + override string describe() { result = "command-line argument" } } /** diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index e2d35e74bb93..19314b8b7741 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +No user-facing changes. + ## 2.0.0 ### Breaking Changes diff --git a/javascript/ql/src/change-notes/2025-07-31-regexp-injection-threat-model.md b/javascript/ql/src/change-notes/2025-07-31-regexp-injection-threat-model.md new file mode 100644 index 000000000000..f87e10077654 --- /dev/null +++ b/javascript/ql/src/change-notes/2025-07-31-regexp-injection-threat-model.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `js/regex-injection` query no longer considers environment variables as sources by default. Environment variables can be re-enabled as sources by setting the threat model to include the "environment" category. diff --git a/javascript/ql/src/change-notes/released/2.0.1.md b/javascript/ql/src/change-notes/released/2.0.1.md new file mode 100644 index 000000000000..b5b6d0dee915 --- /dev/null +++ b/javascript/ql/src/change-notes/released/2.0.1.md @@ -0,0 +1,3 @@ +## 2.0.1 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 0abe6ccede0f..fe974a4dbf37 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.0 +lastReleaseVersion: 2.0.1 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 55256002d7c9..c06711ab2caf 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.0.0 +version: 2.0.2-dev groups: - javascript - queries diff --git a/javascript/ql/test/library-tests/frameworks/data/test.expected b/javascript/ql/test/library-tests/frameworks/data/test.expected index 875b0189d619..0bc1b6b6ee07 100644 --- a/javascript/ql/test/library-tests/frameworks/data/test.expected +++ b/javascript/ql/test/library-tests/frameworks/data/test.expected @@ -1,21 +1,4 @@ legacyDataFlowDifference -| test.js:5:30:5:37 | source() | test.js:5:8:5:38 | testlib ... urce()) | only flow with NEW data flow library | -| test.js:6:22:6:29 | source() | test.js:6:8:6:30 | preserv ... urce()) | only flow with NEW data flow library | -| test.js:7:41:7:48 | source() | test.js:7:8:7:49 | require ... urce()) | only flow with NEW data flow library | -| test.js:11:38:11:45 | source() | test.js:11:8:11:55 | testlib ... , 1, 1) | only flow with NEW data flow library | -| test.js:13:44:13:51 | source() | test.js:13:8:13:55 | testlib ... e(), 1) | only flow with NEW data flow library | -| test.js:17:47:17:54 | source() | test.js:17:8:17:61 | testlib ... , 1, 1) | only flow with NEW data flow library | -| test.js:18:50:18:57 | source() | test.js:18:8:18:61 | testlib ... e(), 1) | only flow with NEW data flow library | -| test.js:19:53:19:60 | source() | test.js:19:8:19:61 | testlib ... urce()) | only flow with NEW data flow library | -| test.js:21:34:21:41 | source() | test.js:21:8:21:51 | testlib ... , 1, 1) | only flow with NEW data flow library | -| test.js:22:37:22:44 | source() | test.js:22:8:22:51 | testlib ... , 1, 1) | only flow with NEW data flow library | -| test.js:23:40:23:47 | source() | test.js:23:8:23:51 | testlib ... e(), 1) | only flow with NEW data flow library | -| test.js:24:43:24:50 | source() | test.js:24:8:24:51 | testlib ... urce()) | only flow with NEW data flow library | -| test.js:31:29:31:36 | source() | test.js:32:10:32:10 | y | only flow with NEW data flow library | -| test.js:37:29:37:36 | source() | test.js:38:10:38:10 | y | only flow with NEW data flow library | -| test.js:43:29:43:36 | source() | test.js:44:10:44:10 | y | only flow with NEW data flow library | -| test.js:47:33:47:40 | source() | test.js:49:10:49:13 | this | only flow with NEW data flow library | -| test.js:102:16:102:34 | testlib.getSource() | test.js:104:8:104:24 | source.continue() | only flow with NEW data flow library | consistencyIssue taintFlow | guardedRouteHandler.js:6:10:6:28 | req.injectedReqData | guardedRouteHandler.js:6:10:6:28 | req.injectedReqData | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected index 22394ec4cb89..862255f70f23 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/CommandInjection.expected @@ -21,6 +21,12 @@ | child_process-test.js:75:29:75:31 | cmd | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:75:29:75:31 | cmd | This command line depends on a $@. | child_process-test.js:73:25:73:31 | req.url | user-provided value | | child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | This command line depends on a $@. | child_process-test.js:83:19:83:36 | req.query.fileName | user-provided value | | child_process-test.js:94:11:94:35 | "ping " ... ms.host | child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:11:94:35 | "ping " ... ms.host | This command line depends on a $@. | child_process-test.js:94:21:94:30 | ctx.params | user-provided value | +| command-line-libs.js:14:8:14:18 | options.cmd | command-line-libs.js:9:16:9:23 | req.body | command-line-libs.js:14:8:14:18 | options.cmd | This command line depends on a $@. | command-line-libs.js:9:16:9:23 | req.body | user-provided value | +| command-line-libs.js:15:8:15:18 | program.cmd | command-line-libs.js:9:16:9:23 | req.body | command-line-libs.js:15:8:15:18 | program.cmd | This command line depends on a $@. | command-line-libs.js:9:16:9:23 | req.body | user-provided value | +| command-line-libs.js:21:12:21:17 | script | command-line-libs.js:9:16:9:23 | req.body | command-line-libs.js:21:12:21:17 | script | This command line depends on a $@. | command-line-libs.js:9:16:9:23 | req.body | user-provided value | +| command-line-libs.js:29:10:29:24 | parsed['--cmd'] | command-line-libs.js:27:23:27:30 | req.body | command-line-libs.js:29:10:29:24 | parsed['--cmd'] | This command line depends on a $@. | command-line-libs.js:27:23:27:30 | req.body | user-provided value | +| command-line-libs.js:37:8:37:18 | options.cmd | command-line-libs.js:35:62:35:69 | req.body | command-line-libs.js:37:8:37:18 | options.cmd | This command line depends on a $@. | command-line-libs.js:35:62:35:69 | req.body | user-provided value | +| command-line-libs.js:49:8:49:17 | parsed.cmd | command-line-libs.js:42:16:42:23 | req.body | command-line-libs.js:49:8:49:17 | parsed.cmd | This command line depends on a $@. | command-line-libs.js:42:16:42:23 | req.body | user-provided value | | exec-sh2.js:10:12:10:57 | cp.spaw ... ptions) | exec-sh2.js:14:25:14:31 | req.url | exec-sh2.js:10:40:10:46 | command | This command line depends on a $@. | exec-sh2.js:14:25:14:31 | req.url | user-provided value | | exec-sh.js:15:12:15:61 | cp.spaw ... ptions) | exec-sh.js:19:25:19:31 | req.url | exec-sh.js:15:44:15:50 | command | This command line depends on a $@. | exec-sh.js:19:25:19:31 | req.url | user-provided value | | execSeries.js:14:41:14:47 | command | execSeries.js:18:34:18:40 | req.url | execSeries.js:14:41:14:47 | command | This command line depends on a $@. | execSeries.js:18:34:18:40 | req.url | user-provided value | @@ -116,6 +122,35 @@ edges | child_process-test.js:73:15:73:38 | url.par ... , true) | child_process-test.js:73:9:73:49 | cmd | provenance | | | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | provenance | | | child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:11:94:35 | "ping " ... ms.host | provenance | | +| command-line-libs.js:9:9:9:34 | args | command-line-libs.js:12:17:12:20 | args | provenance | | +| command-line-libs.js:9:9:9:34 | args | command-line-libs.js:23:29:23:32 | args | provenance | | +| command-line-libs.js:9:16:9:23 | req.body | command-line-libs.js:9:9:9:34 | args | provenance | | +| command-line-libs.js:12:17:12:20 | args | command-line-libs.js:13:19:13:32 | program.opts() | provenance | | +| command-line-libs.js:12:17:12:20 | args | command-line-libs.js:15:8:15:18 | program.cmd | provenance | | +| command-line-libs.js:12:17:12:20 | args | command-line-libs.js:20:14:20:19 | script | provenance | | +| command-line-libs.js:13:9:13:32 | options | command-line-libs.js:14:8:14:14 | options | provenance | | +| command-line-libs.js:13:19:13:32 | program.opts() | command-line-libs.js:13:9:13:32 | options | provenance | | +| command-line-libs.js:14:8:14:14 | options | command-line-libs.js:14:8:14:18 | options.cmd | provenance | | +| command-line-libs.js:20:14:20:19 | script | command-line-libs.js:21:12:21:17 | script | provenance | | +| command-line-libs.js:23:29:23:32 | args | command-line-libs.js:20:14:20:19 | script | provenance | | +| command-line-libs.js:27:11:27:41 | argsArray | command-line-libs.js:28:53:28:61 | argsArray | provenance | | +| command-line-libs.js:27:23:27:30 | req.body | command-line-libs.js:27:11:27:41 | argsArray | provenance | | +| command-line-libs.js:28:11:28:64 | parsed | command-line-libs.js:29:10:29:15 | parsed | provenance | | +| command-line-libs.js:28:20:28:64 | arg({ ' ... rray }) | command-line-libs.js:28:11:28:64 | parsed | provenance | | +| command-line-libs.js:28:53:28:61 | argsArray | command-line-libs.js:28:20:28:64 | arg({ ' ... rray }) | provenance | | +| command-line-libs.js:29:10:29:15 | parsed | command-line-libs.js:29:10:29:24 | parsed['--cmd'] | provenance | | +| command-line-libs.js:35:9:35:83 | options | command-line-libs.js:37:8:37:14 | options | provenance | | +| command-line-libs.js:35:19:35:83 | command ... \| [] }) | command-line-libs.js:35:9:35:83 | options | provenance | | +| command-line-libs.js:35:62:35:69 | req.body | command-line-libs.js:35:19:35:83 | command ... \| [] }) | provenance | | +| command-line-libs.js:37:8:37:14 | options | command-line-libs.js:37:8:37:18 | options.cmd | provenance | | +| command-line-libs.js:42:9:42:34 | args | command-line-libs.js:43:24:43:27 | args | provenance | | +| command-line-libs.js:42:16:42:23 | req.body | command-line-libs.js:42:9:42:34 | args | provenance | | +| command-line-libs.js:43:9:47:12 | parsed | command-line-libs.js:49:8:49:13 | parsed | provenance | | +| command-line-libs.js:43:18:43:28 | yargs(args) | command-line-libs.js:43:18:47:4 | yargs(a ... ue\\n }) | provenance | | +| command-line-libs.js:43:18:47:4 | yargs(a ... ue\\n }) | command-line-libs.js:43:18:47:12 | yargs(a ... parse() | provenance | | +| command-line-libs.js:43:18:47:12 | yargs(a ... parse() | command-line-libs.js:43:9:47:12 | parsed | provenance | | +| command-line-libs.js:43:24:43:27 | args | command-line-libs.js:43:18:43:28 | yargs(args) | provenance | | +| command-line-libs.js:49:8:49:13 | parsed | command-line-libs.js:49:8:49:17 | parsed.cmd | provenance | | | exec-sh2.js:9:17:9:23 | command | exec-sh2.js:10:40:10:46 | command | provenance | | | exec-sh2.js:14:9:14:49 | cmd | exec-sh2.js:15:12:15:14 | cmd | provenance | | | exec-sh2.js:14:15:14:38 | url.par ... , true) | exec-sh2.js:14:9:14:49 | cmd | provenance | | @@ -269,6 +304,38 @@ nodes | child_process-test.js:83:19:83:36 | req.query.fileName | semmle.label | req.query.fileName | | child_process-test.js:94:11:94:35 | "ping " ... ms.host | semmle.label | "ping " ... ms.host | | child_process-test.js:94:21:94:30 | ctx.params | semmle.label | ctx.params | +| command-line-libs.js:9:9:9:34 | args | semmle.label | args | +| command-line-libs.js:9:16:9:23 | req.body | semmle.label | req.body | +| command-line-libs.js:12:17:12:20 | args | semmle.label | args | +| command-line-libs.js:13:9:13:32 | options | semmle.label | options | +| command-line-libs.js:13:19:13:32 | program.opts() | semmle.label | program.opts() | +| command-line-libs.js:14:8:14:14 | options | semmle.label | options | +| command-line-libs.js:14:8:14:18 | options.cmd | semmle.label | options.cmd | +| command-line-libs.js:15:8:15:18 | program.cmd | semmle.label | program.cmd | +| command-line-libs.js:20:14:20:19 | script | semmle.label | script | +| command-line-libs.js:21:12:21:17 | script | semmle.label | script | +| command-line-libs.js:23:29:23:32 | args | semmle.label | args | +| command-line-libs.js:27:11:27:41 | argsArray | semmle.label | argsArray | +| command-line-libs.js:27:23:27:30 | req.body | semmle.label | req.body | +| command-line-libs.js:28:11:28:64 | parsed | semmle.label | parsed | +| command-line-libs.js:28:20:28:64 | arg({ ' ... rray }) | semmle.label | arg({ ' ... rray }) | +| command-line-libs.js:28:53:28:61 | argsArray | semmle.label | argsArray | +| command-line-libs.js:29:10:29:15 | parsed | semmle.label | parsed | +| command-line-libs.js:29:10:29:24 | parsed['--cmd'] | semmle.label | parsed['--cmd'] | +| command-line-libs.js:35:9:35:83 | options | semmle.label | options | +| command-line-libs.js:35:19:35:83 | command ... \| [] }) | semmle.label | command ... \| [] }) | +| command-line-libs.js:35:62:35:69 | req.body | semmle.label | req.body | +| command-line-libs.js:37:8:37:14 | options | semmle.label | options | +| command-line-libs.js:37:8:37:18 | options.cmd | semmle.label | options.cmd | +| command-line-libs.js:42:9:42:34 | args | semmle.label | args | +| command-line-libs.js:42:16:42:23 | req.body | semmle.label | req.body | +| command-line-libs.js:43:9:47:12 | parsed | semmle.label | parsed | +| command-line-libs.js:43:18:43:28 | yargs(args) | semmle.label | yargs(args) | +| command-line-libs.js:43:18:47:4 | yargs(a ... ue\\n }) | semmle.label | yargs(a ... ue\\n }) | +| command-line-libs.js:43:18:47:12 | yargs(a ... parse() | semmle.label | yargs(a ... parse() | +| command-line-libs.js:43:24:43:27 | args | semmle.label | args | +| command-line-libs.js:49:8:49:13 | parsed | semmle.label | parsed | +| command-line-libs.js:49:8:49:17 | parsed.cmd | semmle.label | parsed.cmd | | exec-sh2.js:9:17:9:23 | command | semmle.label | command | | exec-sh2.js:10:40:10:46 | command | semmle.label | command | | exec-sh2.js:14:9:14:49 | cmd | semmle.label | cmd | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/command-line-libs.js b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/command-line-libs.js new file mode 100644 index 000000000000..83c824d4239a --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/command-line-libs.js @@ -0,0 +1,50 @@ +import express from 'express'; +import { Command } from 'commander'; +import { exec } from 'child_process'; +import arg from 'arg'; +const app = express(); +app.use(express.json()); + +app.post('/Command', async (req, res) => { + const args = req.body.args || []; // $ Source + const program = new Command(); + program.option('--cmd ', 'Command to execute'); + program.parse(args, { from: 'user' }); + const options = program.opts(); + exec(options.cmd); // $ Alert + exec(program.cmd); // $ Alert + + const program1 = new Command(); + program1 + .command('run