Compare commits

..

360 Commits

Author SHA1 Message Date
Chris Smowton
463db799ba Update test expectations 2026-02-06 03:52:14 -08:00
Chris Smowton
d2636aad68 JS: Add missing rule to security-and-quality query list
Has header block

```
 * @id js/unhandled-error-in-stream-pipeline
 * @name Unhandled error in stream pipeline
 * @description Calling `pipe()` on a stream without error handling will drop errors coming from the input stream
 * @kind problem
 * @problem.severity warning
 * @precision high
 * @tags quality
 *       reliability
 *       error-handling
 *       frameworks/nodejs
```

... which would get selected by the security-and-quality selectors if we were using them. Any reason to exclude?
2026-02-06 11:24:30 +00:00
Taus
5adc9f8ff0 Merge pull request #21274 from github/tausbn/python-fix-parsing-of-format-specifiers
Python: Fix syntax error when `=` is used as a format fill character
2026-02-05 16:37:42 +01:00
Taus
8c27437628 Python: Bump extractor version and add change note 2026-02-05 13:50:54 +00:00
Taus
12ee93042b Python: Add tests 2026-02-05 13:47:24 +00:00
Taus
bac356c9a1 Python: Regenerate parser files 2026-02-05 13:46:59 +00:00
Taus
68c1a3d389 Python: Fix syntax error when = is used as a format fill character
An example (provided by @redsun82) is the string `f"{x:=^20}"`. Parsing
this (with unnamed nodes shown) illustrates the problem:

```
module [0, 0] - [2, 0]
  expression_statement [0, 0] - [0, 11]
    string [0, 0] - [0, 11]
      string_start [0, 0] - [0, 2]
      interpolation [0, 2] - [0, 10]
        "{" [0, 2] - [0, 3]
        expression: named_expression [0, 3] - [0, 9]
          name: identifier [0, 3] - [0, 4]
          ":=" [0, 4] - [0, 6]
          ERROR [0, 6] - [0, 7]
            "^" [0, 6] - [0, 7]
          value: integer [0, 7] - [0, 9]
        "}" [0, 9] - [0, 10]
      string_end [0, 10] - [0, 11]
```
Observe that we've managed to combine the format specifier token `:` and
the fill character `=` in a single token (which doesn't match the `:` we
expect in the grammar rule), and hence we get a syntax error.

If we change the `=` to some other character (e.g. a `-`), we instead
get

```
module [0, 0] - [2, 0]
  expression_statement [0, 0] - [0, 11]
    string [0, 0] - [0, 11]
      string_start [0, 0] - [0, 2]
      interpolation [0, 2] - [0, 10]
        "{" [0, 2] - [0, 3]
        expression: identifier [0, 3] - [0, 4]
        format_specifier: format_specifier [0, 4] - [0, 9]
          ":" [0, 4] - [0, 5]
        "}" [0, 9] - [0, 10]
      string_end [0, 10] - [0, 11]
```
and in particular no syntax error.

To fix this, we want to ensure that the `:` is lexed on its own, and the
`token(prec(1, ...))` construction can be used to do exactly this.

Finally, you may wonder why `=` is special here. I think what's going on
is that the lexer knows that `:=` is a token on its own (because it's
used in the walrus operator), and so it greedily consumes the following
`=` with this in mind.
2026-02-05 13:45:54 +00:00
Paolo Tranquilli
05bef12ddd Merge pull request #21265 from github/redsun82/csharp-csrf-inheritance
C#: Fix CSRF query to check antiforgery attributes on base classes
2026-02-05 14:20:30 +01:00
Idriss Riouak
1df3adf021 Merge pull request #21244 from github/idrissrio/cpp/overlay/changes-json
C/C++ overlay: use files table instead of `overlayChangedFiles` for overlay discard
2026-02-05 13:15:07 +01:00
idrissrio
e26c199426 C/C++ overlay: use files table instead of overlayChangedFiles for overlay discard 2026-02-05 12:43:01 +01:00
Tom Hvitved
1203da1b66 Merge pull request #21253 from paldepind/rust/as-path-trait
Rust: Resolve `as` paths to trait
2026-02-05 12:38:16 +01:00
Paolo Tranquilli
f79bd3f4cf C#: accept location changes in test 2026-02-05 12:14:59 +01:00
Mathias Vorreiter Pedersen
476df7de73 Merge pull request #21260 from MathiasVP/add-windows-remote-flow-sources
C++: Add more Win32 and Azure SDK remote flow sources
2026-02-05 10:47:03 +00:00
Anders Schack-Mulligen
29e01748b7 Merge pull request #21267 from aschackmull/java/rename-misc
Java: Rename several AST predicates.
2026-02-05 11:15:29 +01:00
Anders Schack-Mulligen
11003e685d Java: Fix qldoc 2026-02-05 10:37:19 +01:00
Anders Schack-Mulligen
e4daeec2ca Merge pull request #21268 from aschackmull/java/view-cfg
Java: Add support for "View CFG" in VSCode.
2026-02-05 09:48:14 +01:00
Anders Schack-Mulligen
81977f11a1 Cfg: qldoc + overlay fixups. 2026-02-05 08:59:28 +01:00
Anders Schack-Mulligen
32fe12a6dd Java: Delay deprecation a bit. 2026-02-05 08:51:27 +01:00
Anders Schack-Mulligen
83adf793e4 Cfg: Fix compilation. 2026-02-04 15:28:37 +01:00
Simon Friis Vindum
52dc58172d Merge branch 'main' into rust/as-path-trait 2026-02-04 14:47:57 +01:00
Owen Mansel-Chan
544931f73f Merge pull request #21266 from owen-mc/python/pretty-print-models-in-test
Python: Pretty print models in test
2026-02-04 13:46:51 +00:00
Anders Schack-Mulligen
2d02908e7f Java: Add change note. 2026-02-04 14:43:32 +01:00
Anders Schack-Mulligen
4fcf3fbff8 Java: Make loop classes extend LoopStmt and use getBody instead of getStmt. 2026-02-04 14:43:31 +01:00
Anders Schack-Mulligen
6f40ac15b4 Java: Rename ReturnStmt.getResult to getExpr. 2026-02-04 14:43:31 +01:00
Simon Friis Vindum
55ea55a44f Merge pull request #21247 from paldepind/rust/self-types
Rust: Resolve `Self` paths in type definitions
2026-02-04 13:41:53 +01:00
Anders Schack-Mulligen
36fa0a22f9 Java: Rename getTrueExpr/getFalseExpr on ConditionalExpr to getThen/getElse. 2026-02-04 13:38:11 +01:00
Owen Mansel-Chan
3f08ff88a4 Pretty print models in test
Otherwise the tests breaks when unrelated changes are made because the
model numbers change
2026-02-04 10:52:44 +00:00
Anders Schack-Mulligen
5e6e64b2b7 Java: Rename UnaryExpr.getExpr to getOperand. 2026-02-04 10:50:49 +01:00
Paolo Tranquilli
4973523404 C#: Fix CSRF query to check antiforgery attributes on base classes
Fixes https://github.com/github/codeql/discussions/21255
2026-02-04 09:42:20 +01:00
Anders Schack-Mulligen
2d61fc5309 Java: Add support for "View CFG". 2026-02-03 15:49:27 +01:00
Michael B. Gale
8e39ed079e Merge pull request #21252 from github/mbg/go/private-registry-diagnostic
Go: Add diagnostic for private registry usage
2026-02-03 14:36:19 +00:00
Anders Schack-Mulligen
389cd5d648 Cfg: Extract CFG pretty-printing code. 2026-02-03 15:33:55 +01:00
Mathias Vorreiter Pedersen
092d25451f C++: Fix Copilot comments. 2026-02-03 11:45:30 +00:00
Mathias Vorreiter Pedersen
32b86eca50 C++: Add change note. 2026-02-03 11:40:31 +00:00
Mathias Vorreiter Pedersen
40a58135c2 C++: Accept test changes. 2026-02-03 11:30:55 +00:00
Mathias Vorreiter Pedersen
7ef96e3f3c C++: Add taint-inheriting reads from the Winhttp structs. 2026-02-03 11:30:31 +00:00
Mathias Vorreiter Pedersen
5531ef9bc1 C++: Accept test changes. 2026-02-03 11:17:23 +00:00
Mathias Vorreiter Pedersen
cbc2dbc14d C++: Add flow sources and summary models. 2026-02-03 11:14:16 +00:00
Mathias Vorreiter Pedersen
208cf716dc C++: Add tests with tests for remote flow sources from the Win32 API and from the Azure SDK. 2026-02-03 11:13:45 +00:00
Simon Friis Vindum
d72d8b63ed Rust: Fix inconsistency by skipping Self in use globs 2026-02-03 11:54:28 +01:00
Simon Friis Vindum
1791c1f1f9 Rust: Add test with path resolution inconsistency 2026-02-03 11:51:55 +01:00
Michael B. Gale
d5c4a19efa Apply suggestions from code review
Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com>
2026-02-03 10:34:14 +00:00
Tom Hvitved
6fbf727309 Merge pull request #21251 from hvitved/rust/fix-bad-join
Rust: Fix bad join
2026-02-02 19:12:30 +01:00
Owen Mansel-Chan
e00390d23a Merge pull request #21224 from owen-mc/go/use-shared-basic-block-lib
Go: Use shared basic block lib
2026-02-02 16:31:06 +00:00
Michael B. Gale
d079671ec8 Align testItems with what getEnvVars does 2026-02-02 16:17:22 +00:00
Michael B. Gale
cbbc057dd3 Fix singular/plural wording and add test 2026-02-02 16:15:36 +00:00
Simon Friis Vindum
9fc2a54712 Rust: Accept changes to expected files for consistency checks 2026-02-02 17:12:25 +01:00
Simon Friis Vindum
d0e30d19c4 Rust: Resolve as paths to trait 2026-02-02 16:47:43 +01:00
Simon Friis Vindum
8de37fec17 Rust: Add tests with as paths 2026-02-02 16:43:21 +01:00
Henry Mercer
e712e62f14 Merge pull request #21250 from github/post-release-prep/codeql-cli-2.24.1
Post-release preparation for codeql-cli-2.24.1
2026-02-02 07:31:39 -08:00
Michael B. Gale
30b30d65c8 Emit the new diagnostic 2026-02-02 14:47:25 +00:00
Michael B. Gale
6d67e419ff Move private registry sources out of util package 2026-02-02 14:45:06 +00:00
Michael B. Gale
29930fa6bf Track active proxy configurations 2026-02-02 14:40:08 +00:00
Michael B. Gale
a57c6cde30 Add EmitPrivateRegistryUsed 2026-02-02 14:39:27 +00:00
Tom Hvitved
b16f1d3778 Rust: Fix bad join
Before
```
Evaluated relational algebra for predicate _PathResolution::ImplItemNode.getTraitPath/0#dispred#3b7d1cb6_PathResolution::ImplOrTraitItemNode.ge__#shared@0d3de6d9 with tuple counts:
         395360270  ~2%    {5} r1 = JOIN Type::TAssociatedTypeTypeParameter#6da9e52a WITH `PathResolution::ImplItemNode.getTraitPath/0#dispred#3b7d1cb6` CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.0, Lhs.1, Lhs.2, Rhs.1
        1274237644  ~0%    {6}    | JOIN WITH `PathResolution::ItemNode.getASuccessor/1#8f430f71` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.4, Rhs.1, Rhs.2
        1274237644  ~0%    {6}    | JOIN WITH PathResolution::TraitItemNode#8d4ce62d ON FIRST 1 OUTPUT Lhs.0, Lhs.4, Lhs.1, Lhs.2, Lhs.3, Lhs.5
           6984871  ~0%    {5}    | JOIN WITH `PathResolution::ImplOrTraitItemNode.getAssocItem/1#f77bb9ed` ON FIRST 3 OUTPUT Lhs.2, Lhs.0, Lhs.3, Lhs.4, Lhs.5
           6984871  ~0%    {4}    | JOIN WITH TypeAlias::Generated::TypeAlias#1ca97780 ON FIRST 1 OUTPUT Lhs.4, Lhs.1, Lhs.2, Lhs.3
           6076675  ~0%    {4}    | JOIN WITH `TypeAlias::Generated::TypeAlias.getTypeRepr/0#dispred#5fd7e521` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3
                           return r1
```

After
```
Evaluated relational algebra for predicate _PathResolution::ImplItemNode.getTraitPath/0#dispred#3b7d1cb6_PathResolution::ImplOrTraitItemNode.ge__#shared@760e0499 with tuple counts:
          443292  ~2%    {3} r1 = SCAN `PathResolution::ImplOrTraitItemNode.getAssocItem/1#f77bb9ed` OUTPUT In.0, In.2, In.1
            1258  ~1%    {3}    | JOIN WITH Type::TAssociatedTypeTypeParameter#6da9e52a ON FIRST 2 OUTPUT Lhs.2, Lhs.0, Rhs.2
        13656944  ~3%    {4}    | JOIN WITH `PathResolution::ItemNode.getASuccessor/1#8f430f71_102#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Rhs.2
         6984871  ~0%    {4}    | JOIN WITH `PathResolution::ImplItemNode.getTraitPath/0#dispred#3b7d1cb6` ON FIRST 1 OUTPUT Lhs.3, Lhs.1, Lhs.2, Rhs.1
         6076675  ~0%    {4}    | JOIN WITH `TypeAlias::Generated::TypeAlias.getTypeRepr/0#dispred#5fd7e521` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3
                         return r1
```
2026-02-02 15:26:32 +01:00
github-actions[bot]
73d06f26cb Post-release preparation for codeql-cli-2.24.1 2026-02-02 14:04:26 +00:00
Henry Mercer
fedb9464af Merge pull request #21248 from github/henrymercer/fix-mysql-typo
Fix capitalization of MySQL
2026-02-02 05:33:39 -08:00
Simon Friis Vindum
99b498b891 Rust: Resolve Self paths in type definitions 2026-02-02 13:51:59 +01:00
Simon Friis Vindum
95afe615b5 Rust: Add path resolution tests 2026-02-02 13:51:57 +01:00
Simon Friis Vindum
8b03608a4f Merge pull request #21188 from paldepind/rust/self-path-assoc
Rust: Implement type inference for associated types for concrete types
2026-02-02 13:50:43 +01:00
Henry Mercer
1a6b2b9b82 Fix capitalization of MySQL 2026-02-02 12:37:32 +00:00
Henry Mercer
57c2208f7a Merge pull request #21246 from github/henrymercer/kotlin/version-range-formatting
Fix formatting of Kotlin version ranges
2026-02-02 04:30:52 -08:00
Henry Mercer
5f1fd57f84 Fix formatting of Kotlin version ranges 2026-02-02 12:22:50 +00:00
Henry Mercer
6b78313701 Merge pull request #21245 from github/release-prep/2.24.1
Release preparation for version 2.24.1
2026-02-02 04:12:14 -08:00
Henry Mercer
38fcc61817 Fix formatting in Kotlin changelog 2026-02-02 12:10:15 +00:00
github-actions[bot]
0db542e9f0 Release preparation for version 2.24.1 2026-02-02 12:09:09 +00:00
Tom Hvitved
4a04f7b66f Merge pull request #21243 from hvitved/csharp/insecure-object-tests
C#: Add more tests for `InsecureDirectObjectReference.ql`
2026-02-02 13:03:23 +01:00
Simon Friis Vindum
0567864a83 Rust: Make module private
Co-authored-by: Tom Hvitved <hvitved@github.com>
2026-02-02 12:57:26 +01:00
Simon Friis Vindum
18576838d4 Rust: Minor tweaks and improvements 2026-02-02 12:07:18 +01:00
Tom Hvitved
fe0634574d C#: Add more tests for InsecureDirectObjectReference.ql 2026-02-02 11:09:26 +01:00
Michael B. Gale
9a00c75460 Merge pull request #21236 from github/mbg/csharp/fix-registry-feeds
C#: Make sure `allFeeds` contains at least `explicitFeeds`
2026-02-02 07:49:33 +00:00
Owen Mansel-Chan
5204255615 Merge pull request #21234 from owen-mc/python/convert-sanitizers-to-mad
Python: Allow models-as-data sanitizers
2026-01-30 14:28:39 +00:00
Owen Mansel-Chan
0222159df5 Specify vulnerable args instead of safe ones 2026-01-30 14:10:03 +00:00
Michael B. Gale
454d13b485 Remove element check 2026-01-30 14:03:43 +00:00
Mathias Vorreiter Pedersen
16670511de Merge pull request #21239 from MathiasVP/logical-binary-fix-guards-cpp
C++: Ensure that there are AST `GuardCondition`s for `||` and `&&`
2026-01-30 13:50:55 +00:00
Michael B. Gale
ad2aa6d4f8 Accept expected diagnostic output 2026-01-30 13:38:50 +00:00
Michael B. Gale
3e0719609f Fix missing negation 2026-01-30 13:30:47 +00:00
Michael B. Gale
1aba0b20cd Add integration test 2026-01-30 13:19:47 +00:00
Michael B. Gale
1b5ed129ac Log and emit diagnostic if incorrectly named files are found 2026-01-30 13:19:46 +00:00
Mathias Vorreiter Pedersen
5f079c1d51 C++: Add change note. 2026-01-30 12:19:28 +00:00
Michael B. Gale
5ba3b679dd Move into if statement 2026-01-30 12:18:56 +00:00
yoff
8c0baefd3b Merge pull request #21141 from mbaluda/prompt-injection
Python: Prompt injection in OpenAI clients
2026-01-30 12:55:56 +01:00
Anders Peter Fugmann
78495035a6 Merge pull request #20965 from github/andersfugmann/kotlin_2.3.0-beta2
Kotlin: Support Kotlin 2.3.0
2026-01-30 11:37:19 +01:00
Owen Mansel-Chan
a3885cd8b2 Replace sanitizer by exclusion from sink definition 2026-01-30 09:28:02 +00:00
Owen Mansel-Chan
b4cb2c3f13 Make qldoc slightly more specific 2026-01-30 09:28:01 +00:00
Owen Mansel-Chan
ef6332c581 Allow MaD sanitizers for queries with MaD sinks 2026-01-30 09:27:59 +00:00
Owen Mansel-Chan
ad6f800022 Pretty print model numbers in tests 2026-01-30 09:21:24 +00:00
Owen Mansel-Chan
e5f52f086c Merge pull request #21235 from owen-mc/shared/docs/provenance-path-graph
Shared: Add missing QLDocs
2026-01-30 09:02:48 +00:00
Jon Janego
18a2aca42f Merge pull request #21237 from github/urllib-typo-fix
Urllib typo fix
2026-01-29 17:32:12 -06:00
yoff
e7a0fc7140 python: Add query for prompt injection
This pull request introduces a new CodeQL query for detecting prompt injection vulnerabilities in Python code targeting AI prompting APIs such as agents and openai. The changes includes a new experimental query, new taint flow and type models, a customizable dataflow configuration, documentation, and comprehensive test coverage.
2026-01-29 23:47:52 +01:00
Jon Janego
f14ccd8c81 Fix typo in taint flow model for urllib.parse 2026-01-29 16:21:14 -06:00
Jon Janego
e54d7c7c73 Update CHANGELOG.md 2026-01-29 16:20:25 -06:00
Jon Janego
813d4639ca Fix typo in taint flow model for urllib.parse 2026-01-29 16:18:21 -06:00
Michael B. Gale
76fe3fa502 C#: Make sure allFeeds contains at least explicitFeeds 2026-01-29 21:43:44 +00:00
Owen Mansel-Chan
8b936c5dbe Add missing QLDocs 2026-01-29 16:45:23 +00:00
Taus
34800d1519 Merge pull request #20945 from joefarebrother/python-websockets
Python: Model remote flow sources for the `websockets` library
2026-01-29 15:47:46 +01:00
Jon Janego
1644376cc9 Merge pull request #21222 from github/codeql-spark-run-21376405640
Update changelog documentation site
2026-01-29 08:44:11 -06:00
Mathias Vorreiter Pedersen
1b1c9c680c Merge pull request #21227 from MathiasVP/postfix-fix
C++: Get rid of an ugly workaround in dataflow
2026-01-29 12:25:02 +00:00
Mathias Vorreiter Pedersen
61a53fadc0 C++: Fix spelling. 2026-01-29 11:50:44 +00:00
Owen Mansel-Chan
2f29c905c3 Fix typo in change note
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-28 22:39:08 +00:00
Owen Mansel-Chan
e1cf0a15ed Add change note 2026-01-28 22:12:31 +00:00
Owen Mansel-Chan
52c510bfea Use shared getScope instead of getRoot 2026-01-28 22:12:30 +00:00
Owen Mansel-Chan
b2f878229d Use shared getASuccessor and getAPredecessor 2026-01-28 22:12:23 +00:00
Owen Mansel-Chan
3dd6b3fb69 Use shared basic blocks library 2026-01-28 22:11:59 +00:00
Owen Mansel-Chan
c316d51d41 Add ConditionGuardNode.getOutcome 2026-01-28 21:46:26 +00:00
Mathias Vorreiter Pedersen
25647badbd C++: Fix the AST wrapper for binary logical operators. 2026-01-28 14:06:10 +00:00
Mathias Vorreiter Pedersen
6445fd805d C++: Fix IR -> AST mapping for basic blocks. 2026-01-28 14:01:34 +00:00
Owen Mansel-Chan
a35e7b27af Merge pull request #21226 from owen-mc/java/update-qhelp-unrelease-lock
Java: Improve qhelp for `java/unreleased-lock` and add lock type exclusion
2026-01-28 09:46:31 +00:00
Anders Fugmann
ab495fa843 Kotlin: Inline cast 2026-01-28 10:11:22 +01:00
Anders Fugmann
2320d502db Kotlin: Address detections from kotin internal queries 2026-01-28 10:11:21 +01:00
Anders Fugmann
31867a56fb Kotlin: Accept test changes
Accept test changes from Kotlin 2.3.0 update

Updates expected test outputs for kotlin2 library tests to match
actual compiler output. Changes include:
- Location adjustments for properties/methods (now point to identifiers)
- CastExpr -> ImplicitCastExpr for implicit type casts
- Removed duplicate BlockStmt entries in loop ASTs
- Super constructor call location changes

Note that in Kotlin 2.3.0 super constructor calls now have locations spanning
entire class declarations instead of the actual super call site.
2026-01-28 10:11:21 +01:00
Anders Fugmann
86d9c349ec Kotlin: Accept test changes 2026-01-28 10:11:21 +01:00
Anders Fugmann
59fa01e386 Kotlin: Add bitwise 'and' operation expected by Kotlin 2.3 compiler to exist in the stdlib 2026-01-28 10:11:20 +01:00
Anders Fugmann
a6f8af0de5 Kotlin: Accept column location changes in tests 2026-01-28 10:11:20 +01:00
Anders Fugmann
f6f5b7e1e9 Kotlin: Accept test changes after rebasing to include changes from https://github.com/github/codeql/pull/21216 2026-01-28 10:11:19 +01:00
Anders Fugmann
275724000b Kotlin: Update kotlin serialization integration test to use Kotlin compiler 1.8.10 and accept test changes 2026-01-28 09:30:22 +01:00
Anders Fugmann
939f3e83aa Kotlin: Update kotlin compiler version in integration tests 2026-01-28 09:30:22 +01:00
Anders Fugmann
d69fe20d7d Kotlin: Bump upper bound for supported kotlin version in integration test 2026-01-28 09:30:22 +01:00
Anders Fugmann
9f5de6b4f2 Kotlin: Bump versions in documentation 2026-01-28 09:30:21 +01:00
Anders Fugmann
6d60595d73 Kotlin: Add changenotes for Kotlin 2.3 support and removal of support for Kotlin 1.6 and 1.7 2026-01-28 09:30:21 +01:00
Anders Fugmann
e1f3d5b374 Kotlin: Do not skip writing of getter and setters if the local deligate is null 2026-01-28 09:30:20 +01:00
Anders Fugmann
5cdfb77504 Kotlin: Add additional warning suppresion to v1_9_0 and remove copy in v2_3_0 2026-01-28 09:30:20 +01:00
Anders Fugmann
8ee35231c2 Kotlin: Remove support for Kotlin versions 1.6 and 1.7
This change rolls up all files from v1_6_0, v1_6_20, v1_7_0 and v_1_7_20.
In addition, versioned files that are not overridden by any later Kotlin versions (i.e. files that only have one copy under utils/versions) are inlined and removed to simplify list of changes.

List of removed/inlined files:
     allOverriddenIncludingSelf.kt
     copyTo.kt
     ExperimentalCompilerApi.kt
     getFileClassFqName.kt
     IsUnderscoreParameter.kt
     ReferenceEntity.kt
     SyntheticBodyKind.kt
     Types.kt
     withHasQuestionMark.kt
2026-01-28 09:30:20 +01:00
Anders Fugmann
55525279ca Kotlin: Remove obsolete file 2026-01-28 09:30:19 +01:00
Anders Fugmann
4d7c84178a Kotlin: Fix spelling 2026-01-28 09:30:19 +01:00
Anders Fugmann
eb37255c4b Kotlin: Create IrSimpleType factory function to support constructor changes introduced in Kotlin 2.3 2026-01-28 09:30:18 +01:00
Anders Fugmann
164cae845d Kotlin: Strip prefix when building plugin 2026-01-28 09:30:18 +01:00
Anders Fugmann
b8d01ed21b Kotlin: Fix bazel format and address copilot review comments 2026-01-28 09:30:18 +01:00
Anders Fugmann
cc25d30fed Kotlin: Update compiler plugin for Kotlin 2.3.0 2026-01-28 09:30:17 +01:00
Anders Fugmann
07e5479aff Kotlin: Add support for Kotlin 2.3.0 2026-01-28 09:30:17 +01:00
Anders Fugmann
bc419fd35c Kotlin: Silence compilation warnings 2026-01-28 09:30:16 +01:00
Anders Fugmann
772503bad8 Kotlin: Remove resource_strip_prefix for kotlin extraction 2026-01-28 09:30:16 +01:00
Anders Fugmann
beff080ee7 Kotlin: Update kotlin_rules to 2.2.0 and remove support for Kotlin 1.6 and 1.7 2026-01-28 09:30:16 +01:00
Anders Peter Fugmann
f4edff9452 Merge pull request #21216 from github/andersfugmann/kotlin_extractor_load_last
Kotlin: Load kotlin extractor last
2026-01-28 09:22:46 +01:00
Mathias Vorreiter Pedersen
4503c625b4 C++: Implement copilot suggestions. 2026-01-27 19:02:28 +00:00
Mathias Vorreiter Pedersen
28fec0c129 C++: Accept test changes. 2026-01-27 18:29:21 +00:00
Mathias Vorreiter Pedersen
445cca1432 C++: Proper SSA support for post-crement reads. 2026-01-27 18:29:12 +00:00
Henry Mercer
497135593c Merge branch 'main' into codeql-spark-run-21376405640 2026-01-27 09:11:02 -08:00
Henry Mercer
2214a944bb Merge pull request #21225 from github/rc/3.20
Merge `rc/3.20` back to `main`
2026-01-27 07:56:58 -08:00
Owen Mansel-Chan
a0c35516bd Add change note 2026-01-27 15:48:04 +00:00
Owen Mansel-Chan
42cbe0734e Specify what lock types are considered in qhelp 2026-01-27 15:39:03 +00:00
Owen Mansel-Chan
516b84b59a Add test for *Pool exclusion 2026-01-27 15:38:29 +00:00
Owen Mansel-Chan
4f1ad0ff5d Exclude *Pool classes from LockType 2026-01-27 15:38:06 +00:00
Jon Janego
ccc4d8ae3f Update docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.24.0.rst
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-27 09:18:25 -06:00
Simon Friis Vindum
2cb0e81da0 Rust: Remove duplicated inclusion of getAdditionalPathTypeAt 2026-01-27 16:17:52 +01:00
Simon Friis Vindum
aae5333325 Rust: Add test with type inference inconsistency 2026-01-27 16:17:51 +01:00
Simon Friis Vindum
fa59a8ae24 Rust: Implement TypeMention for paths that access associated types on concrete types 2026-01-27 16:17:49 +01:00
Simon Friis Vindum
4526afc29f Rust: Paths to associated types resolve to the associated type if implementation is unclear 2026-01-27 16:17:48 +01:00
Jon Janego
1c5a9053f9 Fix typo in call graph description in change notes 2026-01-27 09:17:40 -06:00
Jon Janego
5a08adc06c Update docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-27 09:11:01 -06:00
Jon Janego
0b8b75ac25 Update codeql-cli-2.23.1.rst 2026-01-27 09:10:37 -06:00
Mads Navntoft
b7125a009e Merge pull request #21221 from github/navntoft/struts
Java: Add support for Struts 7.x package names
2026-01-27 15:53:26 +01:00
Owen Mansel-Chan
97a0b9f0ca (trivial) Remove double spaces in qhelp 2026-01-27 14:40:23 +00:00
Ian Lynagh
46a5035543 Merge pull request #21200 from github/igfoo/rename-holdsInBase-to-isBase
C++: Rename `holdsInBase` to `isBase`
2026-01-27 13:50:04 +00:00
Ian Lynagh
bb71790a53 Merge pull request #21199 from github/igfoo/refactorOverlayFunctionCalls
C++ overlay: Simplify QL
2026-01-27 13:03:01 +00:00
Mathias Vorreiter Pedersen
db3f22a2e8 C++: Another small refactor. 2026-01-27 12:46:52 +00:00
Mathias Vorreiter Pedersen
3d445be926 C++: Small refactor. 2026-01-27 12:46:48 +00:00
Mads Navntoft
ede05b54ea Java: Add change note for Struts 7.x package name support 2026-01-27 13:00:16 +01:00
Mads Navntoft
9a94d0474c Java: Add support for Struts 7.x package names
Updates Struts library to recognize both legacy xwork2 and new struts2
packages:
- StrutsActions.qll: Add org.apache.struts2 alternatives for Action,
  Preparable, ActionSupport
- StrutsConventions.qll: Add org.apache.struts2.action.Action
  alternative

This maintains backward compatibility for analyzing Struts 2.x-6.x apps
while supporting Struts 7.x which renamed packages from
com.opensymphony.xwork2 to org.apache.struts2.
2026-01-27 12:57:55 +01:00
Mathias Vorreiter Pedersen
9e9d57bac5 Merge pull request #21219 from MathiasVP/force-more-uniquess-in-buffer-overflow
C++: Enforce more uniqueness in `Buffer.qll`
2026-01-27 11:00:40 +00:00
Owen Mansel-Chan
8e3c373548 Merge pull request #21223 from github/workflow/coverage/update
Update CSV framework coverage reports
2026-01-27 10:35:28 +00:00
Owen Mansel-Chan
5bfeede364 Add dependency on shared controlflow library 2026-01-27 09:43:19 +00:00
github-actions[bot]
f49531b3ca Add changed framework coverage reports 2026-01-27 00:28:39 +00:00
github-actions[bot]
0f4f0b880a update codeql documentation 2026-01-26 22:32:02 +00:00
Mathias Vorreiter Pedersen
e0a7889b71 C++: Undo the hack. 2026-01-26 21:28:21 +00:00
Mathias Vorreiter Pedersen
bd09aad7d5 C++: Add tests. 2026-01-26 21:24:22 +00:00
Mathias Vorreiter Pedersen
980c4cf5f4 Update cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-26 19:12:38 +00:00
Mathias Vorreiter Pedersen
544015d0a6 C++: Add change note. 2026-01-26 19:12:14 +00:00
Tom Hvitved
b974a84bef Merge pull request #21051 from hvitved/shared/flow-summary-provenance-filtering
Shared: Provenance-based filtering of flow summaries
2026-01-26 17:24:34 +01:00
Mathias Vorreiter Pedersen
aed0e688f5 C++: Remove uniqueness since it is enforced earlier now. 2026-01-26 15:01:40 +00:00
Mathias Vorreiter Pedersen
13a5249a9d C++: Enforce uniqueness in the other branch of 'getSize'. 2026-01-26 15:00:58 +00:00
Mathias Vorreiter Pedersen
91752e5307 C++: Enforce uniqueness in 'getVariableSize'. 2026-01-26 15:00:00 +00:00
Simon Friis Vindum
330505c524 Rust: Add tests for associated types 2026-01-26 15:03:07 +01:00
Anders Fugmann
73850f1b56 Kotlin: Add changenote 2026-01-26 13:27:34 +01:00
yoff
2bd4ccee45 Merge pull request #21004 from yoff/python/mad-barriers
Python: MaD barriers
2026-01-26 13:11:21 +01:00
Tom Hvitved
df09f02981 Shared: Shadow hasManualModel in RelevantSummarizedCallable 2026-01-26 12:40:25 +01:00
Tom Hvitved
732c60c07c C#: Revert change to getASummarizedCallableTarget 2026-01-26 12:40:24 +01:00
Tom Hvitved
0f6bae0ae1 Add change notes 2026-01-26 12:40:22 +01:00
Tom Hvitved
93dad867cd JS: Adapt to changes in FlowSummaryImpl 2026-01-26 12:40:21 +01:00
Tom Hvitved
3b1e062985 C++: Adapt to changes in FlowSummaryImpl 2026-01-26 12:40:20 +01:00
Tom Hvitved
0adece7cde Python: Adapt to changes in FlowSummaryImpl 2026-01-26 12:40:19 +01:00
Tom Hvitved
739748c29b Go: Adapt to changes in FlowSummaryImpl 2026-01-26 12:40:18 +01:00
Tom Hvitved
47d9e8a357 Swift: Adapt to changes in FlowSummaryImpl 2026-01-26 12:40:17 +01:00
Tom Hvitved
7024b07dd2 Java: Adapt to changes in FlowSummaryImpl
Missing manual models were added using the following code added to `FlowSummaryImpl.qll`:

```ql
    private predicate testsummaryElement(
      Input::SummarizedCallableBase c, string namespace, string type, boolean subtypes, string name,
      string signature, string ext, string originalInput, string originalOutput, string kind,
      string provenance, string model, boolean isExact
    ) {
      exists(string input, string output, Callable baseCallable |
        summaryModel(namespace, type, subtypes, name, signature, ext, originalInput, originalOutput,
          kind, provenance, model) and
        baseCallable = interpretElement(namespace, type, subtypes, name, signature, ext, isExact) and
        (
          c.asCallable() = baseCallable and input = originalInput and output = originalOutput
          or
          correspondingKotlinParameterDefaultsArgSpec(baseCallable, c.asCallable(), originalInput,
            input) and
          correspondingKotlinParameterDefaultsArgSpec(baseCallable, c.asCallable(), originalOutput,
            output)
        )
      )
    }

    private predicate testsummaryElement2(
      string namespace, string type, boolean subtypes, string name, string signature, string ext,
      string originalInput, string originalOutput, string kind, string provenance, string model,
      string namespace2, string type2
    ) {
      exists(Input::SummarizedCallableBase c |
        testsummaryElement(c, namespace2, type2, _, _, _, ext, originalInput, originalOutput, kind,
          provenance, model, false) and
        testsummaryElement(c, namespace, type, subtypes, name, _, _, _, _, _, provenance, _, true) and
        signature = paramsString(c.asCallable()) and
        not testsummaryElement(c, _, _, _, _, _, _, originalInput, originalOutput, kind, provenance,
          _, true)
      )
    }

    private string getAMissingManualModel(string namespace2, string type2) {
      exists(
        string namespace, string type, boolean subtypes, string name, string signature, string ext,
        string originalInput, string originalOutput, string kind, string provenance, string model
      |
        testsummaryElement2(namespace, type, subtypes, name, signature, ext, originalInput,
          originalOutput, kind, provenance, model, namespace2, type2) and
        result =
          "- [\"" + namespace + "\", \"" + type + "\", True, \"" + name + "\", \"" + signature +
            "\", \"\", \"" + originalInput + "\", \"" + originalOutput + "\", \"" + kind + "\", \"" +
            provenance + "\"]"
      )
    }
```
2026-01-26 12:40:15 +01:00
Tom Hvitved
c975ae5231 Ruby: Adapt to changes in FlowSummaryImpl 2026-01-26 12:40:14 +01:00
Tom Hvitved
c4e0dda178 Rust: Adapt to changes in FlowSummaryImpl 2026-01-26 12:40:10 +01:00
Tom Hvitved
b11b091559 C#: Adapt to changes in FlowSummaryImpl 2026-01-26 12:39:38 +01:00
Tom Hvitved
4ce04e4749 Shared: Provenance-based filtering of flow summaries 2026-01-26 12:39:37 +01:00
Simon Friis Vindum
01cc19cffc Rust: Add trait visibility test using Self 2026-01-26 12:31:16 +01:00
Simon Friis Vindum
793d2c79de Merge pull request #21215 from paldepind/shared/type-mention-tree
Shared, Rust: Use `HasTypeTreeSig` for `TypeMention`
2026-01-26 12:00:02 +01:00
Michael B. Gale
f76211c64a Merge pull request #21136 from github/mbg/java/maven-plugin-repo-changenote
Java: Add change note for plugin repo support
2026-01-26 10:44:51 +00:00
Michael B. Gale
ffa700c825 Merge pull request #21214 from github/mbg/go/diagnostics-unit-tests
Go: Make diagnostics unit-testable and add test for `EmitCannotFindPackages`
2026-01-26 10:44:03 +00:00
Michael B. Gale
bd8a127565 Merge pull request #21213 from github/mbg/go/improve-package-not-found 2026-01-26 09:59:01 +00:00
Anders Fugmann
c488086135 Kotlin: Ensure the kotlin extractor is loaded as the last extension to be able to capture expansions from other extensions 2026-01-26 10:38:11 +01:00
Simon Friis Vindum
452d307fd5 Rust: Make TypeMention directly satisfy HasTypeTree 2026-01-26 09:46:33 +01:00
Simon Friis Vindum
7100ca4262 Rust: Adapt to changes in shared type inference library 2026-01-26 09:33:50 +01:00
Simon Friis Vindum
a7fecaaa1b Shared: Use HasTypeTreeSig for TypeMention 2026-01-26 09:29:51 +01:00
Michael B. Gale
45e0a929a8 Move nil check into FileDiagnosticsWriter implementation of WriteDiagnostic 2026-01-25 15:33:26 +00:00
Michael B. Gale
8e7d62600d Make EmitCannotFindPackages testable and add tests 2026-01-25 15:24:43 +00:00
Michael B. Gale
f1f4ddb76c Add dependency on testify/assert 2026-01-25 15:20:06 +00:00
Michael B. Gale
fafc2ddc0b Add DiagnosticsWriter interface to abstract over diagnostics output implementation 2026-01-25 15:20:05 +00:00
Michael B. Gale
f837d90060 Improve go/autobuilder/package-not-found diagnostic message 2026-01-25 15:18:19 +00:00
Michael B. Gale
fdc5ae375b Add IsActionsWorkflow 2026-01-25 12:39:56 +00:00
Michael B. Gale
e250c711aa Add IsDynamicActionsWorkflow 2026-01-25 12:06:30 +00:00
Mathias Vorreiter Pedersen
cabcb83b2f Merge pull request #21212 from MathiasVP/fix-as-definition
C++: Fix missing results for `Node.asDefinition`
2026-01-23 19:39:22 +00:00
Jeroen Ketema
e36080061d Merge pull request #21162 from owen-mc/cpp/mad-barriers
C++: Allow MaD barriers
2026-01-23 18:14:01 +01:00
Mathias Vorreiter Pedersen
6c2a3a68b6 C++: Add change note. 2026-01-23 16:35:02 +00:00
Mathias Vorreiter Pedersen
a556152b9d C++: Fix asDefinition to not only work for SSA definitions. 2026-01-23 16:23:21 +00:00
Mathias Vorreiter Pedersen
e58a8330cd C++: Add test for asDefinition. 2026-01-23 16:22:39 +00:00
Chris Smowton
949fc3745a Merge pull request #21211 from smowton/smowton/fix/long-actions-expressions
Actions: tolerate long `${{ ... }}` expressions
2026-01-23 07:54:59 -08:00
Chris Smowton
a326ce34a8 change note 2026-01-23 15:47:17 +00:00
Chris Smowton
9018401722 Add test 2026-01-23 15:37:40 +00:00
Chris Smowton
6c2e0f7658 Move library tests into subdirectory 2026-01-23 15:35:25 +00:00
Chris Smowton
dc26a57548 Use posessive quantifier to avoid stack overflow on large ${{}} expressions 2026-01-23 15:35:24 +00:00
Owen Mansel-Chan
82e2afc93c Merge pull request #5 from jketema/cpp/mad-barriers
C++: Add MySQL MaD taint and barrier models
2026-01-23 15:06:32 +00:00
Jeroen Ketema
7ed1c0a2ee C++: Add change note 2026-01-23 14:15:29 +01:00
Jeroen Ketema
ecd247bf16 C++: Add MaD models for MySQL escaping 2026-01-23 14:15:27 +01:00
Jeroen Ketema
ad590f30c1 Merge branch 'main' into cpp/mad-barriers 2026-01-23 14:14:22 +01:00
Jeroen Ketema
075041f1ae Merge pull request #21209 from jketema/jketema/sql
C++: Simplify `cpp/sql-injection` barrier
2026-01-23 13:33:19 +01:00
Rasmus Wriedt Larsen
7e674f3227 Merge pull request #21160 from owen-mc/scripts/accept-ci-changes-more-robust
Scripts: be more robust when parsing test logs
2026-01-23 11:49:06 +01:00
Geoffrey White
573ab025b4 Merge pull request #21191 from geoffw0/addsub
Rust: More test cases for add, sub etc
2026-01-23 10:30:21 +00:00
Simon Friis Vindum
7bdf2ab9d2 Merge pull request #21210 from paldepind/rust/self-tests
Rust: Add tests for `Self` constructors
2026-01-23 11:27:58 +01:00
Simon Friis Vindum
8f6f7d0985 Rust: Fix typo
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-23 10:07:11 +01:00
Simon Friis Vindum
3d7049265f Rust: Add tests for Self constructors 2026-01-23 09:06:49 +01:00
Jeroen Ketema
ccd07b8a63 C++: Simplify cpp/sql-injection barrier
SQL sanitizers will not likely also be sources, so using `isBarrierIn` here
does not make a lot of sense.

I ran with and without this change on MRVA and got identical results.
2026-01-23 09:03:48 +01:00
yoff
55abc52c61 python: format file 2026-01-22 20:51:46 +01:00
Simon Friis Vindum
e40f896b17 Merge pull request #21205 from paldepind/shared/ti-boound-tm
Rust: Change `getATypeParameterConstraint` to not require a `TypeMention`
2026-01-22 19:08:53 +01:00
yoff
d05901ad3f python/javascript/ruby: mark internal predicates 2026-01-22 17:30:24 +01:00
yoff
7f00a7f67e Update python/ql/lib/semmle/python/security/dataflow/UrlRedirectCustomizations.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2026-01-22 17:30:24 +01:00
yoff
b08c972cc3 ruby: Add back sanitizer as MaD model 2026-01-22 17:30:24 +01:00
yoff
15980cb1da ruby: remove sanitizer to be replaced by MaD model 2026-01-22 17:30:24 +01:00
yoff
75bd4a7a12 javascript: add MaD model
- consider if the model is in the right place
- consider if the barrier kind (sink kind) is the appropriate one
2026-01-22 17:30:24 +01:00
yoff
da2f77d615 javascript: remove sanitizer to be replaced by model 2026-01-22 17:30:24 +01:00
yoff
3dbfb9fa4b python: add machinery for MaD barriers
and reinstate previously removed barrier
now as a MaD row
2026-01-22 17:30:24 +01:00
yoff
699ed50432 python: remove barrier that can be expressed in MaD 2026-01-22 17:30:24 +01:00
Geoffrey White
f484d95081 Merge remote-tracking branch 'upstream/main' into addsub 2026-01-22 16:03:42 +00:00
Simon Friis Vindum
ffaf1c0a24 Rust: Change getATypeParameterConstraint to not require a TypeMention 2026-01-22 14:54:24 +01:00
Tom Hvitved
201512525b Merge pull request #21203 from hvitved/ql4ql/use-nightly
QL4QL: Use nightly CodeQL CLI
2026-01-22 14:30:24 +01:00
Geoffrey White
b8581e89bf Rust: More affected tests. 2026-01-22 13:22:43 +00:00
Simon Friis Vindum
7d34f6e262 Merge pull request #21204 from paldepind/rust/assoc-tp-fix
Rust: Remove mistakenly included inherited associated types
2026-01-22 13:46:09 +01:00
Geoffrey White
67b52e29e0 Rust: Update other affected tests. 2026-01-22 12:29:21 +00:00
Geoffrey White
3d6765ba1c Rust: Clean up / fix some existing models. 2026-01-22 12:29:20 +00:00
Geoffrey White
fa9677d615 Rust: Add model variants for core::ops::bit on Wrapping. 2026-01-22 12:29:14 +00:00
Geoffrey White
9d645508ea Rust: Add model variants for core::ops:arith on Wrapping. 2026-01-22 10:46:15 +00:00
Simon Friis Vindum
114db99dca Rust: Remove mistakenly included inherited associated types 2026-01-22 11:44:26 +01:00
Tom Hvitved
8ce2618b7d Merge pull request #21151 from hvitved/rust/disable-universal-conds-by-default
Type inference: Disable universal conditions by default
2026-01-22 11:19:50 +01:00
Geoffrey White
e8ef58d381 Rust: Fix an issue with identifying sources and sinks in the test. 2026-01-22 09:58:58 +00:00
Geoffrey White
f8d0a0d509 Rust: Expand the Wrapping test some more. 2026-01-22 09:52:26 +00:00
Tom Hvitved
80d543ecae QL4QL: Use nightly CodeQL CLI 2026-01-22 10:14:05 +01:00
Tom Hvitved
65ca8849f2 Type inference: Disable universal conditions 2026-01-22 09:56:52 +01:00
Mathias Vorreiter Pedersen
73eb3e262d Merge pull request #21202 from MathiasVP/add-is-live-predicate-to-ssa-definition
C++: Add `isLiveAtEndOfBlock` predicate to `Ssa::Definition`
2026-01-21 22:50:46 +00:00
Mathias Vorreiter Pedersen
60ee92d834 C++: Drive-by fix: Don't use the uncached ''getAPhiInputOrPriorDefinition' predicate. Instead, cache it and call it like we are supposed to. 2026-01-21 20:28:28 +00:00
Mathias Vorreiter Pedersen
d89967ce8e C++: Add ''isLiveAtEndOfBlock' predicate to 'Definition'. 2026-01-21 20:27:39 +00:00
Mathias Vorreiter Pedersen
dd415386ea Merge pull request #21142 from MathiasVP/ir-support-for-assertions
C++: Generate IR for assertions in release builds
2026-01-21 19:32:24 +00:00
Mathias Vorreiter Pedersen
64a7d7d836 C++: Also output variable name in test. 2026-01-21 19:14:50 +00:00
Ian Lynagh
5e536fb121 C++: Rename holdsInBase to isBase
Makes it consistent with isOverlay.
2026-01-21 18:13:58 +00:00
Ian Lynagh
7bd62087a4 C++ overlay: Simplify QL
Remove redundant variable names.
2026-01-21 18:06:43 +00:00
Owen Mansel-Chan
656ebab776 Allow MaD barriers
This commit was done by Opus 4.5 with the following prompt:

In the commit 004d40ee93 I have made it so that C# CodeQL queries which use sinks defined using data extensions (also known as "models-as-data"), which are accessed using `sinkNode(Node node, string kind)`, also use barriers defined using models-as-data, which are accessed using `barrierNode(Node node, string kind)`, with the same `kind` string. Please do the same for C++. If there are any complicated cases then list them at the end for me to do manually.
2026-01-21 14:45:05 +00:00
Mathias Vorreiter Pedersen
e1089c8d89 Merge branch 'main' into ir-support-for-assertions 2026-01-21 13:56:30 +00:00
Mathias Vorreiter Pedersen
11566ee256 C++: Accept test changes. 2026-01-21 13:50:28 +00:00
Mathias Vorreiter Pedersen
e4ec79255b C++: Fix bugs in variable resolution for assertions following review comments. 2026-01-21 13:50:27 +00:00
Mathias Vorreiter Pedersen
c30dffc7b9 C++: Add more tests. 2026-01-21 13:50:13 +00:00
Geoffrey White
1d461ff5ad Rust: Test unpacking the Wrapping number. 2026-01-21 12:49:59 +00:00
Mathias Vorreiter Pedersen
6ae1ea73f7 Merge pull request #21185 from MathiasVP/mad-cpp-guards
C++: Support models-as-data barriers and barrier guards
2026-01-21 12:13:49 +00:00
Paolo Tranquilli
0b9691aca2 Merge pull request #21047 from github/redsun82/codegen-readme
codegen: mention Rust in the README
2026-01-21 02:51:07 -08:00
Tom Hvitved
9a9e9ac23c Merge pull request #21168 from hvitved/rust/type-inference-remove-blanket-constraint-restriction
Rust: Remove restriction that blanket(-like) impls must have a constraint
2026-01-21 11:05:17 +01:00
Taus
5414bd2716 Merge pull request #21134 from yoff/python/support-ListElement-in-MaD
Python support `ListElement` in MaD
2026-01-20 23:38:02 +01:00
Mathias Vorreiter Pedersen
048afc2c88 C++: Add assertion inside catch block. This does not yet work because the 'LocalScopeVariable' does not have a result for 'getFunction'. 2026-01-20 21:31:52 +00:00
Tom Hvitved
f76d85c9c6 Address review comments 2026-01-20 21:06:20 +01:00
yoff
fa926456ef python: add changenote 2026-01-20 18:16:03 +01:00
Jon Janego
1c38fb6ad6 Merge pull request #21196 from github/changedocs-2.23.9
Changedocs 2.23.9
2026-01-20 10:43:21 -06:00
Jon Janego
b3b30a15b8 Changedocs for 2.23.9 2026-01-20 10:27:54 -06:00
Jon Janego
4ca508d420 Changedocs for 2.23.9 2026-01-20 10:23:36 -06:00
Jeroen Ketema
fbcb65a5d9 Merge pull request #21195 from jketema/jketema/embed
C++: Support C23/C++26 `#embed` preprocessor directives
2026-01-20 16:27:44 +01:00
Jeroen Ketema
701569bb20 Update cpp/ql/lib/semmle/code/cpp/Preprocessor.qll
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-20 16:05:51 +01:00
Jeroen Ketema
b35271a2ca C++: Add upgrade and downgrade script 2026-01-20 15:40:24 +01:00
Jeroen Ketema
28047fe625 C++: Update dbscheme stats file 2026-01-20 14:39:00 +01:00
Jeroen Ketema
e7044061fb C++: Support C23/C++26 #embed preprocessor directives 2026-01-20 14:38:58 +01:00
Ian Lynagh
f8f5094452 Merge pull request #20957 from igfoo/igfoo/consistent-metadata-and-overlay-support
C++ / JS / python: Be consistent in TRAP sections
2026-01-20 12:43:49 +00:00
Ian Lynagh
51b1ea84d3 ql for ql: Fix formatting 2026-01-20 12:12:20 +00:00
Ian Lynagh
49ced5fd9d C++: Add up/downgrade scripts 2026-01-20 11:57:29 +00:00
Ian Lynagh
d6d2855626 rust: Add up/downgrade scripts 2026-01-20 11:56:20 +00:00
Ian Lynagh
c37ab8f98e rust: Regenerate dbscheme 2026-01-20 11:56:16 +00:00
Ian Lynagh
1fd60c7671 Ruby: Add up/downgrade scripts 2026-01-20 11:56:16 +00:00
Ian Lynagh
82e9ea2da0 python: Add up/downgrade scripts 2026-01-20 11:56:16 +00:00
Ian Lynagh
a299174f4d javascript: Add up/downgrade scripts 2026-01-20 11:56:15 +00:00
Ian Lynagh
fdefb4d23a ql-for-ql: Regenerate dbscheme 2026-01-20 11:56:15 +00:00
Ian Lynagh
d2da49220b python: Regenerate dbscheme 2026-01-20 11:56:15 +00:00
Ian Lynagh
4b9c9e7a5a Ruby: Regenerate dbscheme 2026-01-20 11:56:15 +00:00
Ian Lynagh
df8029ff87 tree-sitter: Use more standard shared dbscheme sections
We now use the shared "Overlay support" and "Database metadata".
2026-01-20 11:56:15 +00:00
Ian Lynagh
4140121e96 javascript: Use more standard shared dbscheme sections
We now use the shared "Overlay support" and "Database metadata".
2026-01-20 11:56:14 +00:00
Ian Lynagh
7d6a1f72d5 C++: Use more standard shared dbscheme sections
We now use the shared "Overlay support" and "Database metadata".
2026-01-20 11:56:14 +00:00
Ian Lynagh
c6500e2759 tree-sitter: Add dbscheme regeneration instructions 2026-01-20 11:56:14 +00:00
Ian Lynagh
470bc7d6da ruby: Make 'dbscheme' a phony target 2026-01-20 11:56:14 +00:00
Ian Lynagh
d1175276ca python: Use more standard shared dbscheme sections
We now use the shared "Overlay support" and "Database metadata".
2026-01-20 11:56:13 +00:00
Ian Lynagh
d125e224ac python: Add dbscheme regeneration instructions 2026-01-20 11:56:13 +00:00
Philip Ginsbach-Chen
dc3b7aaab0 Merge pull request #21184 from github/ginsbach/OverlayDocumentation
add documentation for overlay annotations
2026-01-20 11:26:46 +00:00
Philip Ginsbach
8d5eb407ad incorporate additional suggestions from PR review 2026-01-20 11:17:15 +00:00
Tom Hvitved
224e5dece4 Merge pull request #21170 from paldepind/rust/type-inference-fns
Rust: Improve type inference for closures and function traits
2026-01-20 11:52:10 +01:00
Simon Friis Vindum
dd73399238 Rust: Tweak a comment
Co-authored-by: Tom Hvitved <hvitved@github.com>
2026-01-20 09:57:27 +01:00
Simon Friis Vindum
8e6f920ae2 Rust: Fix naming of mention_dyn_fn 2026-01-20 08:50:58 +01:00
Simon Friis Vindum
75cab960e2 Rust: Make AnyTraitFn abstract 2026-01-20 08:50:57 +01:00
Nick Rolfe
6fe76b3b11 Merge pull request #21190 from github/post-release-prep/codeql-cli-2.24.0
Post-release preparation for codeql-cli-2.24.0
2026-01-19 10:09:32 -08:00
Geoffrey White
ff6e598f72 Rust: Annotate failures with explanation. 2026-01-19 17:33:44 +00:00
Geoffrey White
fc5d5b4fcc Rust: Compress the existing core::ops::arith models a bit. 2026-01-19 17:33:41 +00:00
Geoffrey White
50fdc99b8c Rust: More test cases for operators, std::ops and std::num::Wrapping. 2026-01-19 16:58:03 +00:00
github-actions[bot]
48475e66af Post-release preparation for codeql-cli-2.24.0 2026-01-19 15:49:08 +00:00
Michael Nebel
93b3f65388 Merge pull request #21158 from michaelnebel/csharp/cfgforaccess
C# 14: Null conditional assignments.
2026-01-19 16:22:55 +01:00
Geoffrey White
a0311c0ea3 Rust: Test spacing. 2026-01-19 15:07:42 +00:00
Philip Ginsbach
930b17a2e2 clarify compileForOverlayEval only needed in language packs 2026-01-19 14:06:45 +00:00
Philip Ginsbach
efe413cbd0 expand overlay introduction with base/overlay context 2026-01-19 13:59:01 +00:00
Michael Nebel
7ff1c12e8f C#: Add some more tests. 2026-01-19 13:17:47 +01:00
Michael Nebel
7ae2b7698e C#: Relax the condition for when a qualified expression might be null. 2026-01-19 13:17:07 +01:00
Mathias Vorreiter Pedersen
d183dcd6fc C++: Add 'internal: do not use' comment. 2026-01-19 12:04:12 +00:00
Mathias Vorreiter Pedersen
c11b464492 C++: Autoformat. 2026-01-19 11:58:11 +00:00
Mathias Vorreiter Pedersen
b3631545d4 C++: Delete unnecessary conjuncts after review comments. 2026-01-19 11:57:45 +00:00
Mathias Vorreiter Pedersen
c47a9ddf83 Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-19 11:46:42 +00:00
Philip Ginsbach
4e478c3629 add overlay documentation to handbook and language spec 2026-01-19 11:45:18 +00:00
Mathias Vorreiter Pedersen
7aca94b1ca C++: Add change note. 2026-01-19 11:43:59 +00:00
Mathias Vorreiter Pedersen
c70633a0f7 C++: Fix Code Scanning alert. 2026-01-19 11:41:26 +00:00
Mathias Vorreiter Pedersen
58a3260c96 Update cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2026-01-19 11:33:48 +00:00
Mathias Vorreiter Pedersen
a11b271d6e C++: Finish up implementation of MaD barriers. 2026-01-19 11:30:23 +00:00
Anders Schack-Mulligen
48254800b1 WIP
C++: Add support for MaD barriers and barrier guards.
2026-01-19 11:30:21 +00:00
Mathias Vorreiter Pedersen
07ac8a5d81 C++: Parameterize the BarrierGuard modules. This is useful for barrier guards with flow states and will be necessary in the next commit for adding MaD specified barriers. 2026-01-19 11:30:19 +00:00
Mathias Vorreiter Pedersen
2b31928c7b C++: Add MaD barrier guard tests. 2026-01-19 11:30:17 +00:00
Philip Ginsbach
948623e767 add overlay annotation support to QL syntax highlighter 2026-01-19 10:36:11 +00:00
Tom Hvitved
fd309d6e49 Rust: Remove restriction that blanket(-like) impls must have a constraint 2026-01-19 11:21:58 +01:00
Michael Nebel
33fc2bab33 C#: Update test expected output. 2026-01-19 10:19:15 +01:00
Michael Nebel
beb7750c21 C#: Address review comments. 2026-01-19 10:06:14 +01:00
Michael Nebel
86198e3c43 C#: Add tests for out writeacceses. 2026-01-16 11:54:10 +01:00
Michael Nebel
bd1c6e6352 C#: Exclude the field access cases from missing argument call. 2026-01-16 11:54:09 +01:00
Michael Nebel
3d988e8e94 C#: Add field access for out assignments in the CFG. 2026-01-16 11:54:07 +01:00
Michael Nebel
812fdbe412 C#: Add change-note. 2026-01-16 11:54:06 +01:00
Michael Nebel
ab432ec2e9 C#: Update test expected output. 2026-01-16 11:54:04 +01:00
Michael Nebel
5942edf2d9 C#: Take null conditional assignments into account in MaybeNullExpr. 2026-01-16 11:54:02 +01:00
Michael Nebel
f0135e93c5 C#: Add a tests for MaybeNullExpr. 2026-01-16 11:54:01 +01:00
Michael Nebel
4ba89230db C#: Update test expected output. 2026-01-16 11:53:59 +01:00
Michael Nebel
0bf0cbae8f C#: Add some null conditional assignments CFG tests. 2026-01-16 11:53:57 +01:00
Michael Nebel
b061c4d083 C#: Update test expected output. 2026-01-16 11:53:55 +01:00
Michael Nebel
98949937dd C#: Add CFG support for null conditional assignments and include eg. field access in the CFG. 2026-01-16 11:53:54 +01:00
Simon Friis Vindum
78b88d3a44 Rust: Fix grammar in QLDoc
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-16 11:26:05 +01:00
Simon Friis Vindum
9ab29f9be0 Rust: Add a change note for type inference improvements for closures 2026-01-16 10:05:45 +01:00
Simon Friis Vindum
dabc5d54c9 Rust: Improve type inference for closures and function traits 2026-01-16 10:01:00 +01:00
Mathias Vorreiter Pedersen
03d6528687 Update cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedAssertion.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2026-01-15 15:58:28 +00:00
Mathias Vorreiter Pedersen
1b117900c2 Update cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2026-01-15 14:42:11 +00:00
Mathias Vorreiter Pedersen
d6ca1ca846 Update cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2026-01-15 14:41:13 +00:00
Simon Friis Vindum
196f6e1931 Rust: Add type inference tests for closures and function traits 2026-01-15 12:00:41 +01:00
Owen Mansel-Chan
657e26a375 Scripts: be more robust when parsing test logs 2026-01-13 11:36:27 +00:00
Mathias Vorreiter Pedersen
4f4baee888 C++: Fix Code Scanning alerts. 2026-01-12 21:08:02 +00:00
Mathias Vorreiter Pedersen
aa058c2cca C++: Generate IR for assertions in release builds. 2026-01-12 21:07:55 +00:00
Mathias Vorreiter Pedersen
a18f3b6859 C++: Avoid generating IR for a few cases where we will be synthesizing assertions. 2026-01-12 21:06:09 +00:00
Mathias Vorreiter Pedersen
67ab0fee83 C++: Add a few helper predicates. 2026-01-12 21:06:07 +00:00
Mathias Vorreiter Pedersen
6e3fd25b09 C++: Add tests for assertions in release builds. 2026-01-12 21:06:02 +00:00
Michael B. Gale
157487d8f2 Java: Add change note for plugin repo support 2026-01-09 12:49:12 +00:00
yoff
1ac3706e75 Python support ListElement in MaD 2026-01-09 13:08:06 +01:00
Paolo Tranquilli
6fc963177c codegen: mention Rust in the README
Updated README to reflect support for the Rust extractor and added details about Rust generated files.
2025-12-16 11:05:39 +01:00
Joe Farebrother
ac55cf9544 Update test and qldoc 2025-12-01 20:41:59 +00:00
Joe Farebrother
6fbae45d49 Update qldoc 2025-12-01 20:14:36 +00:00
Joe Farebrother
6a1e26c566 Add change note 2025-12-01 20:06:24 +00:00
Joe Farebrother
384e17a4ef Implement websockets models 2025-12-01 16:24:59 +00:00
846 changed files with 158435 additions and 93651 deletions

View File

@@ -27,6 +27,7 @@ jobs:
uses: github/codeql-action/init@main
with:
languages: javascript # does not matter
tools: nightly
- uses: ./.github/actions/os-version
id: os_version
### Build the extractor ###

View File

@@ -30,6 +30,7 @@ jobs:
uses: github/codeql-action/init@main
with:
languages: javascript # does not matter
tools: nightly
- uses: ./.github/actions/os-version
id: os_version
- uses: actions/cache@v3
@@ -75,6 +76,7 @@ jobs:
uses: github/codeql-action/init@main
with:
languages: javascript # does not matter
tools: nightly
- uses: ./.github/actions/os-version
id: os_version
- uses: actions/cache@v3

View File

@@ -24,7 +24,7 @@ bazel_dep(name = "bazel_skylib", version = "1.8.1")
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl")
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
bazel_dep(name = "fmt", version = "12.1.0-codeql.1")
bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1")
bazel_dep(name = "rules_kotlin", version = "2.2.0-codeql.1")
bazel_dep(name = "gazelle", version = "0.40.0")
bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.1")
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
@@ -221,10 +221,6 @@ use_repo(
kotlin_extractor_deps,
"codeql_kotlin_defaults",
"codeql_kotlin_embeddable",
"kotlin-compiler-1.6.0",
"kotlin-compiler-1.6.20",
"kotlin-compiler-1.7.0",
"kotlin-compiler-1.7.20",
"kotlin-compiler-1.8.0",
"kotlin-compiler-1.9.0-Beta",
"kotlin-compiler-1.9.20-Beta",
@@ -234,10 +230,7 @@ use_repo(
"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",
"kotlin-compiler-embeddable-1.7.20",
"kotlin-compiler-2.3.0",
"kotlin-compiler-embeddable-1.8.0",
"kotlin-compiler-embeddable-1.9.0-Beta",
"kotlin-compiler-embeddable-1.9.20-Beta",
@@ -247,10 +240,7 @@ use_repo(
"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",
"kotlin-stdlib-1.7.20",
"kotlin-compiler-embeddable-2.3.0",
"kotlin-stdlib-1.8.0",
"kotlin-stdlib-1.9.0-Beta",
"kotlin-stdlib-1.9.20-Beta",
@@ -260,6 +250,7 @@ use_repo(
"kotlin-stdlib-2.1.20-Beta1",
"kotlin-stdlib-2.2.0-Beta1",
"kotlin-stdlib-2.2.20-Beta2",
"kotlin-stdlib-2.3.0",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

View File

@@ -1,3 +1,9 @@
## 0.4.27
### Bug Fixes
* Fixed a crash when analysing a `${{ ... }}` expression over around 300 characters in length.
## 0.4.26
### Major Analysis Improvements

View File

@@ -0,0 +1,5 @@
## 0.4.27
### Bug Fixes
* Fixed a crash when analysing a `${{ ... }}` expression over around 300 characters in length.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.26
lastReleaseVersion: 0.4.27

View File

@@ -27,8 +27,8 @@ string getADelimitedExpression(YamlString s, int offset) {
// not just the last (greedy match) or first (reluctant match).
result =
s.getValue()
.regexpFind("\\$\\{\\{(?:[^}]|}(?!}))*\\}\\}", _, offset)
.regexpCapture("(\\$\\{\\{(?:[^}]|}(?!}))*\\}\\})", 1)
.regexpFind("\\$\\{\\{(?:[^}]|}(?!}))*+\\}\\}", _, offset)
.regexpCapture("(\\$\\{\\{(?:[^}]|}(?!}))*+\\}\\})", 1)
.trim()
}

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.26
version: 0.4.28-dev
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -1,3 +1,7 @@
## 0.6.19
No user-facing changes.
## 0.6.18
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 0.6.19
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.18
lastReleaseVersion: 0.6.19

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.6.18
version: 0.6.20-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -0,0 +1,5 @@
import codeql.actions.ast.internal.Ast
int getAnExpressionLength() { result = any(ExpressionImpl e).toString().length() }
select max(getAnExpressionLength())

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Sections for databaseMetadata and overlayChangedFiles
compatibility: full

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
class PreprocessorDirective extends @preprocdirect {
string toString() { none() }
}
class Location extends @location_default {
string toString() { none() }
}
from PreprocessorDirective ppd, int kind, int kind_new, Location l
where
preprocdirects(ppd, kind, l) and
if kind = 17 then kind_new = /* ppd_warning */ 18 else kind_new = kind
select ppd, kind_new, l

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: Support embed preprocessor directive
compatibility: partial
embeds.rel: delete
preprocdirects.rel: run preprocdirects.qlo

View File

@@ -1,3 +1,21 @@
## 7.1.0
### New Features
* Added a subclass `Embed` of `PreprocessorDirective` for C23 and C++26 `#embed` preprocessor directives.
* Added modules `DataFlow::ParameterizedBarrierGuard` and `DataFlow::ParameterizedInstructionBarrierGuard`. These modules provide the same features as `DataFlow::BarrierGuard` and `DataFlow::InstructionBarrierGuard`, but allow for an additional parameter to support properly using them in dataflow configurations that uses flow states.
### Minor Analysis Improvements
* The `Buffer.qll` library will no longer report incorrect buffer sizes on certain malformed databases. As a result, the queries `cpp/static-buffer-overflow`, `cpp/overflow-buffer`, `cpp/badly-bounded-write`, `cpp/overrunning-write`, `cpp/overrunning-write-with-float`, and `cpp/very-likely-overrunning-write` will report fewer false positives on such databases.
* Added `taint` summary models and `sql-injection` barrier models for the MySQL `mysql_real_escape_string` and `mysql_real_escape_string_quote` escaping functions.
* The predicate `SummarizedCallable.propagatesFlow` has been extended with the columns `Provenance p` and `boolean isExact`, and as a consequence the predicates `SummarizedCallable.hasProvenance` and `SummarizedCallable.hasExactModel` have been removed.
### Bug Fixes
* Fixed a bug in the `GuardCondition` library which sometimes prevented binary logical operators from being recognized as guard conditions. As a result, queries using `GuardCondition` may see improved results.
* Fixed a bug which caused `Node.asDefinition()` to not have a result for certain assignments.
## 7.0.0
### Breaking Changes

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added remote flow source models for the `winhttp.h` windows header and the Azure SDK core library for C/C++.

View File

@@ -0,0 +1,17 @@
## 7.1.0
### New Features
* Added a subclass `Embed` of `PreprocessorDirective` for C23 and C++26 `#embed` preprocessor directives.
* Added modules `DataFlow::ParameterizedBarrierGuard` and `DataFlow::ParameterizedInstructionBarrierGuard`. These modules provide the same features as `DataFlow::BarrierGuard` and `DataFlow::InstructionBarrierGuard`, but allow for an additional parameter to support properly using them in dataflow configurations that uses flow states.
### Minor Analysis Improvements
* The `Buffer.qll` library will no longer report incorrect buffer sizes on certain malformed databases. As a result, the queries `cpp/static-buffer-overflow`, `cpp/overflow-buffer`, `cpp/badly-bounded-write`, `cpp/overrunning-write`, `cpp/overrunning-write-with-float`, and `cpp/very-likely-overrunning-write` will report fewer false positives on such databases.
* Added `taint` summary models and `sql-injection` barrier models for the MySQL `mysql_real_escape_string` and `mysql_real_escape_string_quote` escaping functions.
* The predicate `SummarizedCallable.propagatesFlow` has been extended with the columns `Provenance p` and `boolean isExact`, and as a consequence the predicates `SummarizedCallable.hasProvenance` and `SummarizedCallable.hasExactModel` have been removed.
### Bug Fixes
* Fixed a bug in the `GuardCondition` library which sometimes prevented binary logical operators from being recognized as guard conditions. As a result, queries using `GuardCondition` may see improved results.
* Fixed a bug which caused `Node.asDefinition()` to not have a result for certain assignments.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 7.0.0
lastReleaseVersion: 7.1.0

View File

@@ -0,0 +1,14 @@
# partial model of the MySQL api
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["", "", False, "mysql_real_escape_string", "", "", "Argument[*2]", "Argument[*1]", "taint", "manual"]
- ["", "", False, "mysql_real_escape_string_quote", "", "", "Argument[*2]", "Argument[*1]", "taint", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: barrierModel
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
- ["", "", False, "mysql_real_escape_string", "", "", "Argument[*1]", "sql-injection", "manual"]
- ["", "", False, "mysql_real_escape_string_quote", "", "", "Argument[*1]", "sql-injection", "manual"]

View File

@@ -24,6 +24,13 @@ extensions:
- ["", "", False, "MapViewOfFileNuma2", "", "", "ReturnValue[*]", "local", "manual"]
# ntifs.h
- ["", "", False, "NtReadFile", "", "", "Argument[*5]", "local", "manual"]
# winhttp.h
- ["", "", False, "WinHttpReadData", "", "", "Argument[*1]", "remote", "manual"]
- ["", "", False, "WinHttpReadDataEx", "", "", "Argument[*1]", "remote", "manual"]
- ["", "", False, "WinHttpQueryHeaders", "", "", "Argument[*3]", "remote", "manual"]
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*5]", "remote", "manual"]
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*6]", "remote", "manual"]
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[**8]", "remote", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
@@ -46,4 +53,6 @@ extensions:
- ["", "", 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"]
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
# winhttp.h
- ["", "", False, "WinHttpCrackUrl", "", "", "Argument[*0]", "Argument[*3]", "taint", "manual"]

View File

@@ -0,0 +1,41 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: sourceModel
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
- ["Azure::Core::Http", "RawResponse", True, "GetHeaders", "", "", "ReturnValue[*]", "remote", "manual"]
- ["Azure::Core::Http", "RawResponse", True, "GetBody", "", "", "ReturnValue[*]", "remote", "manual"]
- ["Azure::Core::Http", "RawResponse", True, "ExtractBodyStream", "", "", "ReturnValue[*]", "remote", "manual"]
- ["Azure::Core::Http", "Request", True, "GetHeaders", "", "", "ReturnValue", "remote", "manual"]
- ["Azure::Core::Http", "Request", True, "GetHeader", "", "", "ReturnValue", "remote", "manual"]
- ["Azure::Core::Http", "Request", True, "GetBodyStream", "", "", "ReturnValue[*]", "remote", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["Azure::Core", "Url", True, "Url", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["Azure::Core", "Url", True, "SetScheme", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["Azure::Core", "Url", True, "SetHost", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["Azure::Core", "Url", True, "SetPort", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
- ["Azure::Core", "Url", True, "SetPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["Azure::Core", "Url", True, "SetQueryParameters", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
- ["Azure::Core", "Url", True, "AppendPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["Azure::Core", "Url", True, "AppendQueryParameter", "", "", "Argument[*1]", "Argument[-1]", "taint", "manual"]
- ["Azure::Core", "Url", True, "GetHost", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
- ["Azure::Core", "Url", True, "GetPath", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
- ["Azure::Core", "Url", True, "GetPort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
- ["Azure::Core", "Url", True, "GetQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
- ["Azure::Core", "Url", True, "GetScheme", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
- ["Azure::Core", "Url", True, "GetRelativeUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
- ["Azure::Core", "Url", True, "GetAbsoluteUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
- ["Azure::Core", "Url", True, "Decode", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
- ["Azure::Core", "Url", True, "Encode", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
- ["Azure::Core::IO", "BodyStream", True, "Read", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
- ["Azure::Core::IO", "BodyStream", True, "ReadToCount", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
- ["Azure::Core::IO", "BodyStream", True, "ReadToEnd", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"]
- ["Azure", "Nullable", True, "Nullable", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
- ["Azure", "Nullable", True, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
- ["Azure", "Nullable", True, "Value", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
- ["Azure", "Nullable", True, "operator->", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
- ["Azure", "Nullable", True, "operator*", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 7.0.0
version: 7.1.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -192,6 +192,15 @@ class Element extends ElementBase {
*/
predicate isAffectedByMacro() { affectedByMacro(this) }
/**
* INTERNAL: Do not use.
*
* Holds if this element is affected by the expansion of `mi`.
*/
predicate isAffectedByMacro(MacroInvocation mi) {
affectedbymacroexpansion(underlyingElement(this), unresolveElement(mi))
}
private Element getEnclosingElementPref() {
enclosingfunction(underlyingElement(this), unresolveElement(result)) or
result.(Function) = stmtEnclosingElement(this) or

View File

@@ -239,6 +239,9 @@ class MacroInvocation extends MacroAccess {
macro_argument_unexpanded(underlyingElement(this), i, result)
}
/** Gets the number of arguments for this macro invocation. */
int getNumberOfArguments() { result = count(int i | exists(this.getUnexpandedArgument(i)) | i) }
/**
* Gets the `i`th _expanded_ argument of this macro invocation, where the
* first argument has `i = 0`. The result has been expanded for macros _and_

View File

@@ -328,3 +328,27 @@ class PreprocessorPragma extends PreprocessorDirective, @ppd_pragma {
class PreprocessorLine extends PreprocessorDirective, @ppd_line {
override string toString() { result = "#line " + this.getHead() }
}
/**
* A C23 or C++26 `#embed` preprocessor directive. For example, the following code
* contains one `Embed` directive:
* ```cpp
* char arr[] = {
* #embed "bin"
* };
* ```
*/
class Embed extends PreprocessorDirective, @ppd_embed {
override string toString() { result = "#embed " + this.getIncludeText() }
/**
* Gets the token which occurs after `#embed`, for example `"filename"`
* or `<filename>`.
*/
string getIncludeText() { result = this.getHead() }
/**
* Gets the file directly embedded by this `#embed`.
*/
File getEmbeddedFile() { embeds(underlyingElement(this), unresolveElement(result)) }
}

View File

@@ -62,11 +62,13 @@ private Class getRootType(FieldAccess fa) {
* 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()
)
result =
unique(Type t |
t = v.getUnspecifiedType() and
not t instanceof ReferenceType
|
t.getSize()
)
}
/**
@@ -79,30 +81,32 @@ private int getSize(VariableAccess va) {
not v instanceof Field and
result = getVariableSize(v)
or
exists(Class c, int trueSize |
// Otherwise, we find the "outermost" object and compute the size
// as the difference between the size of the type of the "outermost
// object" and the offset of the field relative to that type.
// For example, consider the following structs:
// ```
// struct S {
// uint32_t x;
// uint32_t y;
// };
// struct S2 {
// S s;
// uint32_t z;
// };
// ```
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
// is the size of the base object type (i.e., `S2`) minutes the offset
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
// 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) + getVariableSize(f)) and
result = trueSize - v.(Field).getOffsetInClass(c)
)
result =
unique(Class c, int trueSize |
// Otherwise, we find the "outermost" object and compute the size
// as the difference between the size of the type of the "outermost
// object" and the offset of the field relative to that type.
// For example, consider the following structs:
// ```
// struct S {
// uint32_t x;
// uint32_t y;
// };
// struct S2 {
// S s;
// uint32_t z;
// };
// ```
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
// is the size of the base object type (i.e., `S2`) minus the offset
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
// 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) + getVariableSize(f))
|
trueSize - v.(Field).getOffsetInClass(c)
)
)
}
@@ -116,12 +120,8 @@ private int isSource(Expr bufferExpr, Element why) {
exists(Variable bufferVar | bufferVar = bufferExpr.(VariableAccess).getTarget() |
// buffer is a fixed size array
exists(bufferVar.getUnspecifiedType().(ArrayType).getSize()) and
result =
unique(int size | // more generous than .getSize() itself, when the array is a class field or similar.
size = getSize(bufferExpr)
|
size
) and
// more generous than .getSize() itself, when the array is a class field or similar.
result = getSize(bufferExpr) and
why = bufferVar and
not memberMayBeVarSize(_, bufferVar) and
not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild*() = bufferExpr) and

View File

@@ -8,7 +8,8 @@ import semmle.code.cpp.ir.IR
private import codeql.util.Void
private import codeql.controlflow.Guards as SharedGuards
private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr as TE
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedFunction as TF
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
private class BasicBlock = IRCfg::BasicBlock;
@@ -683,24 +684,26 @@ final class GuardCondition = GuardConditionImpl;
*/
private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl instanceof Cpp::BinaryLogicalOperation
{
GuardConditionImpl l;
GuardConditionImpl r;
GuardConditionFromBinaryLogicalOperator() {
super.getLeftOperand() = l and
super.getRightOperand() = r
}
override predicate valueControls(Cpp::BasicBlock controlled, GuardValue v) {
exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs |
this = binop and
lhs = binop.getLeftOperand() and
rhs = binop.getRightOperand() and
lhs.valueControls(controlled, v) and
rhs.valueControls(controlled, v)
)
// `l || r` does not control `r` even though `l` does.
not r.(Cpp::Expr).getBasicBlock() = controlled and
l.valueControls(controlled, v)
or
r.valueControls(controlled, v)
}
override predicate valueControlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v) {
exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs |
this = binop and
lhs = binop.getLeftOperand() and
rhs = binop.getRightOperand() and
lhs.valueControlsEdge(pred, succ, v) and
rhs.valueControlsEdge(pred, succ, v)
)
l.valueControlsEdge(pred, succ, v)
or
r.valueControlsEdge(pred, succ, v)
}
pragma[nomagic]
@@ -1026,7 +1029,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
private predicate excludeAsControlledInstruction(Instruction instr) {
// Exclude the temporaries generated by a ternary expression.
exists(TranslatedConditionalExpr tce |
exists(TE::TranslatedConditionalExpr tce |
instr = tce.getInstruction(ConditionValueFalseStoreTag())
or
instr = tce.getInstruction(ConditionValueTrueStoreTag())
@@ -1038,6 +1041,14 @@ private predicate excludeAsControlledInstruction(Instruction instr) {
or
// Exclude unreached instructions, as their AST is the whole function and not a block.
instr instanceof UnreachedInstruction
or
// Exclude instructions generated by a translated function as they map to the function itself
// and the function is considered the last basic block of a function body.
any(TF::TranslatedFunction tf).getInstruction(_) = instr
or
// `ChiInstruction`s generated by instructions in the above case don't come from `getInstruction` (since they are generated by AliasedSSA)
// so we need to special case them.
excludeAsControlledInstruction(instr.(ChiInstruction).getPartial())
}
/**

View File

@@ -95,6 +95,7 @@
import cpp
private import new.DataFlow
private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as Private
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import internal.FlowSummaryImpl
@@ -367,6 +368,8 @@ private predicate elementSpec(
) {
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
barrierModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
barrierGuardModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
}
@@ -1028,6 +1031,84 @@ private module Cached {
isSinkNode(n, kind, model) and n.asNode() = node
)
}
private newtype TKindModelPair =
TMkPair(string kind, string model) { isBarrierGuardNode(_, _, kind, model) }
private GuardValue convertAcceptingValue(Public::AcceptingValue av) {
av.isTrue() and result.asBooleanValue() = true
or
av.isFalse() and result.asBooleanValue() = false
or
// NOTE: The below cases don't contribute anything currently since the
// callers immediately use `.asBooleanValue()` to convert the `GuardValue`
// to a boolean. Once we're willing to accept the breaking change of
// converting the barrier guard API to use `GuardValue`s instead `Boolean`s
// we can remove this restriction.
av.isNoException() and result.getDualValue().isThrowsException()
or
av.isZero() and result.asIntValue() = 0
or
av.isNotZero() and result.getDualValue().asIntValue() = 0
or
av.isNull() and result.isNullValue()
or
av.isNotNull() and result.isNonNullValue()
}
private predicate barrierGuardChecks(IRGuardCondition g, Expr e, boolean gv, TKindModelPair kmp) {
exists(
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingvalue,
string kind, string model
|
isBarrierGuardNode(n, acceptingvalue, kind, model) and
n.asNode().asExpr() = e and
kmp = TMkPair(kind, model) and
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
n.asNode().(Private::ArgumentNode).getCall().asCallInstruction() = g
)
}
private newtype TKindModelPairIntPair =
MkKindModelPairIntPair(TKindModelPair pair, int indirectionIndex) {
indirectionIndex > 0 and
Private::nodeHasInstruction(_, _, indirectionIndex) and
exists(pair)
}
private predicate indirectBarrierGuardChecks(
IRGuardCondition g, Expr e, boolean gv, TKindModelPairIntPair kmp
) {
exists(
SourceSinkInterpretationInput::InterpretNode interpretNode,
Public::AcceptingValue acceptingvalue, string kind, string model, int indirectionIndex,
Private::ArgumentNode arg
|
isBarrierGuardNode(interpretNode, acceptingvalue, kind, model) and
arg = interpretNode.asNode() and
arg.asIndirectExpr(indirectionIndex) = e and
kmp = MkKindModelPairIntPair(TMkPair(kind, model), indirectionIndex) and
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
arg.getCall().asCallInstruction() = g
)
}
/**
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
* model.
*/
cached
predicate barrierNode(DataFlow::Node node, string kind, string model) {
exists(SourceSinkInterpretationInput::InterpretNode n |
isBarrierNode(n, kind, model) and n.asNode() = node
)
or
DataFlow::ParameterizedBarrierGuard<TKindModelPair, barrierGuardChecks/4>::getABarrierNode(TMkPair(kind,
model)) = node
or
DataFlow::ParameterizedBarrierGuard<TKindModelPairIntPair, indirectBarrierGuardChecks/4>::getAnIndirectBarrierNode(MkKindModelPairIntPair(TMkPair(kind,
model), _)) = node
}
}
import Cached
@@ -1044,6 +1125,12 @@ predicate sourceNode(DataFlow::Node node, string kind) { sourceNode(node, kind,
*/
predicate sinkNode(DataFlow::Node node, string kind) { sinkNode(node, kind, _) }
/**
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
* model.
*/
predicate barrierNode(DataFlow::Node node, string kind) { barrierNode(node, kind, _) }
private predicate interpretSummary(
Function f, string input, string output, string kind, string provenance, string model
) {
@@ -1058,40 +1145,22 @@ private predicate interpretSummary(
// adapter class for converting Mad summaries to `SummarizedCallable`s
private class SummarizedCallableAdapter extends SummarizedCallable {
SummarizedCallableAdapter() { interpretSummary(this, _, _, _, _, _) }
string input_;
string output_;
string kind;
Provenance p_;
string model_;
private predicate relevantSummaryElementManual(
string input, string output, string kind, string model
) {
exists(Provenance provenance |
interpretSummary(this, input, output, kind, provenance, model) and
provenance.isManual()
)
}
private predicate relevantSummaryElementGenerated(
string input, string output, string kind, string model
) {
exists(Provenance provenance |
interpretSummary(this, input, output, kind, provenance, model) and
provenance.isGenerated()
)
}
SummarizedCallableAdapter() { interpretSummary(this, input_, output_, kind, p_, model_) }
override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
string input, string output, boolean preservesValue, Provenance p, boolean isExact, string model
) {
exists(string kind |
this.relevantSummaryElementManual(input, output, kind, model)
or
not this.relevantSummaryElementManual(_, _, _, _) and
this.relevantSummaryElementGenerated(input, output, kind, model)
|
if kind = "value" then preservesValue = true else preservesValue = false
)
}
override predicate hasProvenance(Provenance provenance) {
interpretSummary(this, _, _, _, provenance, _)
input = input_ and
output = output_ and
(if kind = "value" then preservesValue = true else preservesValue = false) and
p = p_ and
isExact = true and
model = model_
}
}

View File

@@ -20,6 +20,8 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
class SinkBase = Void;
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getBlock()) }
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
ReturnKind getStandardReturnValueKind() { result = getReturnValueKind("") }
@@ -149,16 +151,27 @@ module SourceSinkInterpretationInput implements
}
predicate barrierElement(
Element n, string output, string kind, Public::Provenance provenance, string model
Element e, string output, string kind, Public::Provenance provenance, string model
) {
none()
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
barrierModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
predicate barrierGuardElement(
Element n, string input, Public::AcceptingValue acceptingvalue, string kind,
Element e, string input, Public::AcceptingValue acceptingvalue, string kind,
Public::Provenance provenance, string model
) {
none()
exists(
string package, string type, boolean subtypes, string name, string signature, string ext
|
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingvalue, kind,
provenance, model) and
e = interpretElement(package, type, subtypes, name, signature, ext)
)
}
private newtype TInterpretNode =

View File

@@ -23,7 +23,7 @@ class Expr extends StmtParent, @expr {
predicate hasChild(Expr e, int n) { e = this.getChild(n) }
/** Gets the enclosing function of this expression, if any. */
Function getEnclosingFunction() { result = exprEnclosingElement(this) }
override Function getEnclosingFunction() { result = exprEnclosingElement(this) }
/** Gets the nearest enclosing set of curly braces around this expression in the source, if any. */
BlockStmt getEnclosingBlock() { result = this.getEnclosingStmt().getEnclosingBlock() }

View File

@@ -45,13 +45,13 @@ private string getSingleLocationFilePath(@element e) {
overlay[local]
private string getMultiLocationFilePath(@element e) {
exists(@location_default loc |
exists(@var_decl vd | var_decls(vd, e, _, _, loc))
var_decls(_, e, _, _, loc)
or
exists(@fun_decl fd | fun_decls(fd, e, _, _, loc))
fun_decls(_, e, _, _, loc)
or
exists(@type_decl td | type_decls(td, e, loc))
type_decls(_, e, loc)
or
exists(@namespace_decl nd | namespace_decls(nd, e, loc, _))
namespace_decls(_, e, loc, _)
|
result = getLocationFilePath(loc)
)
@@ -62,19 +62,29 @@ private string getMultiLocationFilePath(@element e) {
* overlay variant.
*/
overlay[local]
private predicate holdsInBase() { not isOverlay() }
private predicate isBase() { not isOverlay() }
/**
* Holds if `path` was extracted in the overlay database.
*/
overlay[local]
private predicate overlayHasFile(string path) {
isOverlay() and
files(_, path) and
path != ""
}
/**
* Discards an element from the base variant if:
* - It has a single location in a changed file, or
* - All of its locations are in changed files.
* - It has a single location in a file extracted in the overlay, or
* - All of its locations are in files extracted in the overlay.
*/
overlay[discard_entity]
private predicate discardElement(@element e) {
holdsInBase() and
isBase() and
(
overlayChangedFiles(getSingleLocationFilePath(e))
overlayHasFile(getSingleLocationFilePath(e))
or
forex(string path | path = getMultiLocationFilePath(e) | overlayChangedFiles(path))
forex(string path | path = getMultiLocationFilePath(e) | overlayHasFile(path))
)
}

View File

@@ -1144,7 +1144,7 @@ private newtype TDataFlowCall =
}
private predicate summarizedCallableIsManual(SummarizedCallable sc) {
sc.asSummarizedCallable().applyManualModel()
sc.asSummarizedCallable().hasManualModel()
}
/**

View File

@@ -312,6 +312,13 @@ class Node extends TIRDataFlowNode {
*/
Expr asDefinition() { result = this.asDefinition(_) }
private predicate isCertainStore() {
exists(SsaImpl::Definition def |
SsaImpl::defToNode(this, def, _) and
def.isCertain()
)
}
/**
* Gets the definition associated with this node, if any.
*
@@ -361,11 +368,10 @@ class Node extends TIRDataFlowNode {
* pointed to by `p`.
*/
Expr asDefinition(boolean uncertain) {
exists(StoreInstruction store, SsaImpl::Definition def |
exists(StoreInstruction store |
store = this.asInstruction() and
result = asDefinitionImpl(store) and
SsaImpl::defToNode(this, def, _) and
if def.isCertain() then uncertain = false else uncertain = true
if this.isCertainStore() then uncertain = false else uncertain = true
)
}
@@ -2417,6 +2423,19 @@ class ContentSet instanceof Content {
}
}
private signature class ParamSig;
private module WithParam<ParamSig P> {
/**
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
*
* The expression `e` is expected to be a syntactic part of the guard `g`.
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
* the argument `x`.
*/
signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch, P param);
}
/**
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
*
@@ -2438,7 +2457,7 @@ private predicate controls(IRGuardCondition g, Node n, boolean edge) {
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
* in data flow and taint tracking.
*/
module BarrierGuard<guardChecksSig/3 guardChecks> {
module ParameterizedBarrierGuard<ParamSig P, WithParam<P>::guardChecksSig/4 guardChecks> {
bindingset[value, n]
pragma[inline_late]
private predicate convertedExprHasValueNumber(ValueNumber value, Node n) {
@@ -2448,12 +2467,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
)
}
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch) {
guardChecks(g, n.asOperand().getDef().getConvertedResultExpression(), branch)
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch, P p) {
guardChecks(g, n.asOperand().getDef().getConvertedResultExpression(), branch, p)
}
/**
* Gets an expression node that is safely guarded by the given guard check.
* Gets an expression node that is safely guarded by the given guard check
* when the parameter is `p`.
*
* For example, given the following code:
* ```cpp
@@ -2484,19 +2504,27 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
*
* NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
*/
Node getABarrierNode() {
Node getABarrierNode(P p) {
exists(IRGuardCondition g, ValueNumber value, boolean edge |
convertedExprHasValueNumber(value, result) and
guardChecks(g,
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge, p) and
controls(g, result, edge)
)
or
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
result = SsaImpl::BarrierGuard<P, guardChecksNode/4>::getABarrierNode(p)
}
/**
* Gets an indirect expression node that is safely guarded by the given guard check.
* Gets an expression node that is safely guarded by the given guard check.
*
* See `getABarrierNode/1` for examples.
*/
Node getABarrierNode() { result = getABarrierNode(_) }
/**
* Gets an indirect expression node that is safely guarded by the given
* guard check with parameter `p`.
*
* For example, given the following code:
* ```cpp
@@ -2528,6 +2556,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
*
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
Node getAnIndirectBarrierNode(P p) { result = getAnIndirectBarrierNode(_, p) }
/**
* Gets an indirect expression node that is safely guarded by the given guard check.
*
* See `getAnIndirectBarrierNode/1` for examples.
*/
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
bindingset[value, n]
@@ -2542,10 +2577,10 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
}
private predicate guardChecksIndirectNode(
IRGuardCondition g, Node n, boolean branch, int indirectionIndex
IRGuardCondition g, Node n, boolean branch, int indirectionIndex, P p
) {
guardChecks(g, n.asIndirectOperand(indirectionIndex).getDef().getConvertedResultExpression(),
branch)
branch, p)
}
/**
@@ -2582,19 +2617,44 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
*
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
Node getAnIndirectBarrierNode(int indirectionIndex) {
Node getAnIndirectBarrierNode(int indirectionIndex, P p) {
exists(IRGuardCondition g, ValueNumber value, boolean edge |
indirectConvertedExprHasValueNumber(indirectionIndex, value, result) and
guardChecks(g,
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge, p) and
controls(g, result, edge)
)
or
result =
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
SsaImpl::BarrierGuardWithIntParam<P, guardChecksIndirectNode/5>::getABarrierNode(indirectionIndex,
p)
}
}
/**
* Provides a set of barrier nodes for a guard that validates an expression.
*
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
* in data flow and taint tracking.
*/
module BarrierGuard<guardChecksSig/3 guardChecks> {
private predicate guardChecks(IRGuardCondition g, Expr e, boolean branch, Unit unit) {
guardChecks(g, e, branch) and
exists(unit)
}
import ParameterizedBarrierGuard<Unit, guardChecks/4>
}
private module InstrWithParam<ParamSig P> {
/**
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
*/
signature predicate instructionGuardChecksSig(
IRGuardCondition g, Instruction instr, boolean branch, P p
);
}
/**
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
*/
@@ -2606,7 +2666,9 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
* in data flow and taint tracking.
*/
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
module ParameterizedInstructionBarrierGuard<
ParamSig P, InstrWithParam<P>::instructionGuardChecksSig/4 instructionGuardChecks>
{
bindingset[value, n]
pragma[inline_late]
private predicate operandHasValueNumber(ValueNumber value, Node n) {
@@ -2616,21 +2678,27 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
)
}
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch) {
instructionGuardChecks(g, n.asOperand().getDef(), branch)
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch, P p) {
instructionGuardChecks(g, n.asOperand().getDef(), branch, p)
}
/** Gets a node that is safely guarded by the given guard check. */
Node getABarrierNode() {
/**
* Gets a node that is safely guarded by the given guard check with
* parameter `p`.
*/
Node getABarrierNode(P p) {
exists(IRGuardCondition g, ValueNumber value, boolean edge |
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge, p) and
operandHasValueNumber(value, result) and
controls(g, result, edge)
)
or
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
result = SsaImpl::BarrierGuard<P, guardChecksNode/4>::getABarrierNode(p)
}
/** Gets a node that is safely guarded by the given guard check. */
Node getABarrierNode() { result = getABarrierNode(_) }
bindingset[value, n]
pragma[inline_late]
private predicate indirectOperandHasValueNumber(ValueNumber value, int indirectionIndex, Node n) {
@@ -2641,25 +2709,52 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
}
private predicate guardChecksIndirectNode(
IRGuardCondition g, Node n, boolean branch, int indirectionIndex
IRGuardCondition g, Node n, boolean branch, int indirectionIndex, P p
) {
instructionGuardChecks(g, n.asIndirectOperand(indirectionIndex).getDef(), branch)
instructionGuardChecks(g, n.asIndirectOperand(indirectionIndex).getDef(), branch, p)
}
/**
* Gets an indirect node with indirection index `indirectionIndex` that is
* safely guarded by the given guard check.
* safely guarded by the given guard check with parameter `p`.
*/
Node getAnIndirectBarrierNode(int indirectionIndex) {
Node getAnIndirectBarrierNode(int indirectionIndex, P p) {
exists(IRGuardCondition g, ValueNumber value, boolean edge |
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge, p) and
indirectOperandHasValueNumber(value, indirectionIndex, result) and
controls(g, result, edge)
)
or
result =
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
SsaImpl::BarrierGuardWithIntParam<P, guardChecksIndirectNode/5>::getABarrierNode(indirectionIndex,
p)
}
/**
* Gets an indirect node that is safely guarded by the given guard check
* with parameter `p`.
*/
Node getAnIndirectBarrierNode(P p) { result = getAnIndirectBarrierNode(_, p) }
/** Gets an indirect node that is safely guarded by the given guard check. */
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
}
/**
* Provides a set of barrier nodes for a guard that validates an instruction.
*
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
* in data flow and taint tracking.
*/
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
private predicate instructionGuardChecks(
IRGuardCondition g, Instruction i, boolean branch, Unit unit
) {
instructionGuardChecks(g, i, branch) and
exists(unit)
}
import ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>
}
/**

View File

@@ -15,17 +15,79 @@ private import DataFlowPrivate
import SsaImplCommon
private module SourceVariables {
/**
* Holds if `store` is the `StoreInstruction` generated by a postfix
* increment or decrement operation `e`, and `postCrement` is the operand
* that represents the use of the evaluated value of `e`.
*/
private predicate isUseAfterPostfixCrement0(StoreInstruction store, Operand postCrement) {
exists(
BinaryInstruction binary, IRBlock b, int iPre, int iPost, int iStore, Operand preCrement,
Instruction left
|
binary instanceof AddInstruction
or
binary instanceof PointerAddInstruction
or
binary instanceof SubInstruction
or
binary instanceof PointerSubInstruction
|
store.getSourceValue() = binary and
left = binary.getLeft() and
strictcount(left.getAUse()) = 2 and
left.getAUse() = preCrement and
left.getAUse() = postCrement and
b.getInstruction(iPre) = preCrement.getUse() and
b.getInstruction(iPost) = postCrement.getUse() and
b.getInstruction(iStore) = store and
iPre < iStore and
iStore < iPost
)
}
/**
* Holds if `store` is the `StoreInstruction` generated by an postfix
* increment or decrement operation `e`, and `postCrement` is the fully
* converted operand that represents the use of the evaluated value of `e`.
*/
private predicate isUseAfterPostfixCrement(StoreInstruction store, Operand postCrement) {
isUseAfterPostfixCrement0(store, postCrement) and
conversionFlow(postCrement, _, false, _)
or
exists(Instruction instr, Operand postCrement0 |
isUseAfterPostfixCrement(store, postCrement0) and
conversionFlow(postCrement0, instr, false, _) and
instr = postCrement.getDef()
)
}
private predicate hasSavedPostfixCrementSourceVariable(
BaseSourceVariable base, StoreInstruction store, int ind
) {
exists(BaseSourceVariableInstruction inst, int ind0 |
isUseAfterPostfixCrement(store, _) and
inst.getBaseSourceVariable() = base and
isDef(_, _, store.getDestinationAddressOperand(), inst, ind0, 0) and
ind = [ind0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
)
}
cached
private newtype TSourceVariable =
TMkSourceVariable(BaseSourceVariable base, int ind) {
TNormalSourceVariable(BaseSourceVariable base, int ind) {
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
} or
TSavedPostfixCrementSourceVariable(StoreInstruction store, int ind) {
hasSavedPostfixCrementSourceVariable(_, store, ind)
}
class SourceVariable extends TSourceVariable {
abstract private class AbstractSourceVariable extends TSourceVariable {
BaseSourceVariable base;
int ind;
SourceVariable() { this = TMkSourceVariable(base, ind) }
bindingset[ind]
AbstractSourceVariable() { any() }
/** Gets the IR variable associated with this `SourceVariable`, if any. */
IRVariable getIRVariable() { result = base.(BaseIRVariable).getIRVariable() }
@@ -37,7 +99,7 @@ private module SourceVariables {
BaseSourceVariable getBaseVariable() { result = base }
/** Gets a textual representation of this element. */
string toString() { result = repeatStars(this.getIndirection()) + base.toString() }
abstract string toString();
/**
* Gets the number of loads performed on the base source variable
@@ -62,6 +124,53 @@ private module SourceVariables {
/** Gets the location of this variable. */
Location getLocation() { result = this.getBaseVariable().getLocation() }
}
final class SourceVariable = AbstractSourceVariable;
/**
* A regular source variable. Most source variables are instances of this
* class.
*/
class NormalSourceVariable extends AbstractSourceVariable, TNormalSourceVariable {
NormalSourceVariable() { this = TNormalSourceVariable(base, ind) }
final override string toString() {
result = repeatStars(this.getIndirection()) + base.toString()
}
}
/**
* Before a value is postfix incremented (or decremented) we "save" its
* current value so that the pre-incremented value can be returned to the
* enclosing expression. We use the source variables represented by this
* class to represent the "saved value".
*/
class SavedPostfixCrementSourceVariable extends AbstractSourceVariable,
TSavedPostfixCrementSourceVariable
{
StoreInstruction store;
SavedPostfixCrementSourceVariable() {
this = TSavedPostfixCrementSourceVariable(store, ind) and
hasSavedPostfixCrementSourceVariable(base, store, ind)
}
final override string toString() {
result = repeatStars(this.getIndirection()) + base.toString() + " [before crement]"
}
/**
* Gets the `StoreInstruction` that writes the incremented (or decremented)
* value.
*/
StoreInstruction getStoreInstruction() { result = store }
/**
* Gets the fully converted `Operand` that represents the use of the
* value before the increment.
*/
Operand getOperand() { isUseAfterPostfixCrement(store, result) }
}
}
import SourceVariables
@@ -109,17 +218,43 @@ private newtype TDefImpl =
TDirectDefImpl(Operand address, int indirectionIndex) {
isDef(_, _, address, _, _, indirectionIndex)
} or
TSavedPostfixCrementDefImpl(SavedPostfixCrementSourceVariable sv, int indirectionIndex) {
isDef(_, _, sv.getStoreInstruction().getDestinationAddressOperand(), _, sv.getIndirection(),
indirectionIndex)
} or
TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents the initial "definition" of a global variable when entering
// a function body.
isGlobalDefImpl(v, f, _, indirectionIndex)
}
pragma[nomagic]
private predicate hasOperandAndIndirection(
SavedPostfixCrementSourceVariable sv, Operand operand, int indirection
) {
sv.getOperand() = operand and
sv.getIndirection() = indirection
}
private predicate hasBeforePostCrementUseImpl(
SavedPostfixCrementSourceVariable sv, Operand operand, int indirectionIndex
) {
not isDef(true, _, operand, _, _, _) and
exists(int indirection |
hasOperandAndIndirection(sv, operand, indirection) and
isUse(_, operand, _, indirection, indirectionIndex)
)
}
cached
private newtype TUseImpl =
TDirectUseImpl(Operand operand, int indirectionIndex) {
isUse(_, operand, _, _, indirectionIndex) and
not isDef(true, _, operand, _, _, _)
not isDef(true, _, operand, _, _, _) and
not hasBeforePostCrementUseImpl(_, operand, indirectionIndex)
} or
TSavedPostfixCrementUseImpl(SavedPostfixCrementSourceVariable sv, int indirectionIndex) {
hasBeforePostCrementUseImpl(sv, _, indirectionIndex)
} or
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents a final "use" of a global variable to ensure that
@@ -223,19 +358,8 @@ abstract class DefImpl extends TDefImpl {
*/
abstract int getIndirection();
/**
* Gets the base source variable (i.e., the variable without
* any indirection) of this definition or use.
*/
abstract BaseSourceVariable getBaseSourceVariable();
/** Gets the variable that is defined or used. */
SourceVariable getSourceVariable() {
exists(BaseSourceVariable v, int indirection |
sourceVariableHasBaseAndIndex(result, v, indirection) and
defHasSourceVariable(this, v, indirection)
)
}
abstract SourceVariable getSourceVariable();
/**
* Holds if this definition is guaranteed to totally overwrite the
@@ -243,8 +367,8 @@ abstract class DefImpl extends TDefImpl {
*/
abstract predicate isCertain();
/** Gets the value written to the destination variable by this definition. */
abstract Node0Impl getValue();
/** Gets the value written to the destination variable by this definition, if any. */
Node0Impl getValue() { none() }
/** Gets the operand that represents the address of this definition, if any. */
Operand getAddressOperand() { none() }
@@ -293,19 +417,8 @@ abstract class UseImpl extends TUseImpl {
/** Gets the indirection index of this use. */
final int getIndirectionIndex() { result = indirectionIndex }
/**
* Gets the base source variable (i.e., the variable without
* any indirection) of this definition or use.
*/
abstract BaseSourceVariable getBaseSourceVariable();
/** Gets the variable that is defined or used. */
SourceVariable getSourceVariable() {
exists(BaseSourceVariable v, int indirection |
sourceVariableHasBaseAndIndex(result, v, indirection) and
useHasSourceVariable(this, v, indirection)
)
}
abstract SourceVariable getSourceVariable();
/**
* Holds if this use is guaranteed to read the
@@ -314,18 +427,6 @@ abstract class UseImpl extends TUseImpl {
abstract predicate isCertain();
}
pragma[noinline]
private predicate defHasSourceVariable(DefImpl def, BaseSourceVariable bv, int ind) {
bv = def.getBaseSourceVariable() and
ind = def.getIndirection()
}
pragma[noinline]
private predicate useHasSourceVariable(UseImpl use, BaseSourceVariable bv, int ind) {
bv = use.getBaseSourceVariable() and
ind = use.getIndirection()
}
pragma[noinline]
private predicate sourceVariableHasBaseAndIndex(SourceVariable v, BaseSourceVariable bv, int ind) {
v.getBaseVariable() = bv and
@@ -358,16 +459,12 @@ abstract private class DefAddressImpl extends DefImpl, TDefAddressImpl {
final override predicate isCertain() { any() }
final override Node0Impl getValue() { none() }
override Cpp::Location getLocation() { result = v.getLocation() }
final override SourceVariable getSourceVariable() {
final override NormalSourceVariable getSourceVariable() {
result.getBaseVariable() = v and
result.getIndirection() = 0
}
final override BaseSourceVariable getBaseSourceVariable() { result = v }
}
private class DefVariableAddressImpl extends DefAddressImpl {
@@ -413,8 +510,17 @@ private class DirectDef extends DefImpl, TDirectDefImpl {
isDef(_, _, address, result, _, indirectionIndex)
}
override BaseSourceVariable getBaseSourceVariable() {
result = this.getBase().getBaseSourceVariable()
pragma[nomagic]
private predicate hasBaseSourceVariableAndIndirection(BaseSourceVariable v, int indirection) {
v = this.getBase().getBaseSourceVariable() and
indirection = this.getIndirection()
}
final override NormalSourceVariable getSourceVariable() {
exists(BaseSourceVariable v, int indirection |
sourceVariableHasBaseAndIndex(result, v, indirection) and
this.hasBaseSourceVariableAndIndirection(v, indirection)
)
}
override int getIndirection() { isDef(_, _, address, _, result, indirectionIndex) }
@@ -424,6 +530,32 @@ private class DirectDef extends DefImpl, TDirectDefImpl {
override predicate isCertain() { isDef(true, _, address, _, _, indirectionIndex) }
}
/**
* A definition that "saves" the value of a variable before it is incremented
* or decremented.
*/
private class SavedPostfixCrementDefImpl extends DefImpl, TSavedPostfixCrementDefImpl {
SavedPostfixCrementSourceVariable sv;
SavedPostfixCrementDefImpl() { this = TSavedPostfixCrementDefImpl(sv, indirectionIndex) }
override Cpp::Location getLocation() { result = sv.getStoreInstruction().getLocation() }
final override predicate hasIndexInBlock(IRBlock block, int index) {
sv.getStoreInstruction() = block.getInstruction(index)
}
override string toString() { result = "Def of " + this.getSourceVariable() }
override SourceVariable getSourceVariable() { result = sv }
override int getIndirection() { result = sv.getIndirection() }
override predicate isCertain() {
isDef(true, _, sv.getStoreInstruction().getDestinationAddressOperand(), _, _, indirectionIndex)
}
}
private class DirectUseImpl extends UseImpl, TDirectUseImpl {
Operand operand;
@@ -432,29 +564,22 @@ private class DirectUseImpl extends UseImpl, TDirectUseImpl {
override string toString() { result = "Use of " + this.getSourceVariable() }
final override predicate hasIndexInBlock(IRBlock block, int index) {
// See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
// predicate's implementation.
if this.getBase().getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
then
exists(Operand op, int indirection, Instruction base |
indirection = this.getIndirection() and
base = this.getBase() and
op =
min(Operand cand, int i |
isUse(_, cand, base, indirection, indirectionIndex) and
block.getInstruction(i) = cand.getUse()
|
cand order by i
) and
block.getInstruction(index) = op.getUse()
)
else operand.getUse() = block.getInstruction(index)
operand.getUse() = block.getInstruction(index)
}
private BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, indirectionIndex) }
override BaseSourceVariable getBaseSourceVariable() {
result = this.getBase().getBaseSourceVariable()
pragma[nomagic]
private predicate hasBaseSourceVariableAndIndirection(BaseSourceVariable bv, int indirection) {
this.getBase().getBaseSourceVariable() = bv and
this.getIndirection() = indirection
}
override NormalSourceVariable getSourceVariable() {
exists(BaseSourceVariable v, int indirection |
sourceVariableHasBaseAndIndex(result, v, indirection) and
this.hasBaseSourceVariableAndIndirection(v, indirection)
)
}
final Operand getOperand() { result = operand }
@@ -468,6 +593,34 @@ private class DirectUseImpl extends UseImpl, TDirectUseImpl {
override Node getNode() { nodeHasOperand(result, operand, indirectionIndex) }
}
/**
* The use of the original "saved" variable after the variable has been incremented
* or decremented.
*/
private class SavedPostfixCrementUseImpl extends UseImpl, TSavedPostfixCrementUseImpl {
SavedPostfixCrementSourceVariable sv;
SavedPostfixCrementUseImpl() { this = TSavedPostfixCrementUseImpl(sv, indirectionIndex) }
override string toString() { result = "Use of " + this.getSourceVariable() }
final override predicate hasIndexInBlock(IRBlock block, int index) {
this.getOperand().getUse() = block.getInstruction(index)
}
override SourceVariable getSourceVariable() { result = sv }
final Operand getOperand() { result = sv.getOperand() }
final override Cpp::Location getLocation() { result = this.getOperand().getLocation() }
override int getIndirection() { result = sv.getIndirection() }
override predicate isCertain() { isUse(true, this.getOperand(), _, _, indirectionIndex) }
override Node getNode() { nodeHasOperand(result, this.getOperand(), indirectionIndex) }
}
pragma[nomagic]
private predicate finalParameterNodeHasParameterAndIndex(
FinalParameterNode n, Parameter p, int indirectionIndex
@@ -532,7 +685,18 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
result instanceof UnknownLocation
}
override BaseIRVariable getBaseSourceVariable() { result.getIRVariable().getAst() = p }
pragma[nomagic]
private predicate hasBaseSourceVariableAndIndirection(BaseIRVariable v, int indirection) {
v.getIRVariable().getAst() = p and
indirection = this.getIndirection()
}
override NormalSourceVariable getSourceVariable() {
exists(BaseIRVariable v, int indirection |
sourceVariableHasBaseAndIndex(result, v, indirection) and
this.hasBaseSourceVariableAndIndirection(v, indirection)
)
}
}
/**
@@ -612,8 +776,17 @@ class GlobalUse extends UseImpl, TGlobalUse {
hasReturnPosition(f, block, index)
}
override BaseSourceVariable getBaseSourceVariable() {
baseSourceVariableIsGlobal(result, global, f)
pragma[nomagic]
private predicate hasBaseSourceVariableAndIndirection(BaseIRVariable v, int indirection) {
baseSourceVariableIsGlobal(v, global, f) and
indirection = this.getIndirection()
}
override NormalSourceVariable getSourceVariable() {
exists(BaseIRVariable v, int indirection |
sourceVariableHasBaseAndIndex(result, v, indirection) and
this.hasBaseSourceVariableAndIndirection(v, indirection)
)
}
final override Cpp::Location getLocation() { result = f.getLocation() }
@@ -658,15 +831,15 @@ class GlobalDefImpl extends DefImpl, TGlobalDefImpl {
)
}
/** Gets the global variable associated with this definition. */
override BaseSourceVariable getBaseSourceVariable() {
baseSourceVariableIsGlobal(result, global, f)
final override NormalSourceVariable getSourceVariable() {
exists(BaseSourceVariable v |
sourceVariableHasBaseAndIndex(result, v, indirectionIndex) and
baseSourceVariableIsGlobal(v, global, f)
)
}
override int getIndirection() { result = indirectionIndex }
override Node0Impl getValue() { none() }
override predicate isCertain() { any() }
/**
@@ -704,9 +877,15 @@ predicate defToNode(Node node, Definition def, SourceVariable sv) {
}
private predicate defToNode(Node node, Definition def) {
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
or
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
// Only definitions of `NormalSourceVariable` need to be converted into
// dataflow nodes. The other case, `SavedPostfixCrementSourceVariable`,
// are internal definitions that don't have a dataflow node representation.
def.getSourceVariable() instanceof NormalSourceVariable and
(
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
or
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
)
or
node.(InitialGlobalValue).getGlobalDef() = def
}
@@ -940,6 +1119,16 @@ module SsaCached {
SsaImpl::phiHasInputFromBlock(phi, inp, bb)
}
cached
predicate uncertainWriteDefinitionInput(Definition uncertain, Definition inp) {
SsaImpl::uncertainWriteDefinitionInput(uncertain, inp)
}
cached
predicate ssaDefReachesEndOfBlock(IRBlock bb, Definition def) {
SsaImpl::ssaDefReachesEndOfBlock(bb, def, _)
}
predicate variableRead = SsaInput::variableRead/4;
predicate variableWrite = SsaInput::variableWrite/4;
@@ -1035,13 +1224,23 @@ class SynthNode extends DataFlowIntegrationImpl::SsaNode {
SynthNode() { not this.asDefinition() instanceof SsaImpl::WriteDefinition }
}
signature predicate guardChecksNodeSig(IRGuards::IRGuardCondition g, Node e, boolean branch);
private signature class ParamSig;
signature predicate guardChecksNodeSig(
IRGuards::IRGuardCondition g, Node e, boolean branch, int indirectionIndex
);
private module ParamIntPair<ParamSig P> {
newtype TPair = MkPair(P p, int indirectionIndex) { nodeHasInstruction(_, _, indirectionIndex) }
}
module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
private module WithParam<ParamSig P> {
signature predicate guardChecksNodeSig(IRGuards::IRGuardCondition g, Node e, boolean gv, P param);
}
private module IntWithParam<ParamSig P> {
signature predicate guardChecksNodeSig(
IRGuards::IRGuardCondition g, Node e, boolean gv, int indirectionIndex, P param
);
}
module BarrierGuardWithIntParam<ParamSig P, IntWithParam<P>::guardChecksNodeSig/5 guardChecksNode> {
private predicate ssaDefReachesCertainUse(Definition def, UseImpl use) {
exists(SourceVariable v, IRBlock bb, int i |
use.hasIndexInBlock(bb, i, v) and
@@ -1052,21 +1251,23 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
private predicate guardChecksInstr(
IRGuards::Guards_v1::Guard g, IRGuards::GuardsInput::Expr instr, IRGuards::GuardValue gv,
int indirectionIndex
ParamIntPair<P>::TPair pair
) {
exists(Node node |
exists(Node node, int indirectionIndex, P p |
pair = ParamIntPair<P>::MkPair(p, indirectionIndex) and
nodeHasInstruction(node, instr, indirectionIndex) and
guardChecksNode(g, node, gv.asBooleanValue(), indirectionIndex)
guardChecksNode(g, node, gv.asBooleanValue(), indirectionIndex, p)
)
}
private predicate guardChecksWithWrappers(
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, IRGuards::GuardValue val,
int indirectionIndex
ParamIntPair<P>::MkPair pair
) {
exists(Instruction e |
IRGuards::Guards_v1::ParameterizedValidationWrapper<int, guardChecksInstr/4>::guardChecks(g,
e, val, indirectionIndex)
exists(Instruction e, int indirectionIndex |
IRGuards::Guards_v1::ParameterizedValidationWrapper<ParamIntPair<P>::TPair, guardChecksInstr/4>::guardChecks(g,
e, val, pair) and
pair = ParamIntPair<P>::MkPair(_, indirectionIndex)
|
indirectionIndex = 0 and
def.(Definition).getAUse().getDef() = e
@@ -1075,18 +1276,19 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
)
}
Node getABarrierNode(int indirectionIndex) {
Node getABarrierNode(int indirectionIndex, P p) {
// Only get the SynthNodes from the shared implementation, as the ExprNodes cannot
// be matched on SourceVariable.
result.(SsaSynthNode).getSynthNode() =
DataFlowIntegrationImpl::BarrierGuardDefWithState<int, guardChecksWithWrappers/4>::getABarrierNode(indirectionIndex)
DataFlowIntegrationImpl::BarrierGuardDefWithState<ParamIntPair<P>::MkPair, guardChecksWithWrappers/4>::getABarrierNode(ParamIntPair<P>::MkPair(p,
indirectionIndex))
or
// Calculate the guarded UseImpls corresponding to ExprNodes directly.
exists(
DataFlowIntegrationInput::Guard g, IRGuards::GuardValue branch, Definition def, IRBlock bb
|
guardChecksWithWrappers(g, def, branch, indirectionIndex) and
exists(UseImpl use |
guardChecksWithWrappers(g, def, branch, ParamIntPair<P>::MkPair(p, indirectionIndex)) and
ssaDefReachesCertainUse(def, use) and
use.getBlock() = bb and
DataFlowIntegrationInput::guardControlsBlock(g, bb, branch) and
@@ -1096,15 +1298,16 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
}
}
module BarrierGuard<guardChecksNodeSig/3 guardChecksNode> {
module BarrierGuard<ParamSig P, WithParam<P>::guardChecksNodeSig/4 guardChecksNode> {
private predicate guardChecksNode(
IRGuards::IRGuardCondition g, Node e, boolean branch, int indirectionIndex
IRGuards::IRGuardCondition g, Node e, boolean gv, int indirectionIndex, P p
) {
guardChecksNode(g, e, branch) and indirectionIndex = 0
indirectionIndex = 0 and
guardChecksNode(g, e, gv, p)
}
Node getABarrierNode() {
result = BarrierGuardWithIntParam<guardChecksNode/4>::getABarrierNode(0)
Node getABarrierNode(P p) {
result = BarrierGuardWithIntParam<P, guardChecksNode/5>::getABarrierNode(0, p)
}
}
@@ -1159,9 +1362,17 @@ class Definition extends SsaImpl::Definition {
private Definition getAPhiInputOrPriorDefinition() {
result = this.(PhiNode).getAnInput()
or
SsaImpl::uncertainWriteDefinitionInput(this, result)
uncertainWriteDefinitionInput(this, result)
}
/**
* Holds if this SSA definition is live at the end of basic block `bb`.
* That is, this definition reaches the end of basic block `bb`, at which
* point it is still live, without crossing another SSA definition of the
* same source variable.
*/
predicate isLiveAtEndOfBlock(IRBlock bb) { ssaDefReachesEndOfBlock(bb, this) }
/**
* Gets a definition that ultimately defines this SSA definition and is
* not itself a phi node.

View File

@@ -104,7 +104,11 @@ newtype TInstructionTag =
} or
SizeofVlaDimensionTag(int index) {
exists(VlaDeclStmt v | exists(v.getTransitiveVlaDimensionStmt(index)))
}
} or
AssertionVarAddressTag() or
AssertionVarLoadTag() or
AssertionOpTag() or
AssertionBranchTag()
class InstructionTag extends TInstructionTag {
final string toString() { result = getInstructionTagId(this) }
@@ -296,4 +300,12 @@ string getInstructionTagId(TInstructionTag tag) {
tag = CoAwaitBranchTag() and result = "CoAwaitBranch"
or
tag = BoolToIntConversionTag() and result = "BoolToIntConversion"
or
tag = AssertionVarAddressTag() and result = "AssertionVarAddress"
or
tag = AssertionVarLoadTag() and result = "AssertionVarLoad"
or
tag = AssertionOpTag() and result = "AssertionOp"
or
tag = AssertionBranchTag() and result = "AssertionBranch"
}

View File

@@ -0,0 +1,387 @@
private import cpp
private import semmle.code.cpp.ir.internal.IRUtilities
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.CppType
private import semmle.code.cpp.ir.internal.TempVariableTag
private import InstructionTag
private import TranslatedElement
private import TranslatedStmt
private import TranslatedFunction
/**
* Holds if `s` is a statement that may be an expanded assertion in a
* release build.
*/
pragma[nomagic]
private predicate stmtCandidate(Stmt s) {
not s.isFromUninstantiatedTemplate(_) and
(
// The expansion of `__analysis_assume(x != 0);` when `__analysis_assume` is
// empty is the empty statement.
s instanceof EmptyStmt
or
// The expansion of `assert(x != 0)` when `assert` is `((void)0)` is a zero literal
// with a void type.
exists(Expr e |
e = s.(ExprStmt).getExpr() and
e.getValue() = "0" and
e.getActualType() instanceof VoidType
)
)
}
pragma[nomagic]
private predicate macroInvocationLocation(int startline, Function f, MacroInvocation mi) {
mi.getMacroName() = ["assert", "__analysis_assume"] and
mi.getNumberOfArguments() = 1 and
mi.getLocation().hasLocationInfo(_, startline, _, _, _) and
f.getEntryPoint().isAffectedByMacro(mi)
}
pragma[nomagic]
private predicate stmtParentLocation(int startline, Function f, StmtParent p) {
p.getEnclosingFunction() = f and
p.getLocation().hasLocationInfo(_, startline, _, _, _)
}
/**
* Holds if `mi` is a macro invocation with a name that is known
* to correspond to an assertion macro, and the macro invocation
* is the only thing on the line.
*/
pragma[nomagic]
private predicate assertion0(MacroInvocation mi, Stmt s, string arg) {
stmtCandidate(s) and
s =
unique(StmtParent p, int startline, Function f |
macroInvocationLocation(startline, f, mi) and
stmtParentLocation(startline, f, p) and
// Also do not count the elements from the expanded macro, i.e., when checking
// if `assert(x)` is the only thing on the line we do not count the
// generated `((void)0)` expression.
not p = mi.getAnExpandedElement()
|
p
) and
arg = mi.getUnexpandedArgument(0)
}
private Function getEnclosingFunctionForMacroInvocation(MacroInvocation mi) {
exists(Stmt s |
assertion0(mi, s, _) and
result = s.getEnclosingFunction()
)
}
/**
* Holds if `arg` has two components and the `i`'th component of the string
* `arg` is `s`, and the components are separated by an operation with
* opcode `opcode`.
*/
bindingset[arg]
pragma[inline_late]
private predicate parseArgument(string arg, string s, int i, Opcode opcode) {
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?<=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareLE
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?>=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareGE
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?<\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareLT
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?>\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareGT
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?!=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareNE
or
s =
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?==\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
i + 1) and
opcode instanceof Opcode::CompareEQ
}
private Element getAChildScope(Element scope) { result.getParentScope() = scope }
private predicate hasAVariable(MacroInvocation mi, Stmt s, Element scope) {
assertion0(mi, s, _) and
s.getParent() = scope
or
hasAVariable(mi, s, getAChildScope(scope))
}
private LocalScopeVariable getVariable(MacroInvocation mi, int i) {
exists(string operand, string arg, Stmt s |
assertion0(mi, s, arg) and
parseArgument(arg, operand, i, _) and
result =
unique(Variable v |
v.getLocation().getStartLine() < s.getLocation().getStartLine() and
hasAVariable(mi, s, v.getParentScope()) and
v.hasName(operand)
|
v
)
)
}
/**
* Holds if the `i`'th component of the macro invocation `mi` with opcode
* `opcode` is a reference to `var`.
*/
private predicate hasVarAccessMacroArgument(MacroInvocation mi, Variable var, int i, Opcode opcode) {
exists(string arg, string s, Function f |
arg = mi.getUnexpandedArgument(0) and
f = getEnclosingFunctionForMacroInvocation(mi) and
parseArgument(arg, s, i, opcode) and
var = getVariable(mi, i)
)
}
/**
* Holds if the `i`'th component of the macro invocation `mi` with opcode
* `opcode` is a constant with the value `k`.
*/
private predicate hasConstMacroArgument(MacroInvocation mi, int k, int i, Opcode opcode) {
exists(string arg, string s |
assertion0(mi, _, arg) and
s.toInt() = k and
parseArgument(arg, s, i, opcode)
)
}
predicate hasAssertionOperand(MacroInvocation mi, int i) {
hasVarAccessMacroArgument(mi, _, i, _)
or
hasConstMacroArgument(mi, _, i, _)
}
private predicate hasAssertionOpcode(MacroInvocation mi, Opcode opcode) {
hasVarAccessMacroArgument(mi, _, _, opcode)
or
hasConstMacroArgument(mi, _, _, opcode)
}
/**
* Holds if `mi` is a macro invocation that is an assertion that should be generated
* in the control-flow graph at `s`.
*/
predicate assertion(MacroInvocation mi, Stmt s) {
assertion0(mi, s, _) and
hasAssertionOperand(mi, 0) and
hasAssertionOperand(mi, 1)
}
/** The translation of an operand of an assertion. */
abstract private class TranslatedAssertionOperand extends TranslatedElement,
TTranslatedAssertionOperand
{
MacroInvocation mi;
int index;
TranslatedAssertionOperand() { this = TTranslatedAssertionOperand(mi, index) }
MacroInvocation getMacroInvocation() { result = mi }
/**
* Gets the statement that is being replaced by the assertion that uses this
* operand.
*/
Stmt getStmt() { assertion(mi, result) }
final override Locatable getAst() { result = this.getStmt() }
final override TranslatedElement getChild(int id) { none() }
final override Declaration getFunction() { result = this.getStmt().getEnclosingFunction() }
/** Gets the instruction which holds the result of this operand. */
abstract Instruction getResult();
final override string toString() { result = "Operand of assertion: " + mi }
/** Gets the index of this operand (i.e., `0` or `1`). */
final int getIndex() { result = index }
}
/** An operand of an assertion that is a variable access. */
class TranslatedAssertionVarAccess extends TranslatedAssertionOperand {
TranslatedAssertionVarAccess() { hasVarAccessMacroArgument(mi, _, index, _) }
Variable getVariable() { hasVarAccessMacroArgument(mi, result, index, _) }
final override IRUserVariable getInstructionVariable(InstructionTag tag) {
tag = AssertionVarAddressTag() and
result.getVariable() = this.getVariable()
}
final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(AssertionVarAddressTag()) and kind instanceof GotoEdge
}
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = AssertionVarAddressTag() and
kind instanceof GotoEdge and
result = this.getInstruction(AssertionVarLoadTag())
or
tag = AssertionVarLoadTag() and
result = getTranslatedAssertionMacroInvocation(mi).getChildSuccessor(this, kind)
}
final override Instruction getALastInstructionInternal() {
result = this.getInstruction(AssertionVarLoadTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
exists(Variable v | v = this.getVariable() |
opcode instanceof Opcode::VariableAddress and
tag = AssertionVarAddressTag() and
resultType = getTypeForGLValue(v.getType())
or
opcode instanceof Opcode::Load and
tag = AssertionVarLoadTag() and
resultType = getTypeForPRValue(v.getType())
)
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = AssertionVarLoadTag() and
operandTag instanceof AddressOperandTag and
result = this.getInstruction(AssertionVarAddressTag())
}
final override Instruction getResult() { result = this.getInstruction(AssertionVarLoadTag()) }
}
/** An operand of an assertion that is a constant access. */
private class TranslatedAssertionConst extends TranslatedAssertionOperand {
TranslatedAssertionConst() { hasConstMacroArgument(mi, _, index, _) }
int getConst() { hasConstMacroArgument(mi, result, index, _) }
final override string getInstructionConstantValue(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = this.getConst().toString()
}
final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
}
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = getTranslatedAssertionMacroInvocation(mi).getChildSuccessor(this, kind)
}
final override Instruction getALastInstructionInternal() {
result = this.getInstruction(OnlyInstructionTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
opcode instanceof Opcode::Constant and
tag = OnlyInstructionTag() and
resultType = getIntType()
}
final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
}
/**
* Gets the `TranslatedAssertionMacroInvocation` corresponding to the macro
* invocation `mi`.
*/
TranslatedAssertionMacroInvocation getTranslatedAssertionMacroInvocation(MacroInvocation mi) {
result.getMacroInvocation() = mi
}
/**
* A synthesized assertion which would have otherwise been invisible because the
* database represents a release build where assertions are disabled.
*/
private class TranslatedAssertionMacroInvocation extends TranslatedStmt {
MacroInvocation mi;
TranslatedAssertionMacroInvocation() { assertion(mi, stmt) }
final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getLeft().getFirstInstruction(kind)
}
TranslatedAssertionOperand getLeft() {
result.getMacroInvocation() = mi and
result.getIndex() = 0
}
TranslatedAssertionOperand getRight() {
result.getMacroInvocation() = mi and
result.getIndex() = 1
}
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = AssertionOpTag() and
kind instanceof GotoEdge and
result = this.getInstruction(AssertionBranchTag())
or
tag = AssertionBranchTag() and
kind instanceof TrueEdge and
result = this.getParent().getChildSuccessor(this, _)
}
final override TranslatedElement getChildInternal(int id) {
id = 0 and result = this.getLeft()
or
id = 1 and result = this.getRight()
}
final override Instruction getALastInstructionInternal() {
result = this.getInstruction(AssertionBranchTag())
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = AssertionOpTag() and
resultType = getBoolType() and
hasAssertionOpcode(mi, opcode)
or
tag = AssertionBranchTag() and
resultType = getVoidType() and
opcode instanceof Opcode::ConditionalBranch
}
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
child = this.getLeft() and
result = this.getRight().getFirstInstruction(kind)
or
child = this.getRight() and
kind instanceof GotoEdge and
result = this.getInstruction(AssertionOpTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = AssertionOpTag() and
(
operandTag instanceof LeftOperandTag and
result = this.getLeft().getResult()
or
operandTag instanceof RightOperandTag and
result = this.getRight().getResult()
)
or
tag = AssertionBranchTag() and
operandTag instanceof ConditionOperandTag and
result = this.getInstruction(AssertionOpTag())
}
MacroInvocation getMacroInvocation() { result = mi }
}

View File

@@ -12,6 +12,7 @@ private import TranslatedFunction
private import TranslatedStmt
private import TranslatedExpr
private import IRConstruction
private import TranslatedAssertion
private import semmle.code.cpp.models.interfaces.SideEffect
private import SideEffects
@@ -138,6 +139,14 @@ private predicate ignoreExprAndDescendants(Expr expr) {
// conditionally constructed (until we have a mechanism for calling these only when the
// temporary's constructor was run)
isConditionalTemporaryDestructorCall(expr)
or
// An assertion in a release build is often defined as `#define assert(x) ((void)0)`.
// We generate a synthetic assertion in release builds, and when we do that the
// expression `((void)0)` should not be translated.
exists(MacroInvocation mi |
assertion(mi, _) and
expr = mi.getExpr().getFullyConverted()
)
}
/**
@@ -909,7 +918,8 @@ newtype TTranslatedElement =
} or
// The side effect that initializes newly-allocated memory.
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) }
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) } or
TTranslatedAssertionOperand(MacroInvocation mi, int index) { hasAssertionOperand(mi, index) }
/**
* Gets the index of the first explicitly initialized element in `initList`

View File

@@ -10,6 +10,7 @@ private import TranslatedElement
private import TranslatedExpr
private import TranslatedFunction
private import TranslatedInitialization
private import TranslatedAssertion
TranslatedStmt getTranslatedStmt(Stmt stmt) { result.getAst() = stmt }
@@ -324,8 +325,16 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
class TranslatedEmptyStmt extends TranslatedStmt {
TranslatedEmptyStmt() {
stmt instanceof EmptyStmt or
stmt instanceof LabelStmt or
// An assertion macro invocation can expand to
// an empty statement in release builds. In that case
// we synthesize the check that would have occurred.
// This is handled by `TranslatedAssertion.qll` and so
// we exclude these statements here.
not assertion(_, stmt) and
stmt instanceof EmptyStmt
or
stmt instanceof LabelStmt
or
stmt instanceof SwitchCase
}
@@ -420,6 +429,15 @@ class TranslatedDeclStmt extends TranslatedStmt {
class TranslatedExprStmt extends TranslatedStmt {
override ExprStmt stmt;
TranslatedExprStmt() {
// An assertion macro invocation typically expand to the
// expression `((void)0)` in release builds. In that case
// we synthesize the check that would have occurred.
// This is handled by `TranslatedAssertion.qll` and so
// we exclude these statements here.
not assertion(_, stmt)
}
TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr().getFullyConverted()) }
override TranslatedElement getChildInternal(int id) { id = 0 and result = this.getExpr() }

View File

@@ -57,3 +57,4 @@ private import implementations.CAtlFile
private import implementations.CAtlFileMapping
private import implementations.CAtlTemporaryFile
private import implementations.CRegKey
private import implementations.WinHttp

View File

@@ -16,17 +16,3 @@ private class MySqlExecutionFunction extends SqlExecutionFunction {
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
}
/**
* The `mysql_real_escape_string` family of functions from the MySQL C API.
*/
private class MySqlBarrierFunction extends SqlBarrierFunction {
MySqlBarrierFunction() {
this.hasName(["mysql_real_escape_string", "mysql_real_escape_string_quote"])
}
override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(2) and
output.isParameterDeref(1)
}
}

View File

@@ -0,0 +1,50 @@
private import cpp
private import semmle.code.cpp.ir.dataflow.FlowSteps
private import semmle.code.cpp.dataflow.new.DataFlow
/** The `WINHTTP_HEADER_NAME` class from `winhttp.h`. */
class WinHttpHeaderName extends Class {
WinHttpHeaderName() { this.hasGlobalName("_WINHTTP_HEADER_NAME") }
}
/** The `WINHTTP_EXTENDED_HEADER` class from `winhttp.h`. */
class WinHttpExtendedHeader extends Class {
WinHttpExtendedHeader() { this.hasGlobalName("_WINHTTP_EXTENDED_HEADER") }
}
private class WinHttpHeaderNameInheritingContent extends TaintInheritingContent,
DataFlow::FieldContent
{
WinHttpHeaderNameInheritingContent() {
this.getIndirectionIndex() = 2 and
(
this.getAField().getDeclaringType() instanceof WinHttpHeaderName
or
// The extended header looks like:
// struct WINHTTP_EXTENDED_HEADER {
// union { [...] };
// union { [...] };
// };
// So the first declaring type is the anonymous unions, and the declaring
// type of those anonymous unions is the `WINHTTP_EXTENDED_HEADER` struct.
this.getAField().getDeclaringType().getDeclaringType() instanceof WinHttpExtendedHeader
)
}
}
/** The `URL_COMPONENTS` class from `winhttp.h`. */
class WinHttpUrlComponents extends Class {
WinHttpUrlComponents() { this.hasGlobalName("_WINHTTP_URL_COMPONENTS") }
}
private class WinHttpUrlComponentsInheritingContent extends TaintInheritingContent,
DataFlow::FieldContent
{
WinHttpUrlComponentsInheritingContent() {
exists(Field f | f = this.getField() and f.getDeclaringType() instanceof WinHttpUrlComponents |
if f.getType().getUnspecifiedType() instanceof PointerType
then this.getIndirectionIndex() = 2
else this.getIndirectionIndex() = 1
)
}
}

View File

@@ -20,7 +20,7 @@ class Stmt extends StmtParent, @stmt {
predicate hasChild(Element e, int n) { this.getChild(n) = e }
/** Gets the enclosing function of this statement, if any. */
Function getEnclosingFunction() { result = stmtEnclosingElement(this) }
override Function getEnclosingFunction() { result = stmtEnclosingElement(this) }
/**
* Gets the nearest enclosing block of this statement in the source, if any.
@@ -159,7 +159,10 @@ private class TStmtParent = @stmt or @expr;
*
* This is normally a statement, but may be a `StmtExpr`.
*/
class StmtParent extends ControlFlowNode, TStmtParent { }
class StmtParent extends ControlFlowNode, TStmtParent {
/** Gets the enclosing function of this element, if any. */
Function getEnclosingFunction() { none() }
}
/**
* A C/C++ 'expression' statement.

View File

@@ -2353,6 +2353,7 @@ case @preprocdirect.kind of
| 14 = @ppd_ms_import
| 15 = @ppd_elifdef
| 16 = @ppd_elifndef
| 17 = @ppd_embed
| 18 = @ppd_warning
;
@@ -2379,6 +2380,11 @@ includes(
int included: @file ref
);
embeds(
unique int id: @ppd_embed ref,
int included: @file ref
);
link_targets(
int id: @link_target,
int binary: @file ref
@@ -2389,6 +2395,8 @@ link_parent(
int link_target : @link_target ref
);
/*- Database metadata -*/
/**
* The CLI will automatically emit applicable tuples for this table,
* such as `databaseMetadata("isOverlay", "true")` when building an
@@ -2399,6 +2407,8 @@ databaseMetadata(
string value: string ref
);
/*- Overlay support -*/
/**
* The CLI will automatically emit tuples for each new/modified/deleted file
* when building an overlay database.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Sections for databaseMetadata and overlayChangedFiles
compatibility: full

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Support embed preprocessor directive
compatibility: partial

View File

@@ -1,3 +1,7 @@
## 1.5.10
No user-facing changes.
## 1.5.9
### Minor Analysis Improvements

View File

@@ -45,14 +45,15 @@ module SqlTaintedConfig implements DataFlow::ConfigSig {
predicate isBarrier(DataFlow::Node node) {
node.asExpr().getUnspecifiedType() instanceof IntegralType
}
predicate isBarrierIn(DataFlow::Node node) {
or
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
node.asIndirectArgument() = sql.getACallToThisFunction().getArgument(arg) and
input.isParameterDeref(arg) and
sql.barrierSqlArgument(input, _)
)
or
// barrier defined using models-as-data
barrierNode(node, "sql-injection")
}
predicate observeDiffInformedIncrementalMode() { any() }

View File

@@ -0,0 +1,3 @@
## 1.5.10
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.5.9
lastReleaseVersion: 1.5.10

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.5.9
version: 1.5.11-dev
groups:
- cpp
- queries

View File

@@ -310,7 +310,7 @@ private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputS
}
private predicate hasManualSummaryModel(Callable api) {
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.hasManualModel()) or
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
}

View File

@@ -384,7 +384,9 @@ astGuardsControl
| 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:7:126:28 | ... && ... | true | 131 | 131 |
| test.c:126:7:126:28 | ... && ... | true | 131 | 132 |
| test.c:126:7:126:28 | ... && ... | true | 134 | 123 |
| test.c:126:12:126:26 | call to test3_condition | true | 126 | 128 |
| test.c:126:12:126:26 | call to test3_condition | true | 131 | 132 |
| test.c:131:7:131:7 | b | true | 131 | 132 |
@@ -405,9 +407,7 @@ astGuardsControl
| test.c:181:9:181:9 | x | true | 181 | 182 |
| test.c:181:9:181:9 | x | true | 186 | 180 |
| 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 |
astGuardsEnsure
@@ -589,13 +589,9 @@ astGuardsEnsure
| test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | == | test.c:175:32:175:32 | 0 | 0 | 175 | 175 |
| test.c:175:13:175:32 | ... == ... | test.c:175:32:175:32 | 0 | != | test.c:175:13:175:15 | call to foo | 0 | 175 | 175 |
| test.c:175:13:175:32 | ... == ... | test.c:175:32:175:32 | 0 | == | test.c:175:13:175:15 | call to foo | 0 | 175 | 175 |
| 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 |
astGuardsEnsure_const
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | != | 0 | 7 | 9 |
@@ -793,13 +789,21 @@ astGuardsEnsure_const
| 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 | != | 0 | 131 | 131 |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 |
| 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:7:126:7 | 1 | == | 1 | 131 | 131 |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 |
| 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 | != | 0 | 131 | 131 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 132 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 134 | 123 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 131 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 132 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 134 | 123 |
| 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 | != | 0 | 131 | 132 |
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
@@ -846,17 +850,11 @@ astGuardsEnsure_const
| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | == | 1 | 186 | 180 |
| 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 |

View File

@@ -105,9 +105,13 @@
| 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 | ... && ... | not 0 | test.c:126:31:128:16 | { ... } |
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:3:131:7 | if (...) ... |
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:10:132:16 | { ... } |
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:134:1:123:10 | return ... |
| test.c:126:7:126:28 | ... && ... | true | test.c:126:31:128:16 | { ... } |
| test.c:126:7:126:28 | ... && ... | true | test.c:131:3:131:7 | if (...) ... |
| test.c:126:7:126:28 | ... && ... | true | test.c:131:10:132:16 | { ... } |
| test.c:126:7:126:28 | ... && ... | true | test.c:134:1:123:10 | return ... |
| test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:126:31:128:16 | { ... } |
| test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:131:10:132:16 | { ... } |
| test.c:126:12:126:26 | call to test3_condition | true | test.c:126:31:128:16 | { ... } |
@@ -162,17 +166,11 @@
| 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 | not null | test.cpp:19:5:19:14 | ExprStmt |
| test.cpp:18:8:18:10 | call to get | true | test.cpp:19:5:19:14 | ExprStmt |
| test.cpp:30:22:30:22 | x | -1 | test.cpp:30:6:30:16 | doSomething |
| test.cpp:30:22:30:22 | x | -1 | test.cpp:31:16:32:21 | { ... } |
| test.cpp:30:22:30:22 | x | not -1 | test.cpp:30:6:30:16 | doSomething |
| test.cpp:30:22:30:22 | x | not -1 | test.cpp:34:1:34:1 | return ... |
| test.cpp:31:7:31:7 | x | -1 | test.cpp:30:6:30:16 | doSomething |
| test.cpp:31:7:31:7 | x | -1 | test.cpp:31:16:32:21 | { ... } |
| test.cpp:31:7:31:7 | x | not -1 | test.cpp:30:6:30:16 | doSomething |
| test.cpp:31:7:31:7 | x | not -1 | test.cpp:34:1:34:1 | return ... |
| 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:60:31:60:31 | i | 0 | test.cpp:62:5:64:12 | case ...: |
@@ -408,19 +406,11 @@
| test.cpp:400:11:400:25 | call to testEnumWrapper | 2 | test.cpp:404:5:406:12 | case ...: |
| test.cpp:400:27:400:27 | b | false | test.cpp:404:5:406:12 | case ...: |
| test.cpp:400:27:400:27 | b | true | test.cpp:401:5:403:12 | case ...: |
| test.cpp:410:26:410:26 | o | not null | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:410:26:410:26 | o | not null | test.cpp:412:1:412:1 | return ... |
| test.cpp:410:26:410:26 | o | null | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:410:26:410:26 | o | null | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:7:411:8 | ! ... | false | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | false | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:7:411:8 | ! ... | true | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | true | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:8:411:8 | o | false | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | false | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:8:411:8 | o | not null | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | not null | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:8:411:8 | o | null | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | null | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:8:411:8 | o | true | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | true | test.cpp:412:1:412:1 | return ... |

View File

@@ -195,13 +195,9 @@ binary
| 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 | { ... } |
@@ -762,13 +758,21 @@ unary
| 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 | != | 0 | test.c:131:3:131:7 | if (...) ... |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:10:132:16 | { ... } |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:134:1:123:10 | return ... |
| 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:7:126:7 | 1 | == | 1 | test.c:131:3:131:7 | if (...) ... |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... |
| 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 | != | 0 | test.c:131:3:131:7 | if (...) ... |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:134:1:123:10 | return ... |
| 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:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:3:131:7 | if (...) ... |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:10:132:16 | { ... } |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:134:1:123:10 | return ... |
| 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 | != | 0 | test.c:131:10:132: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 | { ... } |
@@ -853,17 +857,11 @@ unary
| 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 | { ... } |
@@ -1401,35 +1399,19 @@ unary
| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | == | 0 | test.cpp:394:50:395:7 | { ... } |
| test.cpp:400:11:400:25 | call to testEnumWrapper | test.cpp:400:11:400:25 | call to testEnumWrapper | == | 1 | test.cpp:401:5:403:12 | case ...: |
| test.cpp:400:11:400:25 | call to testEnumWrapper | test.cpp:400:11:400:25 | call to testEnumWrapper | == | 2 | test.cpp:404:5:406:12 | case ...: |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:412:1:412:1 | return ... |
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:411:11:411:18 | ExprStmt |
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:412:1:412:1 | return ... |

View File

@@ -0,0 +1,18 @@
struct S {
int x;
};
void use(int);
void test() {
int y = 43; // $ asDefinition=43
use(y);
y = 44; // $ asDefinition="... = ..."
use(y);
int x = 43; // $ asDefinition=43
x = 44; // $ asDefinition="... = ..."
S s;
s.x = 42; // $ asDefinition="... = ..."
}

View File

@@ -0,0 +1,22 @@
import cpp
import utils.test.InlineExpectationsTest
import semmle.code.cpp.dataflow.new.DataFlow::DataFlow
bindingset[s]
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }
module AsDefinitionTest implements TestSig {
string getARelevantTag() { result = "asDefinition" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Node n, Expr e |
e = n.asDefinition() and
location = e.getLocation() and
element = n.toString() and
tag = "asDefinition" and
value = quote(e.toString())
)
}
}
import MakeTest<AsDefinitionTest>

View File

@@ -147,6 +147,29 @@ astFlow
| 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 |
| test.cpp:1258:11:1258:16 | call to source | test.cpp:1259:8:1259:10 | ... ++ |
| test.cpp:1262:7:1262:12 | call to source | test.cpp:1263:8:1263:10 | ... -- |
| test.cpp:1266:7:1266:12 | call to source | test.cpp:1267:8:1267:10 | ++ ... |
| test.cpp:1266:7:1266:12 | call to source | test.cpp:1268:8:1268:8 | x |
| test.cpp:1270:7:1270:12 | call to source | test.cpp:1271:8:1271:10 | -- ... |
| test.cpp:1270:7:1270:12 | call to source | test.cpp:1272:8:1272:8 | x |
| test.cpp:1274:7:1274:12 | call to source | test.cpp:1275:8:1275:14 | ... += ... |
| test.cpp:1274:7:1274:12 | call to source | test.cpp:1276:8:1276:8 | x |
| test.cpp:1278:7:1278:12 | call to source | test.cpp:1279:8:1279:14 | ... -= ... |
| test.cpp:1278:7:1278:12 | call to source | test.cpp:1280:8:1280:8 | x |
| test.cpp:1284:11:1284:16 | call to source | test.cpp:1285:8:1285:20 | ... ? ... : ... |
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1289:8:1289:20 | ... ++ |
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1290:8:1290:8 | x |
| test.cpp:1292:7:1292:12 | call to source | test.cpp:1294:8:1294:8 | x |
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1297:8:1297:18 | ... ? ... : ... |
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1298:8:1298:8 | x |
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1301:8:1301:18 | ... ? ... : ... |
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1302:8:1302:8 | x |
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1305:8:1305:18 | ... ? ... : ... |
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1306:8:1306:8 | x |
| test.cpp:1308:7:1308:12 | call to source | test.cpp:1309:14:1309:16 | ... ++ |
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1313:8:1313:24 | ... ? ... : ... |
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1314:8:1314: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 |
| true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x |
@@ -354,6 +377,19 @@ irFlow
| 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 | * ... |
| test.cpp:1258:11:1258:16 | call to source | test.cpp:1259:8:1259:10 | ... ++ |
| test.cpp:1262:7:1262:12 | call to source | test.cpp:1263:8:1263:10 | ... -- |
| test.cpp:1284:11:1284:16 | call to source | test.cpp:1285:8:1285:20 | ... ? ... : ... |
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1290:8:1290:8 | x |
| test.cpp:1292:7:1292:12 | call to source | test.cpp:1294:8:1294:8 | x |
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1297:8:1297:18 | ... ? ... : ... |
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1298:8:1298:8 | x |
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1301:8:1301:18 | ... ? ... : ... |
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1302:8:1302:8 | x |
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1306:8:1306:8 | x |
| test.cpp:1308:7:1308:12 | call to source | test.cpp:1309:8:1309:16 | ... ++ |
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1313:8:1313:24 | ... ? ... : ... |
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1314:8:1314:8 | x |
| 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 |

View File

@@ -1252,4 +1252,64 @@ namespace globals_without_explicit_def {
calls_set_array();
sink(*global_int_array); // $ ir MISSING: ast
}
}
void crement_test1() {
int x = source();
sink(x++); // $ ir ast
sink(x);
x = source();
sink(x--); // $ ir ast
sink(x);
x = source();
sink(++x); // $ SPURIOUS: ast
sink(x); // $ SPURIOUS: ast
x = source();
sink(--x); // $ SPURIOUS: ast
sink(x); // $ SPURIOUS: ast
x = source();
sink(x += 10); // $ SPURIOUS: ast
sink(x); // $ SPURIOUS: ast
x = source();
sink(x -= 10); // $ SPURIOUS: ast
sink(x); // $ SPURIOUS: ast
}
void crement_test2(bool b, int y) {
int x = source();
sink(b ? x++ : x--); // $ ir ast
sink(x);
x = source();
sink((b ? x : y)++); // $ ast MISSING: ir
sink(x); // $ ir ast
x = source();
sink(++(b ? x : y));
sink(x); // $ ir ast
x = source();
sink(b ? x++ : y); // $ ir ast
sink(x); // $ ir ast
x = source();
sink(b ? x : y++); // $ ir ast
sink(x); // $ ir ast
x = source();
sink(b ? ++x : y); // $ SPURIOUS: ast
sink(x); // $ ir ast
x = source();
sink((long)x++); // $ ir ast
sink(x);
x = source();
sink(b ? (long)x++ : 0); // $ ir ast
sink(x); // $ ir ast
}

View File

@@ -0,0 +1,297 @@
using uint16_t = unsigned short;
using int64_t = long long;
using size_t = unsigned long;
using uint8_t = unsigned char;
using int32_t = int;
using uint32_t = unsigned int;
namespace std
{
class string
{
public:
string();
string(const char *);
~string();
};
template <typename K, typename V>
class map
{
public:
map();
~map();
V& operator[](const K& key);
};
template <typename T>
class vector
{
public:
vector();
~vector();
T& operator[](size_t);
};
template<typename T>
class unique_ptr {
public:
unique_ptr();
~unique_ptr();
T* get();
};
}
namespace Azure
{
template <typename T>
class Nullable
{
public:
Nullable();
Nullable(const T);
Nullable(const Nullable &);
~Nullable();
Nullable (Nullable &&);
Nullable & operator= (const Nullable &);
bool HasValue() const;
const T & Value () const;
T& Value ();
const T * operator-> () const;
T * operator-> ();
const T & operator* () const;
T & operator* ();
};
namespace Core
{
class Url
{
public:
Url();
Url(const std::string &);
void AppendPath(const std::string &encodedPath);
void AppendQueryParameter(const std::string &encodedKey,
const std::string &encodedValue);
static std::string Url::Decode(const std::string &value);
static std::string Url::Encode(const std::string &value,
const std::string &doNotEncodeSymbols = "");
std::string Url::GetAbsoluteUrl() const;
const std::string &GetHost() const;
const std::string &GetPath() const;
uint16_t GetPort() const;
std::map<std::string, std::string> GetQueryParameters() const;
std::string Url::GetRelativeUrl() const;
const std::string &GetScheme() const;
void RemoveQueryParameter(const std::string &encodedKey);
void SetHost(const std::string &encodedHost);
void SetPath(const std::string &encodedPath);
void SetPort(uint16_t port);
void SetQueryParameters(std::map<std::string, std::string> queryParameters);
void SetScheme(const std::string &scheme);
};
class Context
{
public:
Context();
};
namespace IO
{
class BodyStream
{
public:
virtual ~BodyStream();
virtual int64_t Length() const = 0;
virtual void Rewind();
size_t Read(uint8_t *buffer, size_t count, Azure::Core::Context const &context = Azure::Core::Context());
size_t ReadToCount(uint8_t *buffer, size_t count, Azure::Core::Context const &context = Azure::Core::Context());
std::vector<uint8_t> ReadToEnd(Azure::Core::Context const &context = Azure::Core::Context());
};
}
enum class HttpStatusCode {
None = 0,
Continue = 100,
SwitchingProtocols = 101,
Processing = 102,
EarlyHints = 103,
OK = 200,
Created = 201,
Accepted = 202,
NonAuthoritativeInformation = 203,
NoContent = 204,
ResetContent = 205,
PartialContent = 206,
MultiStatus = 207,
AlreadyReported = 208,
IMUsed = 226,
MultipleChoices = 300,
MovedPermanently = 301,
Found = 302,
SeeOther = 303,
NotModified = 304,
UseProxy = 305,
TemporaryRedirect = 307,
PermanentRedirect = 308,
BadRequest = 400,
Unauthorized = 401,
PaymentRequired = 402,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
NotAcceptable = 406,
ProxyAuthenticationRequired = 407,
RequestTimeout = 408,
Conflict = 409,
Gone = 410,
LengthRequired = 411,
PreconditionFailed = 412,
PayloadTooLarge = 413,
URITooLong = 414,
UnsupportedMediaType = 415,
RangeNotSatisfiable = 416,
ExpectationFailed = 417,
MisdirectedRequest = 421,
UnprocessableEntity = 422,
Locked = 423,
FailedDependency = 424,
TooEarly = 425,
UpgradeRequired = 426,
PreconditionRequired = 428,
TooManyRequests = 429,
RequestHeaderFieldsTooLarge = 431,
UnavailableForLegalReasons = 451,
InternalServerError = 500,
NotImplemented = 501,
BadGateway = 502,
ServiceUnavailable = 503,
GatewayTimeout = 504,
HTTPVersionNotSupported = 505,
VariantAlsoNegotiates = 506,
InsufficientStorage = 507,
LoopDetected = 508,
NotExtended = 510,
NetworkAuthenticationRequired = 511
};
namespace Http
{
class HttpMethod
{
public:
HttpMethod(std::string value);
bool operator==(const HttpMethod &other) const;
bool operator!=(const HttpMethod &other) const;
const std::string &ToString() const;
};
extern const HttpMethod Get;
extern const HttpMethod Head;
extern const HttpMethod Post;
extern const HttpMethod Put;
extern const HttpMethod Delete;
extern const HttpMethod Patch;
extern const HttpMethod Options;
class Request
{
public:
explicit Request(HttpMethod httpMethod,
Url url);
explicit Request(HttpMethod httpMethod,
Url url,
bool shouldBufferResponse);
explicit Request(HttpMethod httpMethod,
Url url,
IO::BodyStream *bodyStream);
explicit Request(HttpMethod httpMethod,
Url url,
IO::BodyStream *bodyStream,
bool shouldBufferResponse);
std::map<std::string, std::string> GetHeaders () const;
Azure::Nullable<std::string> GetHeader(std::string const &name);
IO::BodyStream * GetBodyStream();
Azure::Core::IO::BodyStream const* GetBodyStream () const;
};
class RawResponse {
public:
RawResponse (int32_t majorVersion, int32_t minorVersion, HttpStatusCode statusCode, std::string const &reasonPhrase);
RawResponse (RawResponse const &response);
RawResponse (RawResponse &&response);
~RawResponse ();
void SetHeader (std::string const &name, std::string const &value);
void SetBodyStream (std::unique_ptr< Azure::Core::IO::BodyStream > stream);
void SetBody (std::vector< uint8_t > body);
uint32_t GetMajorVersion () const;
uint32_t GetMinorVersion () const;
HttpStatusCode GetStatusCode () const;
std::string const & GetReasonPhrase () const;
std::map<std::string, std::string>& GetHeaders () const;
std::unique_ptr<Azure::Core::IO::BodyStream> ExtractBodyStream ();
std::vector<uint8_t> & GetBody ();
std::vector<uint8_t> const& GetBody() const;
};
}
}
}
void sink(char);
void sink(std::string);
void sink(std::vector<uint8_t>);
void sink(Azure::Nullable<std::string>);
void test_BodyStream() {
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
Azure::Core::IO::BodyStream * resp = request.GetBodyStream();
{
unsigned char buffer[1024];
resp->Read(buffer, sizeof(buffer));
sink(*buffer); // $ ir
}
{
unsigned char buffer[1024];
resp->ReadToCount(buffer, sizeof(buffer));
sink(*buffer); // $ ir
}
{
std::vector<unsigned char> vec = resp->ReadToEnd();
sink(vec); // $ ir
}
}
void test_RawResponse(Azure::Core::Http::RawResponse& resp) {
{
std::map<std::string, std::string> body = resp.GetHeaders();
sink(body["Content-Type"]); // $ ir
}
{
std::vector<uint8_t> body = resp.GetBody();
sink(body); // $ ir
}
{
std::unique_ptr<Azure::Core::IO::BodyStream> bodyStream = resp.ExtractBodyStream();
sink(bodyStream.get()->ReadToEnd()); // $ ir
}
}
void test_GetHeader() {
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
{
auto headerValue = request.GetHeader("Content-Type").Value();
sink(headerValue); // $ ir
}
{
std::map<std::string, std::string> headers = request.GetHeaders();
std::string contentType = headers["Content-Type"];
sink(contentType); // $ ir
}
}

View File

@@ -14,45 +14,111 @@ models
| 13 | Source: ; ; false; NtReadFile; ; ; Argument[*5]; local; manual |
| 14 | Source: ; ; false; ReadFile; ; ; Argument[*1]; local; manual |
| 15 | Source: ; ; false; ReadFileEx; ; ; Argument[*1]; local; manual |
| 16 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
| 17 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
| 18 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
| 19 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
| 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; 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; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
| 33 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
| 34 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
| 35 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
| 36 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
| 37 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
| 16 | Source: ; ; false; WinHttpQueryHeaders; ; ; Argument[*3]; remote; manual |
| 17 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[**8]; remote; manual |
| 18 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*5]; remote; manual |
| 19 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*6]; remote; manual |
| 20 | Source: ; ; false; WinHttpReadData; ; ; Argument[*1]; remote; manual |
| 21 | Source: ; ; false; WinHttpReadDataEx; ; ; Argument[*1]; remote; manual |
| 22 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
| 23 | Source: Azure::Core::Http; RawResponse; true; ExtractBodyStream; ; ; ReturnValue[*]; remote; manual |
| 24 | Source: Azure::Core::Http; RawResponse; true; GetBody; ; ; ReturnValue[*]; remote; manual |
| 25 | Source: Azure::Core::Http; RawResponse; true; GetHeaders; ; ; ReturnValue[*]; remote; manual |
| 26 | Source: Azure::Core::Http; Request; true; GetBodyStream; ; ; ReturnValue[*]; remote; manual |
| 27 | Source: Azure::Core::Http; Request; true; GetHeader; ; ; ReturnValue; remote; manual |
| 28 | Source: Azure::Core::Http; Request; true; GetHeaders; ; ; ReturnValue; remote; manual |
| 29 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
| 30 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
| 31 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
| 32 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
| 33 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
| 34 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
| 35 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 36 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 37 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 38 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
| 39 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 40 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
| 41 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 42 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
| 43 | Summary: ; ; false; WinHttpCrackUrl; ; ; Argument[*0]; Argument[*3]; taint; manual |
| 44 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
| 45 | Summary: ; ; false; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
| 46 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
| 47 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
| 48 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
| 49 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
| 50 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
| 51 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
| 52 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
| 53 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
| 54 | 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:37 |
| 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:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:54 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:29 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:29 Sink:MaD:2 |
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:100:64:100:71 | *send_str | provenance | TaintFunction |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
| 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:37 |
| 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:35 |
| 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:34 |
| 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:36 |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:54 |
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:53 |
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:50 |
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:51 |
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:52 |
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:26 |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:50 |
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:51 |
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:52 |
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:273:62:273:64 | call to GetHeaders | provenance | Src:MaD:25 |
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:10:274:29 | call to operator[] | provenance | |
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:14:274:29 | call to operator[] | provenance | |
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:277:45:277:47 | call to GetBody | provenance | Src:MaD:24 |
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
| azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | |
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:23 |
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:52 |
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:53 |
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:27 |
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
| azure.cpp:290:10:290:20 | headerValue | azure.cpp:290:10:290:20 | headerValue | provenance | |
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:293:58:293:67 | call to GetHeaders | provenance | Src:MaD:28 |
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:294:38:294:53 | call to operator[] | provenance | TaintFunction |
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
| azure.cpp:295:10:295:20 | contentType | azure.cpp:295:10:295:20 | contentType | provenance | |
| 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:48 |
| 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:47 |
| 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:49 |
| 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 |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:22 |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:1 |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:17:24:17:24 | x | provenance | |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:21:27:21:27 | x | provenance | |
@@ -61,15 +127,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:35 |
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:48 |
| 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:34 |
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:47 |
| 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:36 |
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:49 |
| 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 | |
@@ -77,16 +143,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:33 |
| 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:46 |
| 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:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:22 |
| 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: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 param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
| 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:44 |
| 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:44 |
| 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:44 |
| 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 | |
@@ -95,7 +161,7 @@ edges
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
| test.cpp:88:22:88:22 | y | test.cpp:89:11:89:11 | y | provenance | Sink:MaD:1 |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:16 |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:22 |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:97:26:97:26 | x | provenance | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
@@ -104,28 +170,28 @@ edges
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:104:62:104:62 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:32 |
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:16 |
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:45 |
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:22 |
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:118:44:118:44 | *x | provenance | |
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | |
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:32 |
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:18 |
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:45 |
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:30 |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | |
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | |
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:30:8:30:15 | * ... | provenance | |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | provenance | |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:18 |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:30 |
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:4 |
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:36:10:36:13 | * ... | provenance | |
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:5 |
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | |
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | |
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:22 |
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:22 |
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:34 |
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:34 |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | |
@@ -173,11 +239,11 @@ edges
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:12 |
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | |
| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | provenance | |
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:21 |
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:33 |
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | |
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:19 |
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:31 |
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | |
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:20 |
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:32 |
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | |
| windows.cpp:403:26:403:36 | *lpParameter [x] | windows.cpp:405:10:405:25 | *lpParameter [x] | provenance | |
| windows.cpp:405:10:405:25 | *lpParameter [x] | windows.cpp:406:8:406:8 | *s [x] | provenance | |
@@ -196,17 +262,17 @@ 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:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:39 |
| 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:35 |
| 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:36 |
| 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:37 |
| 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] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:38 |
| 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:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:41 |
| 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:42 |
| 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:40 |
| 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 | |
@@ -218,37 +284,51 @@ edges
| 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:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:39 |
| 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:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:35 |
| 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:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:36 |
| 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:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:37 |
| 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:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:40 |
| 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:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:38 |
| 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:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:41 |
| 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 |
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:42 |
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:20 |
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:21 |
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | windows.cpp:661:10:661:16 | * ... | provenance | Src:MaD:16 |
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:18 |
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:19 |
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:17 |
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | provenance | MaD:43 |
| windows.cpp:728:5:728:28 | ... = ... | windows.cpp:729:35:729:35 | *x | provenance | |
| windows.cpp:728:12:728:28 | call to source | windows.cpp:728:5:728:28 | ... = ... | provenance | |
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | provenance | |
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:43 |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:731:10:731:36 | * ... | provenance | |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:733:10:733:35 | * ... | provenance | |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:735:10:735:37 | * ... | provenance | |
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 |
@@ -262,6 +342,59 @@ nodes
| asio_streams.cpp:100:64:100:71 | *send_str | semmle.label | *send_str |
| asio_streams.cpp:101:7:101:17 | send_buffer | semmle.label | send_buffer |
| asio_streams.cpp:103:29:103:39 | *send_buffer | semmle.label | *send_buffer |
| azure.cpp:62:10:62:14 | [summary param] this in Value | semmle.label | [summary param] this in Value |
| azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | semmle.label | [summary] to write: ReturnValue[*] in Value |
| azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | semmle.label | [summary param] *0 in Read [Return] |
| azure.cpp:113:16:113:19 | [summary param] this in Read | semmle.label | [summary param] this in Read |
| azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | semmle.label | [summary param] *0 in ReadToCount [Return] |
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | semmle.label | [summary param] this in ReadToCount |
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | semmle.label | [summary param] this in ReadToEnd |
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | semmle.label | [summary] to write: ReturnValue in ReadToEnd [element] |
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | semmle.label | [summary] to write: ReturnValue.Element in ReadToEnd |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
| azure.cpp:257:5:257:8 | *resp | semmle.label | *resp |
| azure.cpp:257:16:257:21 | Read output argument | semmle.label | Read output argument |
| azure.cpp:258:10:258:16 | * ... | semmle.label | * ... |
| azure.cpp:262:5:262:8 | *resp | semmle.label | *resp |
| azure.cpp:262:23:262:28 | ReadToCount output argument | semmle.label | ReadToCount output argument |
| azure.cpp:263:10:263:16 | * ... | semmle.label | * ... |
| azure.cpp:266:38:266:41 | *resp | semmle.label | *resp |
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
| azure.cpp:267:10:267:12 | vec | semmle.label | vec |
| azure.cpp:267:10:267:12 | vec [element] | semmle.label | vec [element] |
| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
| azure.cpp:274:10:274:29 | call to operator[] | semmle.label | call to operator[] |
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
| azure.cpp:278:10:278:13 | body | semmle.label | body |
| azure.cpp:278:10:278:13 | body | semmle.label | body |
| azure.cpp:278:10:278:13 | body | semmle.label | body |
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
| azure.cpp:282:10:282:38 | call to ReadToEnd | semmle.label | call to ReadToEnd |
| azure.cpp:282:21:282:23 | *call to get | semmle.label | *call to get |
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
| azure.cpp:289:24:289:56 | call to GetHeader | semmle.label | call to GetHeader |
| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
| azure.cpp:294:38:294:53 | call to operator[] | semmle.label | call to operator[] |
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | semmle.label | [summary param] 0 in ymlStepManual |
| test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | semmle.label | [summary] to write: ReturnValue in ymlStepManual |
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | semmle.label | [summary param] 0 in ymlStepGenerated |
@@ -482,8 +615,34 @@ nodes
| 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 |
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | semmle.label | WinHttpReadData output argument |
| windows.cpp:647:10:647:16 | * ... | semmle.label | * ... |
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | semmle.label | WinHttpReadDataEx output argument |
| windows.cpp:654:10:654:16 | * ... | semmle.label | * ... |
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | semmle.label | WinHttpQueryHeaders output argument |
| windows.cpp:661:10:661:16 | * ... | semmle.label | * ... |
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
| windows.cpp:671:10:671:16 | * ... | semmle.label | * ... |
| windows.cpp:673:10:673:29 | * ... | semmle.label | * ... |
| windows.cpp:675:10:675:27 | * ... | semmle.label | * ... |
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | semmle.label | [summary param] *0 in WinHttpCrackUrl |
| windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | semmle.label | [summary param] *3 in WinHttpCrackUrl [Return] |
| windows.cpp:728:5:728:28 | ... = ... | semmle.label | ... = ... |
| windows.cpp:728:12:728:28 | call to source | semmle.label | call to source |
| windows.cpp:729:35:729:35 | *x | semmle.label | *x |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | semmle.label | WinHttpCrackUrl output argument |
| windows.cpp:731:10:731:36 | * ... | semmle.label | * ... |
| windows.cpp:733:10:733:35 | * ... | semmle.label | * ... |
| windows.cpp:735:10:735:37 | * ... | semmle.label | * ... |
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 |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | azure.cpp:257:16:257:21 | Read output argument |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | azure.cpp:262:23:262:28 | ReadToCount output argument |
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] |
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | azure.cpp:289:63:289:65 | call to Value |
| 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 |
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated |
| 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 |
@@ -498,4 +657,5 @@ subpaths
| 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 |
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |
testFailures

View File

@@ -1,4 +1,10 @@
| asio_streams.cpp:87:34:87:44 | read_until output argument | remote |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | remote |
| azure.cpp:273:62:273:64 | call to GetHeaders | remote |
| azure.cpp:277:45:277:47 | call to GetBody | remote |
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | remote |
| azure.cpp:289:32:289:40 | call to GetHeader | remote |
| azure.cpp:293:58:293:67 | call to GetHeaders | remote |
| test.cpp:10:10:10:18 | call to ymlSource | local |
| test.cpp:56:8:56:16 | call to ymlSource | local |
| test.cpp:94:10:94:18 | call to ymlSource | local |
@@ -20,3 +26,9 @@
| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | local |
| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | local |
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | local |
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | remote |
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | remote |
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | remote |
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | remote |
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | remote |
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | remote |

View File

@@ -1,8 +1,12 @@
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer |
| azure.cpp:252:79:252:98 | call to string | azure.cpp:252:62:252:99 | call to Url |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument |
| azure.cpp:287:79:287:98 | call to string | azure.cpp:287:62:287:99 | call to Url |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value |
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual |
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated |
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
| test.cpp:28:35:28:35 | 0 | test.cpp:28:11:28:33 | call to ymlStepManual_with_body |
| test.cpp:32:38:32:38 | 0 | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
| test.cpp:35:38:35:38 | x | test.cpp:35:11:35:36 | call to ymlStepGenerated_with_body |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |

View File

@@ -5586,3 +5586,6 @@
| Unrecognized output specification "Field[***hEvent]" in summary model. |
| Unrecognized output specification "Parameter[***0]" in summary model. |
| Unrecognized output specification "Parameter[****0]" in summary model. |
| Unrecognized output specification "ReturnValue[*****]" in summary model. |
| Unrecognized output specification "ReturnValue[****]" in summary model. |
| Unrecognized output specification "ReturnValue[***]" in summary model. |

View File

@@ -573,4 +573,165 @@ void test_copy_and_move_memory() {
RtlMoveVolatileMemory(dest_buffer, &x, sizeof(x));
sink(dest_buffer[0]); // $ ir
}
}
using HINTERNET = void*;
using ULONGLONG = unsigned long long;
using UINT = unsigned int;
using PDWORD = DWORD*;
using PCSTR = const char*;
typedef union _WINHTTP_HEADER_NAME {
PCWSTR pwszName;
PCSTR pszName;
} WINHTTP_HEADER_NAME, *PWINHTTP_HEADER_NAME;
typedef struct _WINHTTP_EXTENDED_HEADER {
union {
PCWSTR pwszName;
PCSTR pszName;
};
union {
PCWSTR pwszValue;
PCSTR pszValue;
};
} WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER;
BOOL WinHttpReadData(
HINTERNET hRequest,
LPVOID lpBuffer,
DWORD dwNumberOfBytesToRead,
LPDWORD lpdwNumberOfBytesRead
);
DWORD WinHttpReadDataEx(
HINTERNET hRequest,
LPVOID lpBuffer,
DWORD dwNumberOfBytesToRead,
LPDWORD lpdwNumberOfBytesRead,
ULONGLONG ullFlags,
DWORD cbProperty,
PVOID pvProperty
);
using LPCWSTR = const wchar_t*;
BOOL WinHttpQueryHeaders(
HINTERNET hRequest,
DWORD dwInfoLevel,
LPCWSTR pwszName,
LPVOID lpBuffer,
LPDWORD lpdwBufferLength,
LPDWORD lpdwIndex
);
DWORD WinHttpQueryHeadersEx(
HINTERNET hRequest,
DWORD dwInfoLevel,
ULONGLONG ullFlags,
UINT uiCodePage,
PDWORD pdwIndex,
PWINHTTP_HEADER_NAME pHeaderName,
PVOID pBuffer,
PDWORD pdwBufferLength,
PWINHTTP_EXTENDED_HEADER *ppHeaders,
PDWORD pdwHeadersCount
);
void sink(PCSTR);
void test_winhttp(HINTERNET hRequest) {
{
char buffer[1024];
DWORD bytesRead;
BOOL result = WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead);
sink(buffer);
sink(*buffer); // $ ir
}
{
char buffer[1024];
DWORD bytesRead;
DWORD result = WinHttpReadDataEx(hRequest, buffer, sizeof(buffer), &bytesRead, 0, 0, nullptr);
sink(buffer);
sink(*buffer); // $ ir
}
{
char buffer[1024];
DWORD bufferLength = sizeof(buffer);
WinHttpQueryHeaders(hRequest, 0, nullptr, buffer, &bufferLength, nullptr);
sink(buffer);
sink(*buffer); // $ ir
}
{
char buffer[1024];
DWORD bufferLength = sizeof(buffer);
PWINHTTP_EXTENDED_HEADER headers;
DWORD headersCount;
PWINHTTP_HEADER_NAME headerName;
DWORD result = WinHttpQueryHeadersEx(hRequest, 0, 0, 0, nullptr, headerName, buffer, &bufferLength, &headers, &headersCount);
sink(buffer);
sink(*buffer); // $ ir
sink(headerName->pszName);
sink(*headerName->pszName); // $ ir
sink(headers->pszValue);
sink(*headers->pszValue); // $ ir
}
}
using LPWSTR = wchar_t*;
using INTERNET_SCHEME = enum {
INTERNET_SCHEME_INVALID = -1,
INTERNET_SCHEME_UNKNOWN = 0,
INTERNET_SCHEME_HTTP = 1,
INTERNET_SCHEME_HTTPS = 2,
INTERNET_SCHEME_FTP = 3,
INTERNET_SCHEME_FILE = 4,
INTERNET_SCHEME_NEWS = 5,
INTERNET_SCHEME_MAILTO = 6,
INTERNET_SCHEME_SNEWS = 7,
INTERNET_SCHEME_SOCKS = 8,
INTERNET_SCHEME_WAIS = 9,
INTERNET_SCHEME_LAST = 10
};
using INTERNET_PORT = unsigned short;
typedef struct _WINHTTP_URL_COMPONENTS {
DWORD dwStructSize;
LPWSTR lpszScheme;
DWORD dwSchemeLength;
INTERNET_SCHEME nScheme;
LPWSTR lpszHostName;
DWORD dwHostNameLength;
INTERNET_PORT nPort;
LPWSTR lpszUserName;
DWORD dwUserNameLength;
LPWSTR lpszPassword;
DWORD dwPasswordLength;
LPWSTR lpszUrlPath;
DWORD dwUrlPathLength;
LPWSTR lpszExtraInfo;
DWORD dwExtraInfoLength;
} URL_COMPONENTS, *LPURL_COMPONENTS;
BOOL WinHttpCrackUrl(
LPCWSTR pwszUrl,
DWORD dwUrlLength,
DWORD dwFlags,
LPURL_COMPONENTS lpUrlComponents
);
void sink(LPWSTR);
void test_winhttp_crack_url() {
{
URL_COMPONENTS urlComponents;
urlComponents.dwStructSize = sizeof(URL_COMPONENTS);
wchar_t x[256];
x[0] = (wchar_t)source();
BOOL result = WinHttpCrackUrl(x, 0, 0, &urlComponents);
sink(urlComponents.lpszHostName);
sink(*urlComponents.lpszHostName); // $ ir
sink(urlComponents.lpszUrlPath);
sink(*urlComponents.lpszUrlPath); // $ ir
sink(urlComponents.lpszExtraInfo);
sink(*urlComponents.lpszExtraInfo); // $ ir
}
}

View File

@@ -12,4 +12,38 @@ void testCheckArgument(int p) {
if (checkArgument(&p)) {
sink(p); // $ barrier=glval<int> indirect_barrier=int
}
}
int* get_clean_value(int* x) { return x; }
bool is_clean_value(int*);
int* get_clean_pointer(int* x) { return x; }
bool is_clean_pointer(int*);
void sink(int*);
void test_mad(int x, int* p) {
{
if(is_clean_value(&x)) {
sink(x); // $ external=int
}
}
{
if(is_clean_value(p)) {
sink(*p); // $ external=int
}
}
{
if(is_clean_pointer(p)) {
sink(p); // $ external=int*
}
}
{
if(is_clean_pointer(&x)) {
sink(x); // $ external=glval<int>
}
}
}

View File

@@ -0,0 +1,13 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: barrierModel
data:
- ["", "", False, "get_clean_pointer", "", "", "ReturnValue", "test-barrier", "manual"]
- ["", "", False, "get_clean_data", "", "", "ReturnValue[*]", "test-barrier", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: barrierGuardModel
data:
- ["", "", False, "is_clean_value", "", "", "Argument[*0]", "true", "test-barrier", "manual"]
- ["", "", False, "is_clean_pointer", "", "", "Argument[0]", "true", "test-barrier", "manual"]

View File

@@ -2,6 +2,7 @@ import cpp
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.controlflow.IRGuards
import utils.test.InlineExpectationsTest
import semmle.code.cpp.dataflow.ExternalFlow
predicate instructionGuardChecks(IRGuardCondition gc, Instruction checked, boolean branch) {
exists(CallInstruction call |
@@ -27,18 +28,26 @@ predicate barrierGuard(DataFlow::Node node, string s) {
else s = node.getType().toString().replaceAll(" ", "")
}
predicate externalBarrierGuard(DataFlow::Node node, string s) {
barrierNode(node, "test-barrier") and
if node.isGLValue()
then s = "glval<" + node.getType().toString().replaceAll(" ", "") + ">"
else s = node.getType().toString().replaceAll(" ", "")
}
module Test implements TestSig {
string getARelevantTag() { result = ["barrier", "indirect_barrier"] }
string getARelevantTag() { result = ["barrier", "indirect_barrier", "external"] }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node node, string s |
indirectBarrierGuard(node, s) and
value = s and
exists(DataFlow::Node node |
indirectBarrierGuard(node, value) and
tag = "indirect_barrier"
or
barrierGuard(node, s) and
value = s and
barrierGuard(node, value) and
tag = "barrier"
or
externalBarrierGuard(node, value) and
tag = "external"
|
element = node.toString() and
location = node.getLocation()

View File

@@ -25131,6 +25131,517 @@ ir.cpp:
# 2823| Type = [ArrayType] int[]
# 2823| ValueCategory = lvalue
# 2824| getStmt(5): [ReturnStmt] return ...
# 2830| [TopLevelFunction] void test_assert_simple(int, int, unsigned int, int)
# 2830| <params>:
# 2830| getParameter(0): [Parameter] x
# 2830| Type = [IntType] int
# 2830| getParameter(1): [Parameter] y
# 2830| Type = [IntType] int
# 2830| getParameter(2): [Parameter] u
# 2830| Type = [IntType] unsigned int
# 2830| getParameter(3): [Parameter] shadowed
# 2830| Type = [IntType] int
# 2830| getEntryPoint(): [BlockStmt] { ... }
# 2831| getStmt(0): [ExprStmt] ExprStmt
# 2831| getExpr(): [Literal] 0
# 2831| Type = [IntType] int
# 2831| Value = [Literal] 0
# 2831| ValueCategory = prvalue
# 2831| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2831| Type = [VoidType] void
# 2831| ValueCategory = prvalue
# 2831| getExpr(): [CStyleCast] (void)...
# 2831| Conversion = [VoidConversion] conversion to void
# 2831| Type = [VoidType] void
# 2831| ValueCategory = prvalue
# 2832| getStmt(1): [ExprStmt] ExprStmt
# 2832| getExpr(): [Literal] 0
# 2832| Type = [IntType] int
# 2832| Value = [Literal] 0
# 2832| ValueCategory = prvalue
# 2832| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2832| Type = [VoidType] void
# 2832| ValueCategory = prvalue
# 2832| getExpr(): [CStyleCast] (void)...
# 2832| Conversion = [VoidConversion] conversion to void
# 2832| Type = [VoidType] void
# 2832| ValueCategory = prvalue
# 2833| getStmt(2): [ExprStmt] ExprStmt
# 2833| getExpr(): [Literal] 0
# 2833| Type = [IntType] int
# 2833| Value = [Literal] 0
# 2833| ValueCategory = prvalue
# 2833| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2833| Type = [VoidType] void
# 2833| ValueCategory = prvalue
# 2833| getExpr(): [CStyleCast] (void)...
# 2833| Conversion = [VoidConversion] conversion to void
# 2833| Type = [VoidType] void
# 2833| ValueCategory = prvalue
# 2835| getStmt(3): [EmptyStmt] ;
# 2837| getStmt(4): [ExprStmt] ExprStmt
# 2837| getExpr(): [Literal] 0
# 2837| Type = [IntType] int
# 2837| Value = [Literal] 0
# 2837| ValueCategory = prvalue
# 2837| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2837| Type = [VoidType] void
# 2837| ValueCategory = prvalue
# 2837| getExpr(): [CStyleCast] (void)...
# 2837| Conversion = [VoidConversion] conversion to void
# 2837| Type = [VoidType] void
# 2837| ValueCategory = prvalue
# 2839| getStmt(5): [BlockStmt] { ... }
# 2840| getStmt(0): [DeclStmt] declaration
# 2840| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
# 2840| Type = [IntType] int
# 2840| getVariable().getInitializer(): [Initializer] initializer for shadowed
# 2840| getExpr(): [VariableAccess] x
# 2840| Type = [IntType] int
# 2840| ValueCategory = prvalue(load)
# 2841| getStmt(1): [ExprStmt] ExprStmt
# 2841| getExpr(): [Literal] 0
# 2841| Type = [IntType] int
# 2841| Value = [Literal] 0
# 2841| ValueCategory = prvalue
# 2841| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2841| Type = [VoidType] void
# 2841| ValueCategory = prvalue
# 2841| getExpr(): [CStyleCast] (void)...
# 2841| Conversion = [VoidConversion] conversion to void
# 2841| Type = [VoidType] void
# 2841| ValueCategory = prvalue
# 2843| getStmt(6): [ReturnStmt] return ...
# 2846| [TemplateFunction,TopLevelFunction] void test_assert_in_template<T>(T, int, unsigned int)
# 2846| <params>:
# 2846| getParameter(0): [Parameter] x
# 2846| Type = [TypeTemplateParameter] T
# 2846| getParameter(1): [Parameter] y
# 2846| Type = [IntType] int
# 2846| getParameter(2): [Parameter] u
# 2846| Type = [IntType] unsigned int
# 2846| getEntryPoint(): [BlockStmt] { ... }
# 2847| getStmt(0): [ExprStmt] ExprStmt
# 2847| getExpr(): [Literal] 0
# 2847| Type = [IntType] int
# 2847| Value = [Literal] 0
# 2847| ValueCategory = prvalue
# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2847| Type = [VoidType] void
# 2847| ValueCategory = prvalue
# 2847| getExpr(): [CStyleCast] (void)...
# 2847| Conversion = [VoidConversion] conversion to void
# 2847| Type = [VoidType] void
# 2847| ValueCategory = prvalue
# 2848| getStmt(1): [ExprStmt] ExprStmt
# 2848| getExpr(): [Literal] 0
# 2848| Type = [IntType] int
# 2848| Value = [Literal] 0
# 2848| ValueCategory = prvalue
# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2848| Type = [VoidType] void
# 2848| ValueCategory = prvalue
# 2848| getExpr(): [CStyleCast] (void)...
# 2848| Conversion = [VoidConversion] conversion to void
# 2848| Type = [VoidType] void
# 2848| ValueCategory = prvalue
# 2849| getStmt(2): [ExprStmt] ExprStmt
# 2849| getExpr(): [Literal] 0
# 2849| Type = [IntType] int
# 2849| Value = [Literal] 0
# 2849| ValueCategory = prvalue
# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2849| Type = [VoidType] void
# 2849| ValueCategory = prvalue
# 2849| getExpr(): [CStyleCast] (void)...
# 2849| Conversion = [VoidConversion] conversion to void
# 2849| Type = [VoidType] void
# 2849| ValueCategory = prvalue
# 2851| getStmt(3): [EmptyStmt] ;
# 2853| getStmt(4): [ExprStmt] ExprStmt
# 2853| getExpr(): [Literal] 0
# 2853| Type = [IntType] int
# 2853| Value = [Literal] 0
# 2853| ValueCategory = prvalue
# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2853| Type = [VoidType] void
# 2853| ValueCategory = prvalue
# 2853| getExpr(): [CStyleCast] (void)...
# 2853| Conversion = [VoidConversion] conversion to void
# 2853| Type = [VoidType] void
# 2853| ValueCategory = prvalue
# 2855| getStmt(5): [BlockStmt] { ... }
# 2856| getStmt(0): [DeclStmt] declaration
# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
# 2856| Type = [IntType] int
# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed
# 2856| getExpr(): [VariableAccess] x
# 2856| Type = [TypeTemplateParameter] T
# 2856| ValueCategory = lvalue
# 2856| getExpr().getFullyConverted(): [CStyleCast] (int)...
# 2856| Type = [IntType] int
# 2856| ValueCategory = prvalue
# 2857| getStmt(1): [ExprStmt] ExprStmt
# 2857| getExpr(): [Literal] 0
# 2857| Type = [IntType] int
# 2857| Value = [Literal] 0
# 2857| ValueCategory = prvalue
# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2857| Type = [VoidType] void
# 2857| ValueCategory = prvalue
# 2857| getExpr(): [CStyleCast] (void)...
# 2857| Conversion = [VoidConversion] conversion to void
# 2857| Type = [VoidType] void
# 2857| ValueCategory = prvalue
# 2859| getStmt(6): [ExprStmt] ExprStmt
# 2859| getExpr(): [Literal] 0
# 2859| Type = [IntType] int
# 2859| Value = [Literal] 0
# 2859| ValueCategory = prvalue
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2859| getExpr(): [CStyleCast] (void)...
# 2859| Conversion = [VoidConversion] conversion to void
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2860| getStmt(7): [ReturnStmt] return ...
# 2846| [FunctionTemplateInstantiation,TopLevelFunction] void test_assert_in_template<int>(int, int, unsigned int)
# 2846| <params>:
# 2846| getParameter(0): [Parameter] x
# 2846| Type = [IntType] int
# 2846| getParameter(1): [Parameter] y
# 2846| Type = [IntType] int
# 2846| getParameter(2): [Parameter] u
# 2846| Type = [IntType] unsigned int
# 2846| getEntryPoint(): [BlockStmt] { ... }
# 2847| getStmt(0): [ExprStmt] ExprStmt
# 2847| getExpr(): [Literal] 0
# 2847| Type = [IntType] int
# 2847| Value = [Literal] 0
# 2847| ValueCategory = prvalue
# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2847| Type = [VoidType] void
# 2847| ValueCategory = prvalue
# 2847| getExpr(): [CStyleCast] (void)...
# 2847| Conversion = [VoidConversion] conversion to void
# 2847| Type = [VoidType] void
# 2847| ValueCategory = prvalue
# 2848| getStmt(1): [ExprStmt] ExprStmt
# 2848| getExpr(): [Literal] 0
# 2848| Type = [IntType] int
# 2848| Value = [Literal] 0
# 2848| ValueCategory = prvalue
# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2848| Type = [VoidType] void
# 2848| ValueCategory = prvalue
# 2848| getExpr(): [CStyleCast] (void)...
# 2848| Conversion = [VoidConversion] conversion to void
# 2848| Type = [VoidType] void
# 2848| ValueCategory = prvalue
# 2849| getStmt(2): [ExprStmt] ExprStmt
# 2849| getExpr(): [Literal] 0
# 2849| Type = [IntType] int
# 2849| Value = [Literal] 0
# 2849| ValueCategory = prvalue
# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2849| Type = [VoidType] void
# 2849| ValueCategory = prvalue
# 2849| getExpr(): [CStyleCast] (void)...
# 2849| Conversion = [VoidConversion] conversion to void
# 2849| Type = [VoidType] void
# 2849| ValueCategory = prvalue
# 2851| getStmt(3): [EmptyStmt] ;
# 2853| getStmt(4): [ExprStmt] ExprStmt
# 2853| getExpr(): [Literal] 0
# 2853| Type = [IntType] int
# 2853| Value = [Literal] 0
# 2853| ValueCategory = prvalue
# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2853| Type = [VoidType] void
# 2853| ValueCategory = prvalue
# 2853| getExpr(): [CStyleCast] (void)...
# 2853| Conversion = [VoidConversion] conversion to void
# 2853| Type = [VoidType] void
# 2853| ValueCategory = prvalue
# 2855| getStmt(5): [BlockStmt] { ... }
# 2856| getStmt(0): [DeclStmt] declaration
# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
# 2856| Type = [IntType] int
# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed
# 2856| getExpr(): [VariableAccess] x
# 2856| Type = [IntType] int
# 2856| ValueCategory = prvalue(load)
# 2857| getStmt(1): [ExprStmt] ExprStmt
# 2857| getExpr(): [Literal] 0
# 2857| Type = [IntType] int
# 2857| Value = [Literal] 0
# 2857| ValueCategory = prvalue
# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2857| Type = [VoidType] void
# 2857| ValueCategory = prvalue
# 2857| getExpr(): [CStyleCast] (void)...
# 2857| Conversion = [VoidConversion] conversion to void
# 2857| Type = [VoidType] void
# 2857| ValueCategory = prvalue
# 2859| getStmt(6): [ExprStmt] ExprStmt
# 2859| getExpr(): [Literal] 0
# 2859| Type = [IntType] int
# 2859| Value = [Literal] 0
# 2859| ValueCategory = prvalue
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2859| getExpr(): [CStyleCast] (void)...
# 2859| Conversion = [VoidConversion] conversion to void
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2860| getStmt(7): [ReturnStmt] return ...
# 2846| [FunctionTemplateInstantiation,TopLevelFunction] void test_assert_in_template<short>(short, int, unsigned int)
# 2846| <params>:
# 2846| getParameter(0): [Parameter] x
# 2846| Type = [ShortType] short
# 2846| getParameter(1): [Parameter] y
# 2846| Type = [IntType] int
# 2846| getParameter(2): [Parameter] u
# 2846| Type = [IntType] unsigned int
# 2846| getEntryPoint(): [BlockStmt] { ... }
# 2847| getStmt(0): [ExprStmt] ExprStmt
# 2847| getExpr(): [Literal] 0
# 2847| Type = [IntType] int
# 2847| Value = [Literal] 0
# 2847| ValueCategory = prvalue
# 2847| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2847| Type = [VoidType] void
# 2847| ValueCategory = prvalue
# 2847| getExpr(): [CStyleCast] (void)...
# 2847| Conversion = [VoidConversion] conversion to void
# 2847| Type = [VoidType] void
# 2847| ValueCategory = prvalue
# 2848| getStmt(1): [ExprStmt] ExprStmt
# 2848| getExpr(): [Literal] 0
# 2848| Type = [IntType] int
# 2848| Value = [Literal] 0
# 2848| ValueCategory = prvalue
# 2848| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2848| Type = [VoidType] void
# 2848| ValueCategory = prvalue
# 2848| getExpr(): [CStyleCast] (void)...
# 2848| Conversion = [VoidConversion] conversion to void
# 2848| Type = [VoidType] void
# 2848| ValueCategory = prvalue
# 2849| getStmt(2): [ExprStmt] ExprStmt
# 2849| getExpr(): [Literal] 0
# 2849| Type = [IntType] int
# 2849| Value = [Literal] 0
# 2849| ValueCategory = prvalue
# 2849| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2849| Type = [VoidType] void
# 2849| ValueCategory = prvalue
# 2849| getExpr(): [CStyleCast] (void)...
# 2849| Conversion = [VoidConversion] conversion to void
# 2849| Type = [VoidType] void
# 2849| ValueCategory = prvalue
# 2851| getStmt(3): [EmptyStmt] ;
# 2853| getStmt(4): [ExprStmt] ExprStmt
# 2853| getExpr(): [Literal] 0
# 2853| Type = [IntType] int
# 2853| Value = [Literal] 0
# 2853| ValueCategory = prvalue
# 2853| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2853| Type = [VoidType] void
# 2853| ValueCategory = prvalue
# 2853| getExpr(): [CStyleCast] (void)...
# 2853| Conversion = [VoidConversion] conversion to void
# 2853| Type = [VoidType] void
# 2853| ValueCategory = prvalue
# 2855| getStmt(5): [BlockStmt] { ... }
# 2856| getStmt(0): [DeclStmt] declaration
# 2856| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
# 2856| Type = [IntType] int
# 2856| getVariable().getInitializer(): [Initializer] initializer for shadowed
# 2856| getExpr(): [VariableAccess] x
# 2856| Type = [ShortType] short
# 2856| ValueCategory = prvalue(load)
# 2856| getExpr().getFullyConverted(): [CStyleCast] (int)...
# 2856| Conversion = [IntegralConversion] integral conversion
# 2856| Type = [IntType] int
# 2856| ValueCategory = prvalue
# 2857| getStmt(1): [ExprStmt] ExprStmt
# 2857| getExpr(): [Literal] 0
# 2857| Type = [IntType] int
# 2857| Value = [Literal] 0
# 2857| ValueCategory = prvalue
# 2857| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2857| Type = [VoidType] void
# 2857| ValueCategory = prvalue
# 2857| getExpr(): [CStyleCast] (void)...
# 2857| Conversion = [VoidConversion] conversion to void
# 2857| Type = [VoidType] void
# 2857| ValueCategory = prvalue
# 2859| getStmt(6): [ExprStmt] ExprStmt
# 2859| getExpr(): [Literal] 0
# 2859| Type = [IntType] int
# 2859| Value = [Literal] 0
# 2859| ValueCategory = prvalue
# 2859| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2859| getExpr(): [CStyleCast] (void)...
# 2859| Conversion = [VoidConversion] conversion to void
# 2859| Type = [VoidType] void
# 2859| ValueCategory = prvalue
# 2860| getStmt(7): [ReturnStmt] return ...
# 2867| [TopLevelFunction] void (unnamed namespace)::complex_assertions(int, bool, int)
# 2867| <params>:
# 2867| getParameter(0): [Parameter] x
# 2867| Type = [IntType] int
# 2867| getParameter(1): [Parameter] b
# 2867| Type = [BoolType] bool
# 2867| getParameter(2): [Parameter] max
# 2867| Type = [IntType] int
# 2867| getEntryPoint(): [BlockStmt] { ... }
# 2868| getStmt(0): [DeclStmt] declaration
# 2868| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
# 2868| Type = [IntType] int
# 2868| getVariable().getInitializer(): [Initializer] initializer for y
# 2868| getExpr(): [CommaExpr] ... , ...
# 2868| Type = [IntType] int
# 2868| ValueCategory = prvalue(load)
# 2868| getLeftOperand(): [Literal] 0
# 2868| Type = [IntType] int
# 2868| Value = [Literal] 0
# 2868| ValueCategory = prvalue
# 2868| getRightOperand(): [VariableAccess] x
# 2868| Type = [IntType] int
# 2868| ValueCategory = prvalue(load)
# 2868| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2868| Type = [VoidType] void
# 2868| ValueCategory = prvalue
# 2868| getExpr(): [CStyleCast] (void)...
# 2868| Conversion = [VoidConversion] conversion to void
# 2868| Type = [VoidType] void
# 2868| ValueCategory = prvalue
# 2868| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2868| Type = [IntType] int
# 2868| ValueCategory = prvalue(load)
# 2869| getStmt(1): [DeclStmt] declaration
# 2869| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z
# 2869| Type = [IntType] int
# 2869| getVariable().getInitializer(): [Initializer] initializer for z
# 2869| getExpr(): [ConditionalExpr] ... ? ... : ...
# 2869| Type = [IntType] int
# 2869| ValueCategory = prvalue
# 2869| getCondition(): [VariableAccess] b
# 2869| Type = [BoolType] bool
# 2869| ValueCategory = prvalue(load)
# 2869| getThen(): [CommaExpr] ... , ...
# 2869| Type = [IntType] int
# 2869| Value = [CommaExpr] 0
# 2869| ValueCategory = prvalue
# 2869| getLeftOperand(): [Literal] 0
# 2869| Type = [IntType] int
# 2869| Value = [Literal] 0
# 2869| ValueCategory = prvalue
# 2869| getRightOperand(): [Literal] 0
# 2869| Type = [IntType] int
# 2869| Value = [Literal] 0
# 2869| ValueCategory = prvalue
# 2869| getLeftOperand().getFullyConverted(): [ParenthesisExpr] (...)
# 2869| Type = [VoidType] void
# 2869| ValueCategory = prvalue
# 2869| getExpr(): [CStyleCast] (void)...
# 2869| Conversion = [VoidConversion] conversion to void
# 2869| Type = [VoidType] void
# 2869| ValueCategory = prvalue
# 2869| getElse(): [Literal] 1
# 2869| Type = [IntType] int
# 2869| Value = [Literal] 1
# 2869| ValueCategory = prvalue
# 2869| getThen().getFullyConverted(): [ParenthesisExpr] (...)
# 2869| Type = [IntType] int
# 2869| Value = [ParenthesisExpr] 0
# 2869| ValueCategory = prvalue
# 2871| getStmt(2): [TryStmt] try { ... }
# 2871| getStmt(): [BlockStmt] { ... }
# 2872| getStmt(0): [ExprStmt] ExprStmt
# 2872| getExpr(): [ThrowExpr] throw ...
# 2872| Type = [IntType] int
# 2872| ValueCategory = prvalue
# 2872| getExpr(): [Literal] 41
# 2872| Type = [IntType] int
# 2872| Value = [Literal] 41
# 2872| ValueCategory = prvalue
# 2873| getChild(1): [Handler] <handler>
# 2873| getParameter(): [Parameter] c
# 2873| Type = [IntType] int
# 2873| getBlock(): [CatchBlock] { ... }
# 2874| getStmt(0): [ExprStmt] ExprStmt
# 2874| getExpr(): [Literal] 0
# 2874| Type = [IntType] int
# 2874| Value = [Literal] 0
# 2874| ValueCategory = prvalue
# 2874| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2874| Type = [VoidType] void
# 2874| ValueCategory = prvalue
# 2874| getExpr(): [CStyleCast] (void)...
# 2874| Conversion = [VoidConversion] conversion to void
# 2874| Type = [VoidType] void
# 2874| ValueCategory = prvalue
# 2875| getStmt(1): [ExprStmt] ExprStmt
# 2875| getExpr(): [Literal] 0
# 2875| Type = [IntType] int
# 2875| Value = [Literal] 0
# 2875| ValueCategory = prvalue
# 2875| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2875| Type = [VoidType] void
# 2875| ValueCategory = prvalue
# 2875| getExpr(): [CStyleCast] (void)...
# 2875| Conversion = [VoidConversion] conversion to void
# 2875| Type = [VoidType] void
# 2875| ValueCategory = prvalue
# 2878| getStmt(3): [ExprStmt] ExprStmt
# 2878| getExpr(): [Literal] 0
# 2878| Type = [IntType] int
# 2878| Value = [Literal] 0
# 2878| ValueCategory = prvalue
# 2878| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2878| Type = [VoidType] void
# 2878| ValueCategory = prvalue
# 2878| getExpr(): [CStyleCast] (void)...
# 2878| Conversion = [VoidConversion] conversion to void
# 2878| Type = [VoidType] void
# 2878| ValueCategory = prvalue
# 2879| getStmt(4): [DeclStmt] declaration
# 2879| getDeclarationEntry(0): [VariableDeclarationEntry] definition of shadowed
# 2879| Type = [IntType] int
# 2881| getStmt(5): [TryStmt] try { ... }
# 2881| getStmt(): [BlockStmt] { ... }
# 2882| getStmt(0): [ExprStmt] ExprStmt
# 2882| getExpr(): [ThrowExpr] throw ...
# 2882| Type = [IntType] int
# 2882| ValueCategory = prvalue
# 2882| getExpr(): [Literal] 41
# 2882| Type = [IntType] int
# 2882| Value = [Literal] 41
# 2882| ValueCategory = prvalue
# 2883| getChild(1): [Handler] <handler>
# 2883| getParameter(): [Parameter] shadowed
# 2883| Type = [IntType] int
# 2883| getBlock(): [CatchBlock] { ... }
# 2884| getStmt(0): [ExprStmt] ExprStmt
# 2884| getExpr(): [Literal] 0
# 2884| Type = [IntType] int
# 2884| Value = [Literal] 0
# 2884| ValueCategory = prvalue
# 2884| getExpr().getFullyConverted(): [ParenthesisExpr] (...)
# 2884| Type = [VoidType] void
# 2884| ValueCategory = prvalue
# 2884| getExpr(): [CStyleCast] (void)...
# 2884| Conversion = [VoidConversion] conversion to void
# 2884| Type = [VoidType] void
# 2884| ValueCategory = prvalue
# 2886| getStmt(6): [ReturnStmt] return ...
ir23.cpp:
# 1| [TopLevelFunction] bool consteval_1()
# 1| <params>:

View File

@@ -20741,6 +20741,331 @@ ir.cpp:
# 2821| v2821_10(void) = AliasedUse : m2821_3
# 2821| v2821_11(void) = ExitFunction :
# 2830| void test_assert_simple(int, int, unsigned int, int)
# 2830| Block 0
# 2830| v2830_1(void) = EnterFunction :
# 2830| m2830_2(unknown) = AliasedDefinition :
# 2830| m2830_3(unknown) = InitializeNonLocal :
# 2830| m2830_4(unknown) = Chi : total:m2830_2, partial:m2830_3
# 2830| r2830_5(glval<int>) = VariableAddress[x] :
# 2830| m2830_6(int) = InitializeParameter[x] : &:r2830_5
# 2830| r2830_7(glval<int>) = VariableAddress[y] :
# 2830| m2830_8(int) = InitializeParameter[y] : &:r2830_7
# 2830| r2830_9(glval<unsigned int>) = VariableAddress[u] :
# 2830| m2830_10(unsigned int) = InitializeParameter[u] : &:r2830_9
# 2830| r2830_11(glval<int>) = VariableAddress[shadowed] :
# 2830| m2830_12(int) = InitializeParameter[shadowed] : &:r2830_11
# 2831| r2831_1(glval<int>) = VariableAddress[x] :
# 2831| r2831_2(int) = Load[x] : &:r2831_1, m2830_6
# 2831| r2831_3(int) = Constant[0] :
# 2831| r2831_4(bool) = CompareGT : r2831_2, r2831_3
# 2831| v2831_5(void) = ConditionalBranch : r2831_4
#-----| True -> Block 1
# 2832| Block 1
# 2832| r2832_1(int) = Constant[0] :
# 2832| r2832_2(glval<int>) = VariableAddress[x] :
# 2832| r2832_3(int) = Load[x] : &:r2832_2, m2830_6
# 2832| r2832_4(bool) = CompareLT : r2832_1, r2832_3
# 2832| v2832_5(void) = ConditionalBranch : r2832_4
#-----| True -> Block 2
# 2833| Block 2
# 2833| r2833_1(glval<int>) = VariableAddress[x] :
# 2833| r2833_2(int) = Load[x] : &:r2833_1, m2830_6
# 2833| r2833_3(glval<int>) = VariableAddress[y] :
# 2833| r2833_4(int) = Load[y] : &:r2833_3, m2830_8
# 2833| r2833_5(bool) = CompareLT : r2833_2, r2833_4
# 2833| v2833_6(void) = ConditionalBranch : r2833_5
#-----| True -> Block 3
# 2835| Block 3
# 2835| r2835_1(glval<int>) = VariableAddress[x] :
# 2835| r2835_2(int) = Load[x] : &:r2835_1, m2830_6
# 2835| r2835_3(int) = Constant[2] :
# 2835| r2835_4(bool) = CompareNE : r2835_2, r2835_3
# 2835| v2835_5(void) = ConditionalBranch : r2835_4
#-----| True -> Block 4
# 2837| Block 4
# 2837| r2837_1(glval<unsigned int>) = VariableAddress[u] :
# 2837| r2837_2(unsigned int) = Load[u] : &:r2837_1, m2830_10
# 2837| r2837_3(glval<int>) = VariableAddress[x] :
# 2837| r2837_4(int) = Load[x] : &:r2837_3, m2830_6
# 2837| r2837_5(bool) = CompareLT : r2837_2, r2837_4
# 2837| v2837_6(void) = ConditionalBranch : r2837_5
#-----| True -> Block 5
# 2840| Block 5
# 2840| r2840_1(glval<int>) = VariableAddress[shadowed] :
# 2840| r2840_2(glval<int>) = VariableAddress[x] :
# 2840| r2840_3(int) = Load[x] : &:r2840_2, m2830_6
# 2840| m2840_4(int) = Store[shadowed] : &:r2840_1, r2840_3
# 2841| r2841_1(int) = Constant[0] :
# 2841| v2841_2(void) = Convert : r2841_1
# 2843| v2843_1(void) = NoOp :
# 2830| v2830_13(void) = ReturnVoid :
# 2830| v2830_14(void) = AliasedUse : m2830_3
# 2830| v2830_15(void) = ExitFunction :
# 2846| void test_assert_in_template<int>(int, int, unsigned int)
# 2846| Block 0
# 2846| v2846_1(void) = EnterFunction :
# 2846| m2846_2(unknown) = AliasedDefinition :
# 2846| m2846_3(unknown) = InitializeNonLocal :
# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3
# 2846| r2846_5(glval<int>) = VariableAddress[x] :
# 2846| m2846_6(int) = InitializeParameter[x] : &:r2846_5
# 2846| r2846_7(glval<int>) = VariableAddress[y] :
# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7
# 2846| r2846_9(glval<unsigned int>) = VariableAddress[u] :
# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9
# 2847| r2847_1(glval<int>) = VariableAddress[x] :
# 2847| r2847_2(int) = Load[x] : &:r2847_1, m2846_6
# 2847| r2847_3(int) = Constant[0] :
# 2847| r2847_4(bool) = CompareGT : r2847_2, r2847_3
# 2847| v2847_5(void) = ConditionalBranch : r2847_4
#-----| True -> Block 1
# 2848| Block 1
# 2848| r2848_1(int) = Constant[0] :
# 2848| r2848_2(glval<int>) = VariableAddress[x] :
# 2848| r2848_3(int) = Load[x] : &:r2848_2, m2846_6
# 2848| r2848_4(bool) = CompareLT : r2848_1, r2848_3
# 2848| v2848_5(void) = ConditionalBranch : r2848_4
#-----| True -> Block 2
# 2849| Block 2
# 2849| r2849_1(glval<int>) = VariableAddress[x] :
# 2849| r2849_2(int) = Load[x] : &:r2849_1, m2846_6
# 2849| r2849_3(glval<int>) = VariableAddress[y] :
# 2849| r2849_4(int) = Load[y] : &:r2849_3, m2846_8
# 2849| r2849_5(bool) = CompareLT : r2849_2, r2849_4
# 2849| v2849_6(void) = ConditionalBranch : r2849_5
#-----| True -> Block 3
# 2851| Block 3
# 2851| r2851_1(glval<int>) = VariableAddress[x] :
# 2851| r2851_2(int) = Load[x] : &:r2851_1, m2846_6
# 2851| r2851_3(int) = Constant[2] :
# 2851| r2851_4(bool) = CompareNE : r2851_2, r2851_3
# 2851| v2851_5(void) = ConditionalBranch : r2851_4
#-----| True -> Block 4
# 2853| Block 4
# 2853| r2853_1(glval<unsigned int>) = VariableAddress[u] :
# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, m2846_10
# 2853| r2853_3(glval<int>) = VariableAddress[x] :
# 2853| r2853_4(int) = Load[x] : &:r2853_3, m2846_6
# 2853| r2853_5(bool) = CompareLT : r2853_2, r2853_4
# 2853| v2853_6(void) = ConditionalBranch : r2853_5
#-----| True -> Block 5
# 2856| Block 5
# 2856| r2856_1(glval<int>) = VariableAddress[shadowed] :
# 2856| r2856_2(glval<int>) = VariableAddress[x] :
# 2856| r2856_3(int) = Load[x] : &:r2856_2, m2846_6
# 2856| m2856_4(int) = Store[shadowed] : &:r2856_1, r2856_3
# 2857| r2857_1(glval<int>) = VariableAddress[shadowed] :
# 2857| r2857_2(int) = Load[shadowed] : &:r2857_1, m2856_4
# 2857| r2857_3(int) = Constant[0] :
# 2857| r2857_4(bool) = CompareGT : r2857_2, r2857_3
# 2857| v2857_5(void) = ConditionalBranch : r2857_4
#-----| True -> Block 6
# 2859| Block 6
# 2859| r2859_1(glval<int>) = VariableAddress[x] :
# 2859| r2859_2(int) = Load[x] : &:r2859_1, m2846_6
# 2859| r2859_3(int) = Constant[0] :
# 2859| r2859_4(bool) = CompareGT : r2859_2, r2859_3
# 2859| v2859_5(void) = ConditionalBranch : r2859_4
#-----| True -> Block 7
# 2860| Block 7
# 2860| v2860_1(void) = NoOp :
# 2846| v2846_11(void) = ReturnVoid :
# 2846| v2846_12(void) = AliasedUse : m2846_3
# 2846| v2846_13(void) = ExitFunction :
# 2846| void test_assert_in_template<short>(short, int, unsigned int)
# 2846| Block 0
# 2846| v2846_1(void) = EnterFunction :
# 2846| m2846_2(unknown) = AliasedDefinition :
# 2846| m2846_3(unknown) = InitializeNonLocal :
# 2846| m2846_4(unknown) = Chi : total:m2846_2, partial:m2846_3
# 2846| r2846_5(glval<short>) = VariableAddress[x] :
# 2846| m2846_6(short) = InitializeParameter[x] : &:r2846_5
# 2846| r2846_7(glval<int>) = VariableAddress[y] :
# 2846| m2846_8(int) = InitializeParameter[y] : &:r2846_7
# 2846| r2846_9(glval<unsigned int>) = VariableAddress[u] :
# 2846| m2846_10(unsigned int) = InitializeParameter[u] : &:r2846_9
# 2847| r2847_1(glval<short>) = VariableAddress[x] :
# 2847| r2847_2(short) = Load[x] : &:r2847_1, m2846_6
# 2847| r2847_3(int) = Constant[0] :
# 2847| r2847_4(bool) = CompareGT : r2847_2, r2847_3
# 2847| v2847_5(void) = ConditionalBranch : r2847_4
#-----| True -> Block 1
# 2848| Block 1
# 2848| r2848_1(int) = Constant[0] :
# 2848| r2848_2(glval<short>) = VariableAddress[x] :
# 2848| r2848_3(short) = Load[x] : &:r2848_2, m2846_6
# 2848| r2848_4(bool) = CompareLT : r2848_1, r2848_3
# 2848| v2848_5(void) = ConditionalBranch : r2848_4
#-----| True -> Block 2
# 2849| Block 2
# 2849| r2849_1(glval<short>) = VariableAddress[x] :
# 2849| r2849_2(short) = Load[x] : &:r2849_1, m2846_6
# 2849| r2849_3(glval<int>) = VariableAddress[y] :
# 2849| r2849_4(int) = Load[y] : &:r2849_3, m2846_8
# 2849| r2849_5(bool) = CompareLT : r2849_2, r2849_4
# 2849| v2849_6(void) = ConditionalBranch : r2849_5
#-----| True -> Block 3
# 2851| Block 3
# 2851| r2851_1(glval<short>) = VariableAddress[x] :
# 2851| r2851_2(short) = Load[x] : &:r2851_1, m2846_6
# 2851| r2851_3(int) = Constant[2] :
# 2851| r2851_4(bool) = CompareNE : r2851_2, r2851_3
# 2851| v2851_5(void) = ConditionalBranch : r2851_4
#-----| True -> Block 4
# 2853| Block 4
# 2853| r2853_1(glval<unsigned int>) = VariableAddress[u] :
# 2853| r2853_2(unsigned int) = Load[u] : &:r2853_1, m2846_10
# 2853| r2853_3(glval<short>) = VariableAddress[x] :
# 2853| r2853_4(short) = Load[x] : &:r2853_3, m2846_6
# 2853| r2853_5(bool) = CompareLT : r2853_2, r2853_4
# 2853| v2853_6(void) = ConditionalBranch : r2853_5
#-----| True -> Block 5
# 2856| Block 5
# 2856| r2856_1(glval<int>) = VariableAddress[shadowed] :
# 2856| r2856_2(glval<short>) = VariableAddress[x] :
# 2856| r2856_3(short) = Load[x] : &:r2856_2, m2846_6
# 2856| r2856_4(int) = Convert : r2856_3
# 2856| m2856_5(int) = Store[shadowed] : &:r2856_1, r2856_4
# 2857| r2857_1(glval<int>) = VariableAddress[shadowed] :
# 2857| r2857_2(int) = Load[shadowed] : &:r2857_1, m2856_5
# 2857| r2857_3(int) = Constant[0] :
# 2857| r2857_4(bool) = CompareGT : r2857_2, r2857_3
# 2857| v2857_5(void) = ConditionalBranch : r2857_4
#-----| True -> Block 6
# 2859| Block 6
# 2859| r2859_1(glval<short>) = VariableAddress[x] :
# 2859| r2859_2(short) = Load[x] : &:r2859_1, m2846_6
# 2859| r2859_3(int) = Constant[0] :
# 2859| r2859_4(bool) = CompareGT : r2859_2, r2859_3
# 2859| v2859_5(void) = ConditionalBranch : r2859_4
#-----| True -> Block 7
# 2860| Block 7
# 2860| v2860_1(void) = NoOp :
# 2846| v2846_11(void) = ReturnVoid :
# 2846| v2846_12(void) = AliasedUse : m2846_3
# 2846| v2846_13(void) = ExitFunction :
# 2867| void (unnamed namespace)::complex_assertions(int, bool, int)
# 2867| Block 0
# 2867| v2867_1(void) = EnterFunction :
# 2867| m2867_2(unknown) = AliasedDefinition :
# 2867| m2867_3(unknown) = InitializeNonLocal :
# 2867| m2867_4(unknown) = Chi : total:m2867_2, partial:m2867_3
# 2867| r2867_5(glval<int>) = VariableAddress[x] :
# 2867| m2867_6(int) = InitializeParameter[x] : &:r2867_5
# 2867| r2867_7(glval<bool>) = VariableAddress[b] :
# 2867| m2867_8(bool) = InitializeParameter[b] : &:r2867_7
# 2867| r2867_9(glval<int>) = VariableAddress[max] :
# 2867| m2867_10(int) = InitializeParameter[max] : &:r2867_9
# 2868| r2868_1(glval<int>) = VariableAddress[y] :
# 2868| r2868_2(int) = Constant[0] :
# 2868| v2868_3(void) = Convert : r2868_2
# 2868| r2868_4(glval<int>) = VariableAddress[x] :
# 2868| r2868_5(int) = Load[x] : &:r2868_4, m2867_6
# 2868| r2868_6(int) = CopyValue : r2868_5
# 2868| m2868_7(int) = Store[y] : &:r2868_1, r2868_6
# 2869| r2869_1(glval<int>) = VariableAddress[z] :
# 2869| r2869_2(glval<bool>) = VariableAddress[b] :
# 2869| r2869_3(bool) = Load[b] : &:r2869_2, m2867_8
# 2869| v2869_4(void) = ConditionalBranch : r2869_3
#-----| False -> Block 5
#-----| True -> Block 4
# 2867| Block 1
# 2867| v2867_11(void) = AliasedUse : m2867_3
# 2867| v2867_12(void) = ExitFunction :
# 2867| Block 2
# 2867| v2867_13(void) = Unwind :
#-----| Goto -> Block 1
# 2869| Block 3
# 2869| m2869_5(int) = Phi : from 4:m2869_11, from 5:m2869_14
# 2869| r2869_6(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| r2869_7(int) = Load[#temp2869:17] : &:r2869_6, m2869_5
# 2869| m2869_8(int) = Store[z] : &:r2869_1, r2869_7
# 2872| r2872_1(glval<int>) = VariableAddress[#throw2872:13] :
# 2872| r2872_2(int) = Constant[41] :
# 2872| m2872_3(int) = Store[#throw2872:13] : &:r2872_1, r2872_2
# 2872| v2872_4(void) = ThrowValue : &:r2872_1, m2872_3
#-----| C++ Exception -> Block 6
# 2869| Block 4
# 2869| r2869_9(int) = Constant[0] :
# 2869| r2869_10(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| m2869_11(int) = Store[#temp2869:17] : &:r2869_10, r2869_9
#-----| Goto -> Block 3
# 2869| Block 5
# 2869| r2869_12(int) = Constant[1] :
# 2869| r2869_13(glval<int>) = VariableAddress[#temp2869:17] :
# 2869| m2869_14(int) = Store[#temp2869:17] : &:r2869_13, r2869_12
#-----| Goto -> Block 3
# 2873| Block 6
# 2873| v2873_1(void) = CatchByType[int] :
#-----| C++ Exception -> Block 2
#-----| Goto -> Block 7
# 2873| Block 7
# 2873| r2873_2(glval<int>) = VariableAddress[c] :
# 2873| m2873_3(int) = InitializeParameter[c] : &:r2873_2
# 2874| r2874_1(glval<int>) = VariableAddress[c] :
# 2874| r2874_2(int) = Load[c] : &:r2874_1, m2873_3
# 2874| r2874_3(int) = Constant[42] :
# 2874| r2874_4(bool) = CompareLT : r2874_2, r2874_3
# 2874| v2874_5(void) = ConditionalBranch : r2874_4
#-----| True -> Block 8
# 2875| Block 8
# 2875| r2875_1(int) = Constant[0] :
# 2875| v2875_2(void) = Convert : r2875_1
# 2878| r2878_1(int) = Constant[0] :
# 2878| v2878_2(void) = Convert : r2878_1
# 2879| r2879_1(glval<int>) = VariableAddress[shadowed] :
# 2879| m2879_2(int) = Uninitialized[shadowed] : &:r2879_1
# 2882| r2882_1(glval<int>) = VariableAddress[#throw2882:13] :
# 2882| r2882_2(int) = Constant[41] :
# 2882| m2882_3(int) = Store[#throw2882:13] : &:r2882_1, r2882_2
# 2882| v2882_4(void) = ThrowValue : &:r2882_1, m2882_3
#-----| C++ Exception -> Block 9
# 2883| Block 9
# 2883| v2883_1(void) = CatchByType[int] :
#-----| C++ Exception -> Block 2
#-----| Goto -> Block 10
# 2883| Block 10
# 2883| r2883_2(glval<int>) = VariableAddress[shadowed] :
# 2883| m2883_3(int) = InitializeParameter[shadowed] : &:r2883_2
# 2884| r2884_1(int) = Constant[0] :
# 2884| v2884_2(void) = Convert : r2884_1
# 2886| v2886_1(void) = NoOp :
# 2867| v2867_14(void) = ReturnVoid :
#-----| Goto -> Block 1
ir23.cpp:
# 1| bool consteval_1()
# 1| Block 0

Some files were not shown because too many files have changed in this diff Show More