Compare commits

..

889 Commits

Author SHA1 Message Date
Dave Bartolomeo
9798fcddfa Merge pull request #13998 from github/release-prep/2.14.3
Release preparation for version 2.14.3
2023-08-18 14:59:47 -04:00
github-actions[bot]
098dfb4242 Release preparation for version 2.14.3 2023-08-18 14:48:15 +00:00
Jonas Jensen
a002f59f58 C++: Undo BadlyBoundedWrite change from #13929
This rolls back the query change, ensuring that there is no need for a
change note.
2023-08-18 13:48:58 +02:00
Jonas Jensen
478a105e21 C++: delete change note
Since the previous commit removed the best evidence we had for the
change described in this note, I'm removing the note for now.
2023-08-18 13:35:32 +02:00
Jonas Jensen
cd1f196848 C++: Accept regression in test after evaluator fix 2023-08-18 13:30:20 +02:00
Harry Maclean
222aa41bbf Merge pull request #13938 from hmac/splat-flow-2
Ruby: More precise flow into splat parameters
2023-08-18 12:07:58 +01:00
Erik Krogh Kristensen
08ef31d452 Merge pull request #13916 from erik-krogh/limit-java-field-reg
Java: limit field flow when tracking regex strings
2023-08-18 12:14:31 +02:00
Edward Minnix III
41a527cf72 Merge pull request #13934 from egregius313/egregius313/add-dashes-to-sha-algorithms
Java: Add dashes to SHA algorithm names in `Encryption.qll`
2023-08-17 13:03:15 -04:00
Paolo Tranquilli
700f383bab Merge pull request #13988 from github/redsun82/swift-version-macro
Swift: fix version check macro to be lexicographic
2023-08-17 15:34:04 +02:00
Anders Schack-Mulligen
e27aad9d6c Merge pull request #13987 from aschackmull/java/rangeanalysis-joinorder-fix
Java: Join-order fix in RangeAnalysis.
2023-08-17 14:47:26 +02:00
Mathias Vorreiter Pedersen
af7fe89c5a Merge pull request #13989 from MathiasVP/add-invalid-ptr-false-positive-3
C++: Add `cpp/invalid-pointer-deref` false positive
2023-08-17 12:50:55 +01:00
Mathias Vorreiter Pedersen
5f5a87e2c7 C++: Add false positive. 2023-08-17 12:13:16 +01:00
Paolo Tranquilli
75cc1d8f75 Swift: fix version check macro to be lexicographic 2023-08-17 12:19:28 +02:00
Anders Schack-Mulligen
f8a0b6cd22 Java: Add nomagic 2023-08-17 11:20:02 +02:00
Anders Schack-Mulligen
0afda68ba1 Java: Join-order fix in RangeAnalysis. 2023-08-17 11:07:24 +02:00
Tom Hvitved
7cc01ea8b5 Merge pull request #13595 from hvitved/csharp/use-shared-cfg-pack
C#: Adopt shared CFG construction library from shared `controlflow` pack
2023-08-17 10:37:09 +02:00
Tony Torralba
67c557115b Merge pull request #13915 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-08-17 10:03:04 +02:00
Tom Hvitved
fe0f766994 Merge pull request #13966 from hvitved/csharp/mad-repr-fix
C#: Fix `getMadRepresentationSpecific`
2023-08-17 09:40:41 +02:00
Tom Hvitved
da8005dbd3 Code review suggestions 2023-08-17 09:26:58 +02:00
github-actions[bot]
b0da1ef892 Add changed framework coverage reports 2023-08-17 00:14:13 +00:00
Ian Lynagh
1fb4e13e0a Merge pull request #13960 from igfoo/igfoo/parent
Kotlin: Handle Kotlin 2 parents better
2023-08-16 16:27:15 +01:00
Mathias Vorreiter Pedersen
e56cd0b498 Merge pull request #13984 from MathiasVP/fix-expected-for-swift
Swift: Fix expected files after a semantic merge conflict
2023-08-16 15:06:27 +01:00
yoff
7f2f6f14e7 Merge pull request #13729 from yoff/python/model-aws-lambdas
Python/JavaScript: Shared module for serverless functions
2023-08-16 15:14:08 +02:00
Mathias Vorreiter Pedersen
b2c7c57815 Swift: Fix expected files after a semantic merge conflict. 2023-08-16 13:52:06 +01:00
Mathias Vorreiter Pedersen
66d13dc0d5 Merge pull request #13981 from MathiasVP/fix-orig-delta-for-subtraction
C++: Fix original delta calculation for subtraction in new range analysis
2023-08-16 13:28:21 +01:00
Mathias Vorreiter Pedersen
20df63f26d C++: Respond to review comments. 2023-08-16 12:50:41 +01:00
Jeroen Ketema
591565a0db Merge pull request #13971 from jketema/float
C++: Update test after float128 related extractor changes
2023-08-16 13:11:35 +02:00
Mathias Vorreiter Pedersen
5e14b5cca7 C++: 'origDelta' should always be 'odLeft' when deriving subtraction ranges. 2023-08-16 12:10:31 +01:00
yoff
b2988e5516 Update python/ql/lib/change-notes/2023-08-07-serverless-sources.md
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-08-16 12:56:39 +02:00
Mathias Vorreiter Pedersen
986aa74db7 Merge pull request #13972 from MathiasVP/range-analysis-for-sub-expr
C++: Support subtraction in the new range analysis
2023-08-16 11:51:11 +01:00
Rasmus Wriedt Larsen
c55b0982f7 Merge pull request #13819 from yoff/python/relax-module-resolution
Python: Relax module resolution
2023-08-16 12:04:49 +02:00
Michael Nebel
365b10183f Merge pull request #13744 from tamasvajk/standalone/integration-test
C#: Add integration test for standalone extraction
2023-08-16 10:50:12 +02:00
Stephan Brandauer
20254c3d0a Merge pull request #13886 from github/kaeluka/java-automodel-variadic-args
Java: automodel application mode: use endpoint class like in framework mode
2023-08-16 08:49:01 +02:00
Ed Minnix
cafd08521e Add change note 2023-08-15 23:46:12 -04:00
Ed Minnix
7cfe78a52d Add dashes to SHA algorithm names in Encryption.qll 2023-08-15 23:42:17 -04:00
Jeroen Ketema
4ada83c0ba C++: Update test after float128 related extractor changes 2023-08-15 22:10:05 +02:00
Rasmus Lerchedahl Petersen
6614e037ae Python: format 2023-08-15 21:40:20 +02:00
Chris Smowton
b8372c2f95 Merge pull request #13973 from github/smowton/fix/go-version-comparison
Go: Don't warn when Go version exactly matches go.mod
2023-08-15 18:21:04 +01:00
Mathias Vorreiter Pedersen
49a5a39395 C++: Accept test changes. 2023-08-15 16:49:58 +01:00
Chris Smowton
3bcfbcdf68 Don't warn when Go version exactly matches go.mod
We had only previously tested this with e.g. installed go 1.20.5 >= go.mod request `go 1.20`; now we have go 1.21.0 which shouldn't elicit a warning because 1.21.0 is equal to the go.mod request `go 1.21`.
2023-08-15 16:49:42 +01:00
Paolo Tranquilli
234763efa6 Merge pull request #13959 from github/redsun82/cmake-fix
C++: make cmake generation work with internal rule `cc_binary_add_features`
2023-08-15 17:16:51 +02:00
Robert Marsh
3d20897725 Merge pull request #13910 from rdmarsh2/rdmarsh2/swift/for-await-cfg
Swift: CFG test for for-try-await
2023-08-15 11:16:07 -04:00
Mathias Vorreiter Pedersen
e145b81f58 C++: Accept test changes. 2023-08-15 16:12:44 +01:00
Mathias Vorreiter Pedersen
109e45e112 C++: Add precise range analysis for subtraction. 2023-08-15 16:12:40 +01:00
Mathias Vorreiter Pedersen
3fb024164b C++: Add a FP caused by bad range analysis for subtraction. 2023-08-15 16:00:35 +01:00
Mathias Vorreiter Pedersen
90888e592f Merge pull request #13965 from MathiasVP/better-certain-writes-and-invalid-ptr-deref-prep
C++: Remove more dataflow FPs after frontend upgrade
2023-08-15 15:43:55 +01:00
yoff
7eb41140ab Update python/ql/lib/semmle/python/Module.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-08-15 15:47:00 +02:00
Rasmus Lerchedahl Petersen
e6943ce98e Python: use standard test format 2023-08-15 15:26:18 +02:00
yoff
99bc050366 Update shared/yaml/codeql/serverless/ServerLess.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-08-15 15:09:30 +02:00
Kasper Svendsen
bb317bc558 Merge pull request #13968 from kaspersv/shadow-dbscheme
QL language specs: declarations can shadow dbscheme types and preds
2023-08-15 14:20:04 +02:00
Kasper Svendsen
30a813ab08 QL language specs: declarations can shadow dbscheme types and preds 2023-08-15 13:58:19 +02:00
Ian Lynagh
3b9bd16097 Kotlin: Mark some functions as private 2023-08-15 12:38:47 +01:00
Tom Hvitved
26b76171ca C#: Fix getMadRepresentationSpecific 2023-08-15 13:23:21 +02:00
Ian Lynagh
a8b69e5b55 Kotlin: Fix build on old versions 2023-08-15 11:30:23 +01:00
Mathias Vorreiter Pedersen
569f3c9b78 C++: Don't do indirect (instruction -> operand) flow when there's a store to the address in between the instruction and the operand. 2023-08-15 11:08:01 +01:00
Mathias Vorreiter Pedersen
f662cceb0b C++: Use value numbering to better detect whether a write is certain. 2023-08-15 11:07:14 +01:00
Rasmus Lerchedahl Petersen
8f70c9f950 Python: add comment about namespace packages 2023-08-15 12:02:02 +02:00
Tom Hvitved
44b734e120 Merge pull request #13955 from hvitved/ruby/type-tracking-capture-insensitive
Ruby: Make type tracking flow-insensitive for captured variables
2023-08-15 11:42:41 +02:00
Paolo Tranquilli
8e229ac31b Merge branch 'main' into redsun82/cmake-fix 2023-08-15 11:38:37 +02:00
Erik Krogh Kristensen
6a3b9e10eb Merge pull request #13914 from erik-krogh/escape-unicode
ReDoS: escape unicode chars in the output for the ReDoS queries
2023-08-15 11:21:21 +02:00
Mathias Vorreiter Pedersen
fec9626fe7 Merge pull request #13836 from github/alexdenisov/unresolved-dot-exprs
Swift: 'ParsedSequence' lacks proper types and yields 'Unresolved' AST nodes
2023-08-15 09:14:39 +01:00
Michael Nebel
a95aad51bd Merge pull request #13546 from michaelnebel/java/withoutelement
Java: Support for With[out]Element for MaD.
2023-08-15 10:03:03 +02:00
Rasmus Wriedt Larsen
d12743d7c3 Merge pull request #13941 from yoff/python/test-nice-location
Python: fix nice locations for import aliases
2023-08-14 21:37:23 +02:00
Tom Hvitved
061575ff77 Merge pull request #13937 from hvitved/ruby/for-loop-desugar
Ruby: Improve desugaring of `for` loops
2023-08-14 20:12:12 +02:00
Ian Lynagh
eb27428514 Kotlin: Handle IrExternalPackageFragment when dealing with external decls 2023-08-14 17:37:48 +01:00
Arthur Baars
77db0cf547 Merge pull request #13334 from aibaars/print-cfg-2
Ruby: printCfg: only show graph for selected CfgScope
2023-08-14 18:24:20 +02:00
Ian Lynagh
72af8ac1e2 Kotlin: Switch to useDeclarationParentOf
This lets us handle Kotlin 2 declarations whose parent is an
IrExternalPackageFragment, indicating that they are in a (multi)file
class.
2023-08-14 17:02:49 +01:00
Ian Lynagh
4f336820de Kotlin: Start handling IrExternalPackageFragment parents 2023-08-14 17:02:48 +01:00
Paolo Tranquilli
ef804c018d C++: make cmake generation work with internal rule cc_binary_add_features 2023-08-14 17:32:03 +02:00
Ian Lynagh
77451de9a3 Kotlin: Fix isExternalDeclaration for Kotlin 2 2023-08-14 15:01:13 +01:00
Mathias Vorreiter Pedersen
9359bea7b5 Merge pull request #13725 from MathiasVP/fix-barriers-in-invalid-pointer-deref
C++: Fix barriers in invalid pointer deref
2023-08-14 14:29:12 +01:00
Geoffrey White
5e940cd46f Merge pull request #13829 from geoffw0/typegetname
Swift: Correct the behaviour of Type.getName
2023-08-14 14:21:26 +01:00
Tom Hvitved
e96cbeb00a Ruby: Adjust locations of synthesized nodes 2023-08-14 14:37:47 +02:00
Tom Hvitved
c084a9b27a Ruby: Make type tracking flow-insensitive for captured variables 2023-08-14 13:44:37 +02:00
Harry Maclean
d45e9101ba Ruby: Add change note 2023-08-14 11:20:58 +01:00
Michael Nebel
0e9f8c4b97 Merge pull request #13876 from michaelnebel/csharp/aspnetdlls
C#: Include ASP.NET assemblies in the standalone extraction.
2023-08-14 11:53:47 +02:00
Geoffrey White
b6dc2acc71 Merge branch 'main' into typegetname 2023-08-14 10:46:14 +01:00
Mathias Vorreiter Pedersen
e2f671e327 C++: Add more comments. 2023-08-14 10:44:46 +01:00
Michael Nebel
6ecbb400d7 C#: Turn initialize into a readonly field. 2023-08-14 11:19:42 +02:00
Tamas Vajk
01af74aeda C#: Add space to CMD metacharacters 2023-08-14 11:19:17 +02:00
Tamas Vajk
3680681e8b C#: Add integration test for standalone extraction 2023-08-14 11:19:00 +02:00
Michael Nebel
d76bb49b6a C#: Make some FileContent unit tests. 2023-08-14 11:18:19 +02:00
Michael Nebel
a0bad3ce15 C#: Re-factor FileContent to make it unit-testable and make an initializer class. 2023-08-14 11:18:19 +02:00
Michael Nebel
a362ce083d C#: Some file content regexp tweaking. 2023-08-14 11:18:19 +02:00
Michael Nebel
c95d219c84 C#: Re-factor the processing of all files into a helper class and make sure to only do one pass of the files. 2023-08-14 11:18:19 +02:00
Michael Nebel
db685e5fc4 C#: Tidy up. 2023-08-14 11:18:19 +02:00
Michael Nebel
e24fa4705a C#: Introduce caching or detecting the newest runtimes and fetching all file names in the source dir. 2023-08-14 11:18:19 +02:00
Michael Nebel
ddb50b8120 C#: Improve regular expressions and fix lowercase issue. 2023-08-14 11:18:19 +02:00
Michael Nebel
ca7fa2e7c8 C#: Use ASP.NET dlls when needed and available. 2023-08-14 11:18:19 +02:00
Michael Nebel
b71c41018c C#: Re-factor the GetRuntime method. 2023-08-14 11:18:19 +02:00
Michael Nebel
5bc8804242 C#: Introduce method to decide whether we need to include ASP.NET dlls in standalone compilation. 2023-08-14 11:18:19 +02:00
Michael Nebel
88b51e6ad3 C#: Re-factor logic for fetching info from group and remove a redundant continue statement. 2023-08-14 11:18:18 +02:00
Michael Nebel
881d86321e C#: Introduce regex for framework reference and project sdk and make some minor re-writes. 2023-08-14 11:18:18 +02:00
Michael Nebel
f5d776571b Merge pull request #13952 from michaelnebel/csharp/runtimewhitespacefix
C#: .NET Runtime path detection (bugfix).
2023-08-14 11:17:27 +02:00
Mathias Vorreiter Pedersen
df9c756369 C++: Add more comments. 2023-08-14 10:09:27 +01:00
yoff
d2a0b9a66c Update python/ql/lib/change-notes/2023-08-10-fix-alias-locations.md
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-08-14 10:55:00 +02:00
Mathias Vorreiter Pedersen
c265113073 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-08-14 09:51:28 +01:00
Harry Maclean
ca5456a54a Ruby: Remove duplicate disjuncts 2023-08-14 09:45:57 +01:00
Michael Nebel
9e03a211a5 C#: Add unit test where path to dotnet frameworks contain whitespaces. 2023-08-14 10:40:00 +02:00
Michael Nebel
1942ea8396 C#: Paths can contain whitespace (this is indeed common on windows). 2023-08-14 10:40:00 +02:00
Michael Nebel
280a27d9ca C#: Log some more info during dotnet --list-runtimes execution. 2023-08-14 10:40:00 +02:00
Michael Nebel
78c732db97 C#: Re-factor of ProgressMonitor and introduce LogInfo. 2023-08-14 10:40:00 +02:00
Michael Nebel
ef9453e862 C#: Selected runtime location should be logged as information. 2023-08-14 10:40:00 +02:00
yoff
307f44339c Update python/ql/lib/change-notes/2023-08-08-relax-module-resolution.md
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-08-14 10:23:47 +02:00
Stephan Brandauer
1a95a34441 Java: automodel: use the call for call context, rather than the argument 2023-08-14 09:54:44 +02:00
Stephan Brandauer
4107758c8a Java: automodel extraction: add strings to query selection 2023-08-14 09:49:50 +02:00
Mathias Vorreiter Pedersen
2c6bbd8060 C++: Replace 'left' with 'small' and 'right' with 'large' for consistency. 2023-08-13 22:53:41 +01:00
Robert Marsh
7053c62c41 Swift: update and sync tests 2023-08-11 18:52:37 +00:00
Henry Mercer
75e6fd9c8e Merge pull request #13918 from github/post-release-prep/codeql-cli-2.14.2
Post-release preparation for codeql-cli-2.14.2
2023-08-11 16:28:16 +01:00
Mathias Vorreiter Pedersen
efe3c0d34a C++: Rename n' to m. 2023-08-11 15:24:08 +01:00
Harry Maclean
6011d26823 Ruby: Restrict parameter nodes 2023-08-11 15:14:32 +01:00
Tom Hvitved
e39fb093e9 Merge pull request #13945 from hvitved/ruby/destruct-param-test
Ruby: Add test for documenting missing flow through destructured parameters
2023-08-11 15:11:39 +02:00
Mathias Vorreiter Pedersen
f4e6deeee0 C++: Remove 'ValidForStateConfig'. 2023-08-11 13:57:59 +01:00
Henry Mercer
1213eba630 Merge branch 'main' into post-release-prep/codeql-cli-2.14.2 2023-08-11 13:54:55 +01:00
Ian Lynagh
5161cd1a3c Merge pull request #13944 from igfoo/igfoo/getFunctionLabel
Kotlin: Handle null parent IDs in getFunctionLabel correctly
2023-08-11 12:28:32 +01:00
Mathias Vorreiter Pedersen
2164069eda C++: Add another testcase. 2023-08-11 12:00:43 +01:00
Mathias Vorreiter Pedersen
88d3fcb34b C++: Fix comment. 2023-08-11 11:50:50 +01:00
Mathias Vorreiter Pedersen
3d5b1986c9 C++: Fix a bug where 'boundedImpl' could give back multiple deltas. 2023-08-11 11:46:28 +01:00
Mathias Vorreiter Pedersen
c0a54e90c9 C++: Fix an inequality that should be strict, but wasn't. 2023-08-11 11:43:55 +01:00
Tom Hvitved
c95b58673a Merge pull request #13939 from hvitved/ruby/captured-access-fix2
Ruby: Fix another bug in `isCapturedAccess`
2023-08-11 12:28:39 +02:00
Michael B. Gale
9f51f6f7ac Merge pull request #13948 from github/mbg/go/fix-compare-identical-values-arm64
Make `CompareIdenticalValues` test work on arm64
2023-08-11 11:22:49 +01:00
Michael B. Gale
13d4bd9c0a Make CompareIdenticalValues test work on arm64 2023-08-11 10:51:52 +01:00
Owen Mansel-Chan
c10d03e74e Merge pull request #13820 from owen-mc/go/refactor-data-flow-configurations
Go: Make flow configurations use new data flow API
2023-08-11 10:49:51 +01:00
Owen Mansel-Chan
35a300f894 Apply suggestions from code review
Co-authored-by: Michael B. Gale <mbg@github.com>
2023-08-11 10:06:14 +01:00
Owen Mansel-Chan
b7dfa2347c Put QLDoc on data flow and taint tracking modules
We preserve all old QLDocs, but move them from the
config to the Flow module. This makes more sense than
the Config module, which is often private, and is generally
not directly accessed.
2023-08-11 10:06:12 +01:00
Stephan Brandauer
a9906f6f7b Java: fix - add extra $@
Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com>
2023-08-11 09:15:09 +02:00
Rasmus Lerchedahl Petersen
3457f23db5 Python: Add change note 2023-08-10 20:53:43 +02:00
Rasmus Lerchedahl Petersen
e5cd3e8f64 Python: nice locations for import aliases
These were computed wrongly before.
2023-08-10 20:27:06 +02:00
Tom Hvitved
b28f60ccd2 Ruby: Add test for documenting missing flow through destructured parameters 2023-08-10 20:22:11 +02:00
Robert Marsh
36bdadfc36 Merge pull request #13933 from geoffw0/madtuples
Swift: Models-as-data support for tuple content
2023-08-10 14:17:45 -04:00
Ian Lynagh
58da62e244 Kotlin: Handle null parent IDs in getFunctionLabel correctly 2023-08-10 18:49:10 +01:00
Erik Krogh Kristensen
3e2c6d69f9 Merge pull request #13940 from erik-krogh/rate-default
JS: change the defaults in the qhelp for missing-rate-limit to something more reasonable
2023-08-10 19:25:33 +02:00
Owen Mansel-Chan
08e1e8a120 Improve inaccurate deprecation comments 2023-08-10 15:50:08 +01:00
Owen Mansel-Chan
94c15f712a Remove unnecessary fieldFlowBranchLimit 2023-08-10 15:50:06 +01:00
Owen Mansel-Chan
0928fa6e1f Give MyFlowstate a less generic name 2023-08-10 15:50:05 +01:00
Owen Mansel-Chan
36b1a0dc54 Update for recent changes to DsnInjection 2023-08-10 15:50:03 +01:00
Owen Mansel-Chan
2578ef4786 Remove output from running query like a test 2023-08-10 15:50:02 +01:00
Owen Mansel-Chan
089ea010d7 Improve QLDoc for Config::FlowState in StringBreak 2023-08-10 15:50:01 +01:00
Owen Mansel-Chan
e33d303b48 Do not make unnecessary changes 2023-08-10 15:49:59 +01:00
Owen Mansel-Chan
e6c8a0b653 Use more descriptive names for merged path graphs 2023-08-10 15:49:58 +01:00
Owen Mansel-Chan
6b4bf12316 Revert edit to deprecated class 2023-08-10 15:49:57 +01:00
Owen Mansel-Chan
039925164d Keep newline at the end of identical-files.json
VS Code's JSON formatter removed it automatically. It turns out
that the easiest way to keep it is to use the
`files.insertFinalNewline` setting, which the JSON formatter obeys.
2023-08-10 15:49:55 +01:00
Owen Mansel-Chan
046e517c3f Remove unnecessary import 2023-08-10 15:49:54 +01:00
Owen Mansel-Chan
81d4149a17 Note deprecation in QLDoc for LogInjection 2023-08-10 15:49:52 +01:00
Owen Mansel-Chan
b6b7e1589c Make taint tracking tests use new API 2023-08-10 15:49:51 +01:00
Owen Mansel-Chan
c11da5bf67 Make taint tracking tests use InlineFlowTest 2023-08-10 15:49:50 +01:00
Owen Mansel-Chan
663fb2cc06 Make taint tracking tests use config from InlineFlowTest 2023-08-10 15:49:48 +01:00
Owen Mansel-Chan
8db3e4a9b4 Make IncorrectIntegerConversion use new API 2023-08-10 15:49:47 +01:00
Owen Mansel-Chan
6c0c8d6963 Make BadRedirectCheck use new API 2023-08-10 15:49:45 +01:00
Owen Mansel-Chan
442dfc1833 Make InsecureTLS use new API 2023-08-10 15:49:44 +01:00
Owen Mansel-Chan
b00e44725c Make CorsMisconfiguration use new API 2023-08-10 15:49:43 +01:00
Owen Mansel-Chan
9b19cde8ab Make SensitiveConditionBypass use new API 2023-08-10 15:49:42 +01:00
Owen Mansel-Chan
2d3d21d074 Make StackTraceExposure use new API 2023-08-10 15:49:40 +01:00
Owen Mansel-Chan
d9844bd4d6 Make WrongUsageOfUnsafe use new API 2023-08-10 15:49:39 +01:00
Owen Mansel-Chan
00ea023fdb Make ConditionalBypass use new API 2023-08-10 15:49:37 +01:00
Owen Mansel-Chan
1b4fef9c21 Make HTMLTemplateEscapingPassthrough use new API
Removed edges and nodes are mostly duplicates. They were only there
originally due to multiple configurations being in scope.
`DataFlow::PathNode` has union semantics for configurations. Nodes are
only generated if they are reachable from a source, but this includes
sources from other configurations.

No alerts are lost.
2023-08-10 15:49:36 +01:00
Owen Mansel-Chan
ea1f39683d Make DivideByZero use new API
The extra nodes in .expected files are due to the changes from
https://github.com/github/codeql/pull/13717, which are not applied to
configuration classes extending DataFlow::Configuration or
TaintTracking::Configuration.
2023-08-10 15:49:35 +01:00
Owen Mansel-Chan
045936b1fd Make PamAuthBypass use new API 2023-08-10 15:49:33 +01:00
Owen Mansel-Chan
cfc4a6a6b7 Make Timing use new API 2023-08-10 15:49:32 +01:00
Owen Mansel-Chan
39762da5e0 Make DsnInjection use new API 2023-08-10 15:49:31 +01:00
Owen Mansel-Chan
a53da376d1 Make LDAPInjection use new API 2023-08-10 15:49:29 +01:00
Owen Mansel-Chan
f60ca76eb2 Make EmailInjection use new API 2023-08-10 15:49:28 +01:00
Owen Mansel-Chan
1962aa3de4 Make SSRF use new API 2023-08-10 15:49:27 +01:00
Owen Mansel-Chan
71735c86c2 Make WeakCryptoAlgorithm use new API 2023-08-10 15:49:25 +01:00
Owen Mansel-Chan
46185e3a02 Make HardcodedKeys use new API 2023-08-10 15:49:24 +01:00
Owen Mansel-Chan
b5ac0c94c6 Make ZipSlip use new API 2023-08-10 15:49:23 +01:00
Owen Mansel-Chan
7341b6156d Make XPathInjection use new API 2023-08-10 15:49:21 +01:00
Owen Mansel-Chan
a6177b3c92 Make UnsafeUnzipSymlink use new API 2023-08-10 15:49:20 +01:00
Owen Mansel-Chan
7db1daba6e Make TaintedPath use new API 2023-08-10 15:49:19 +01:00
Owen Mansel-Chan
6c91f77776 Make StringBreak use new API 2023-08-10 15:49:17 +01:00
Owen Mansel-Chan
30ae34352b Make StoredXss use new API 2023-08-10 15:49:16 +01:00
Owen Mansel-Chan
4334a51cf3 Make StoredCommand use new API 2023-08-10 15:49:15 +01:00
Owen Mansel-Chan
ac1670c0af Make SqlInjection use new API
The extra nodes in .expected files are due to the changes from
https://github.com/github/codeql/pull/13717, which are not applied to
configuration classes extending DataFlow::Configuration or
TaintTracking::Configuration.
2023-08-10 15:49:13 +01:00
Owen Mansel-Chan
646e158813 Make tests use config from InlineFlowTest
For InterProceduralDataFlow, it's hard to get it to use InlineFlowTest
because you need to show both the source and the sink, and there are
problems with quoting when the source is already surrounded by quotes.
2023-08-10 15:49:12 +01:00
Owen Mansel-Chan
81854279bd Make tests use InlineFlowTest 2023-08-10 15:49:11 +01:00
Owen Mansel-Chan
d385113e11 Make InsufficientKeySize use new API 2023-08-10 15:49:09 +01:00
Owen Mansel-Chan
16ef11a3c3 Make ConstantOauth2State use new API
Removed edges were only there originally due to multiple configurations
being in scope. `DataFlow::PathNode` has union semantics for
configurations. Nodes are only generated if they are reachable from a
source, but this includes sources from other configurations.

No alerts are lost.
2023-08-10 15:49:08 +01:00
Owen Mansel-Chan
fbd0c4edd0 Make HostKeyCallbackAssignment use new API 2023-08-10 15:49:07 +01:00
Owen Mansel-Chan
a1a31bfd62 Make SuspiciousCharacterInRegexp use new API 2023-08-10 15:49:05 +01:00
Owen Mansel-Chan
8f644af769 Make MissingRegexpAnchor use new API 2023-08-10 15:49:04 +01:00
Owen Mansel-Chan
442f6875f5 Make IncompleteHostNameRegexp use new API 2023-08-10 15:49:03 +01:00
Owen Mansel-Chan
0e1383ddd7 Make UnhandledFileCloseWritableHandle use new API 2023-08-10 15:49:01 +01:00
Owen Mansel-Chan
00cc78dfe6 Make CookieWithoutHttpOnly use new API
The extra nodes in .expected files are due to the changes from
https://github.com/github/codeql/pull/13717, which are not applied to
configuration classes extending DataFlow::Configuration or
TaintTracking::Configuration.
2023-08-10 15:49:00 +01:00
Owen Mansel-Chan
a7382e06c2 Make ClearTextLogging use new API
The extra nodes in .expected files are due to the changes from
https://github.com/github/codeql/pull/13717, which are not applied to
configuration classes extending DataFlow::Configuration or
TaintTracking::Configuration.
2023-08-10 15:48:59 +01:00
Owen Mansel-Chan
653563fcbc Make StringsNewReplacer use new API
We don't have to keep a deprecated copy as this is private. This allows
us to delete a copy of the DataFlow library!
2023-08-10 15:48:57 +01:00
Owen Mansel-Chan
1f6cdc7eda Make OpenURLRedirect use new API
The extra nodes in .expected files are due to the changes from
https://github.com/github/codeql/pull/13717, which are not applied to
configuration classes extending DataFlow::Configuration or
TaintTracking::Configuration.

Removed nodes and edges were only there originally due to multiple
configurations being in scope. `DataFlow::PathNode` has union semantics
for configurations. Nodes are only generated if they are reachable from
a source, but this includes sources from other configurations.
2023-08-10 15:48:55 +01:00
Owen Mansel-Chan
d2a5d19439 Make SafeUrlFlow use new API 2023-08-10 15:48:54 +01:00
Owen Mansel-Chan
97c32970a0 Make RequestForgery use new API
The extra nodes in .expected files are due to the changes from
https://github.com/github/codeql/pull/13717, which are not applied to
configuration classes extending DataFlow::Configuration or
TaintTracking::Configuration.
2023-08-10 15:48:53 +01:00
Owen Mansel-Chan
1c2536321c Make ReflectedXss use new API 2023-08-10 15:48:51 +01:00
Owen Mansel-Chan
3d9f8d50bc Make InsecureRandomness use new API 2023-08-10 15:48:50 +01:00
Michael B. Gale
87c089e0a8 Make CommandInjection.qll use new API
The new `edges` and `nodes` sections in the .expected files are because
the PathGraph module was not imported in the tests before, and thus
these query predicates were not in scope.
2023-08-10 15:48:48 +01:00
Michael B. Gale
957757c271 Make UntrustedDataToUnknownExternalAPI use new API 2023-08-10 15:48:47 +01:00
Michael B. Gale
d6919dd57b Make UntrustedDataToExternalAPI use new API 2023-08-10 15:48:46 +01:00
Michael B. Gale
82a1b15d11 Make AllocationSizeOverflow use new API
The extra nodes in .expected files are due to the changes from
https://github.com/github/codeql/pull/13717, which are not applied to
configuration classes extending DataFlow::Configuration or
TaintTracking::Configuration.
2023-08-10 15:48:44 +01:00
Tom Hvitved
5a6ce293cc Merge pull request #13942 from hvitved/dataflow/variable-capture-consistency-fix 2023-08-10 16:20:28 +02:00
Tom Hvitved
9b38028e25 Data flow: Fix localWriteStep consistency query 2023-08-10 15:31:04 +02:00
Mathias Vorreiter Pedersen
9aae174942 C++: Move conjunct below comment. 2023-08-10 13:58:07 +01:00
Michael Nebel
f6aca58dbb Merge pull request #13885 from michaelnebel/csharp/linqforeach
C#: LINQ recommendation queries.
2023-08-10 14:55:11 +02:00
Rasmus Lerchedahl Petersen
eac44e89d9 Python: test nice locations
there are errors both on lines 2 and 3 due to
locations being computed wrongly.
2023-08-10 14:21:16 +02:00
Mathias Vorreiter Pedersen
6d949cbd39 C++: Rename 'getAFlowStateForNode' to 'getASizeAddend'. 2023-08-10 13:19:28 +01:00
Mathias Vorreiter Pedersen
a2b8eb924e C++: Remove the '+ 1' in 'getAFlowStateForNode'. 2023-08-10 13:17:47 +01:00
Mathias Vorreiter Pedersen
f9fc79b16f Merge pull request #13930 from geoffw0/uitextinput
Swift: Flow sources for UITextInput
2023-08-10 13:05:47 +01:00
Tom Hvitved
f19232f800 Ruby: Fix another bug in isCapturedAccess 2023-08-10 14:02:58 +02:00
erik-krogh
5ffce86768 change the defaults in the qhelp for missing-rate-limit to something more reasonable 2023-08-10 13:40:17 +02:00
Harry Maclean
b365ff095a Ruby: Fix SynthSplatParameterElementNode
Make this class into a proper subclass of `ParameterNodeImpl`, to
prevent some consistency test failures.
2023-08-10 12:35:12 +01:00
Tom Hvitved
77fca277fe Ruby: Improve desugaring of for loops 2023-08-10 13:22:01 +02:00
Ian Lynagh
f377d25c23 Merge pull request #13919 from igfoo/igfoo/useFunction
Kotlin: useFunction might return null
2023-08-10 12:17:20 +01:00
Tom Hvitved
4e954c29a2 Merge pull request #13936 from hvitved/ruby/captured-access-fix
Ruby: Fix bug in `isCapturedAccess`
2023-08-10 13:15:48 +02:00
Tom Hvitved
b99b6b85ba Merge pull request #13927 from hvitved/csharp/fix-bad-join
C#: Fix bad join order
2023-08-10 13:04:16 +02:00
Harry Maclean
5fff9fa8da More precise flow into splat parameters
We now precisely track flow from positional arguments to splat
parameters, provided that splat arguments are not used and there are no
positional parameters after the splat parameter. For example, in this
case:

    def f(x, y, *z); end

    f(a, b, c, d)

we get flow from `c` to `z[0]` and `d` to `z[1]`.

We get false flow if there are positional parameters after the splat
parameter. For example in this case:

    def g(x, y, *z, w); end

    g(a, b, c, d)

we get flow from `d` to `z[0]` instead of `w`.

We also track flow in this case

    def f(a, *b)
      sink b[0]
    end

    f(1, *[taint, 2])
2023-08-10 12:02:47 +01:00
Harry Maclean
a58aa17c7a Merge pull request #13878 from hmac/splat-flow
Ruby: Track flow from splat arguments to positional parameters
2023-08-10 12:01:38 +01:00
Mathias Vorreiter Pedersen
1455e8bd4c C++: Convert all '<'s to '<='s. 2023-08-10 11:55:57 +01:00
Mathias Vorreiter Pedersen
dcc1429ed8 C++: Get rid of '+ 1' in comments. 2023-08-10 11:38:40 +01:00
Mathias Vorreiter Pedersen
b750016bc1 C++: Fix more comments. 2023-08-10 11:31:30 +01:00
Jeroen Ketema
2e338cc7b4 Merge pull request #13929 from jketema/buffer
C++: Only consider the maximum buffer size for badly bounded write
2023-08-10 10:40:37 +02:00
Tom Hvitved
e40f0a7350 Ruby: Fix bug in isCapturedAccess 2023-08-10 09:37:04 +02:00
Tom Hvitved
e7acf8c3a8 Ruby: Add test 2023-08-10 08:53:00 +02:00
github-actions[bot]
432c21d4fb Post-release preparation for codeql-cli-2.14.2 2023-08-09 18:45:18 +00:00
Mathias Vorreiter Pedersen
ce9b018789 C++: Move bounds checkout out of 'operandGuardChecks' for clarity. 2023-08-09 18:37:17 +01:00
Geoffrey White
c20a17e7b7 Swift: Update the consistency test .expecteted as well. 2023-08-09 15:47:28 +01:00
Rasmus Wriedt Larsen
51a05286fa Merge pull request #13731 from pwntester/py/aiohttp_improvements
Python: Aiohttp improvements
2023-08-09 16:37:20 +02:00
Geoffrey White
23f0dd5542 Swift: Support MAD tuple content flow. 2023-08-09 15:08:11 +01:00
Harry Maclean
b03f6efa60 Ruby: Refactor 2023-08-09 15:01:40 +01:00
Harry Maclean
142393b599 Ruby: Handle unknown content in splat flow 2023-08-09 15:01:40 +01:00
Harry Maclean
4239268efd Ruby: Prevent some false flow into splat params
In cases where there are positional parameters after a splat parameter,
don't attempt to match the splat parameter to a splat argument. We need
more sophisticated modelling to handle these cases, which is future
work.
2023-08-09 15:01:40 +01:00
Harry Maclean
6f3e2cdde3 Ruby: Add change note 2023-08-09 15:01:40 +01:00
Harry Maclean
c0baa5116f Ruby: add test for example splat arg/param matches 2023-08-09 15:01:40 +01:00
Harry Maclean
72356d1515 Ruby: track flow from *args to positional params
This models flow in the following case:

    def foo(x, y)
      sink x # 1
      sink y # 2
    end

    args = [source 1, source 2]
    foo(*args)

We do this by introducing a SynthSplatParameterNode which accepts
content from the splat argument, if one is given at the callsite.
From this node we add read steps to each positional parameter.
2023-08-09 15:01:40 +01:00
Jeroen Ketema
e04d30a676 C++: Update expected test changes due to the line in test2.cpp having shifted 2023-08-09 15:50:07 +02:00
Jeroen Ketema
6100425274 C++: Add change note 2023-08-09 15:47:19 +02:00
Geoffrey White
b4b2338144 Swift: Test for MAD tuple content flow. 2023-08-09 14:41:32 +01:00
Jeroen Ketema
6d7a75d1b9 Merge pull request #13931 from MathiasVP/revert-constant-bounds-and-prep
C++: Revert constant bounds for new range analysis
2023-08-09 15:39:53 +02:00
Mathias Vorreiter Pedersen
8a490775d8 Merge branch 'main' into fix-barriers-in-invalid-pointer-deref 2023-08-09 14:32:58 +01:00
Ian Lynagh
0eb6d1c76e Kotlin: useFunction might return null 2023-08-09 13:45:15 +01:00
Mathias Vorreiter Pedersen
acd16afddd Revert "Merge pull request #13880 from MathiasVP/type-bounds-preparation"
This reverts commit 3e9d9e72dc, reversing
changes made to 877ee7047d.
2023-08-09 13:03:06 +01:00
Mathias Vorreiter Pedersen
cb1076c335 Revert "Merge pull request #13783 from MathiasVP/type-bounds-for-new-range-analysis"
This reverts commit e9750af89f, reversing
changes made to 37a546253e.
2023-08-09 13:02:54 +01:00
erik-krogh
fe542565c3 fix performance 2023-08-09 13:48:07 +02:00
Michael B. Gale
01ff690d51 Merge pull request #13923 from github/mbg/go/bump-go-libraries 2023-08-09 11:36:35 +01:00
Mathias Vorreiter Pedersen
da66136ded Merge pull request #13911 from MathiasVP/fix-taint-for-frontend-upgrade
C++: Fix taint-flow in preparation for frontend upgrade
2023-08-09 11:30:07 +01:00
Jeroen Ketema
d0e7354a1b C++: Only consider the maximum buffer size for badly bounded write 2023-08-09 12:30:00 +02:00
Jeroen Ketema
9572b9d308 C++: Add test where buffer initialized with literal is reassigned an allocation 2023-08-09 12:26:10 +02:00
Rasmus Wriedt Larsen
c0dec21546 Merge pull request #13925 from RasmusWL/fixup-script
Misc: Fixup `accept-expected-changes-from-ci.py`
2023-08-09 11:45:34 +02:00
Tom Hvitved
7dac819730 C#: Fix bad join order
Before
```
Evaluated recursive predicate Stmt#3baf294a::TryStmt::getATriedElement#ff@8254eapb in 6096ms on iteration 4 (delta size: 592145).
Evaluated relational algebra for predicate Stmt#3baf294a::TryStmt::getATriedElement#ff@8254eapb on iteration 4 running pipeline standard with tuple counts:
          204507  ~0%    {2} r1 = SCAN Stmt#3baf294a::TryStmt::getATriedElement#ff#prev_delta OUTPUT In.1, In.0
          204507  ~0%    {3} r2 = JOIN r1 WITH _@callable#f_ControlFlowElement#9501aa28::ControlFlowElement::getEnclosingCallable#0#dispred#ff_10#j__#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.0, Lhs.1
        17844283  ~0%    {3} r3 = JOIN r2 WITH ControlFlowElement#9501aa28::ControlFlowElement::getEnclosingCallable#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2
          592145  ~0%    {2} r4 = JOIN r3 WITH Element#baf0c59e::Element::getAChild#0#dispred#ff ON FIRST 2 OUTPUT Lhs.2, Lhs.1
          592145  ~0%    {2} r5 = r4 AND NOT Stmt#3baf294a::TryStmt::getATriedElement#ff#prev(Lhs.0, Lhs.1)
                         return r5
```

After
```
Evaluated recursive predicate Stmt#3baf294a::TryStmt::getATriedElement#ff@4adecd47 in 310ms on iteration 4 (delta size: 592145).
Evaluated relational algebra for predicate Stmt#3baf294a::TryStmt::getATriedElement#ff@4adecd47 on iteration 4 running pipeline standard with tuple counts:
        204507  ~0%    {2} r1 = SCAN Stmt#3baf294a::TryStmt::getATriedElement#ff#prev_delta OUTPUT In.1, In.0
        204507  ~0%    {2} r2 = r1 AND NOT _statements_10#join_rhs#antijoin_rhs#13(Lhs.0)
        592145  ~2%    {3} r3 = JOIN r2 WITH Element#baf0c59e::Element::getAChild#0#dispred#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Rhs.1
        592145  ~0%    {3} r4 = JOIN r3 WITH ControlFlowElement#9501aa28::ControlFlowElement::getEnclosingCallable#0#dispred#ff ON FIRST 1 OUTPUT Lhs.2, Rhs.1, Lhs.1
        592145  ~0%    {2} r5 = JOIN r4 WITH ControlFlowElement#9501aa28::ControlFlowElement::getEnclosingCallable#0#dispred#ff ON FIRST 2 OUTPUT Lhs.2, Lhs.0
        592145  ~0%    {2} r6 = r5 AND NOT Stmt#3baf294a::TryStmt::getATriedElement#ff#prev(Lhs.0, Lhs.1)
                       return r6
```
2023-08-09 11:28:06 +02:00
AlexDenisov
6e8f600cb9 Merge pull request #13924 from github/alexdenisov/cherry-pick-reverted-pr
Revert "Swift: Route compiler diagnostics through our log."
2023-08-09 11:02:19 +02:00
Rasmus Wriedt Larsen
69aa099ed1 Misc: Fixup accept-expected-changes-from-ci.py
I guess there has been a rename of the URL from `/jobs/` to `/job/`, since the script has been working previously.
2023-08-09 10:44:31 +02:00
Geoffrey White
e828d8dace Swift: Add UIKit to supported-frameworks.rst as well. 2023-08-09 09:25:43 +01:00
Geoffrey White
131b2b3e0c Swift: Change note. 2023-08-09 09:25:43 +01:00
Geoffrey White
09346c76e7 Swift: Add models. 2023-08-09 09:25:43 +01:00
AlexDenisov
fa729faa0a Revert "Swift: Route compiler diagnostics through our log." 2023-08-09 10:02:59 +02:00
Mathias Vorreiter Pedersen
499b6f35e5 C++: Also key SSA defs and uses by the base address. 2023-08-09 08:44:16 +01:00
Mathias Vorreiter Pedersen
e2feed78a0 C++: Generate SSA variables for all calls instead of just for calls to
allocators.
2023-08-09 08:44:10 +01:00
Stephan Brandauer
e927470961 Merge branch 'main' into kaeluka/java-automodel-variadic-args 2023-08-09 09:02:32 +02:00
Michael Nebel
560b876c01 Merge pull request #13891 from felickz/csharp-hardcoded-cred-identity-fp
cs/hardcoded-credentials - Removes false positive matches on benign Microsoft.AspNetCore.Identity properties
2023-08-09 08:32:36 +02:00
Chad Bentz
fa23a45f9d Merge branch 'main' into csharp-hardcoded-cred-identity-fp 2023-08-08 17:48:27 -04:00
Geoffrey White
cb6aed18f3 Swift: Add tests. 2023-08-08 22:29:53 +01:00
Michael B. Gale
9da749ad77 Bump Go extractor dependencies 2023-08-08 22:23:47 +01:00
erik-krogh
0bce42410a support arbitrary codepoints in NfaUtils.qll 2023-08-08 22:14:51 +02:00
erik-krogh
859e1bfabc add constraint that i should be between 0 and 65535 2023-08-08 21:11:59 +02:00
Mathias Vorreiter Pedersen
389294bded Merge pull request #13920 from MathiasVP/fix-out-nodes
C++: Remove unnecessary predicates
2023-08-08 20:11:36 +01:00
erik-krogh
0391e063ca move to4digitHex to Numbers.qll 2023-08-08 21:10:58 +02:00
Geoffrey White
a1234d4235 Merge pull request #13905 from geoffw0/forceunwrap
Swift: Flow through ForceValueExpr on LHS of assignment
2023-08-08 18:36:50 +01:00
Mathias Vorreiter Pedersen
2a1d5b7481 Merge branch 'main' into fix-out-nodes 2023-08-08 16:32:03 +01:00
Geoffrey White
2b0fcab182 Swift: Update test annotations following merge. 2023-08-08 16:06:52 +01:00
Geoffrey White
e9f0b535ea Merge branch 'main' into forceunwrap 2023-08-08 16:03:31 +01:00
Anders Schack-Mulligen
0ca3f3308b Merge pull request #13478 from aschackmull/java/varcapture
Java: Add proper support for variable capture flow.
2023-08-08 16:22:56 +02:00
Anders Starcke Henriksen
7da6da1c93 Merge pull request #13852 from github/starcke/automodel-package-filter
Add option to filter automodel queries
2023-08-08 14:59:00 +02:00
Alex Denisov
cebaca328e Swift: 'ParsedSequence' lacks proper types and yields 'Unresolved' AST nodes 2023-08-08 14:41:15 +02:00
Anders Schack-Mulligen
1cd32722be Java: More review fixes. 2023-08-08 14:32:48 +02:00
Mathias Vorreiter Pedersen
f4f5d43bcb C++: indirectReturnOutNodeOperand0 and indirectReturnOutNodeInstruction0
were broken and for some reason only handled the case where calls mapped
to raw indirect nodes :wat:. It turns out these predicates weren't
actually needed anyway.
2023-08-08 13:23:10 +01:00
Alexandre Boulgakov
28863f39b0 Merge pull request #13917 from github/revert-13869-sashabu/swift-logging-compiler
Revert "Swift: Route compiler diagnostics through our log."
2023-08-08 12:45:58 +01:00
Anders Schack-Mulligen
9d59f50340 Java: Review fixes. 2023-08-08 13:37:40 +02:00
Rasmus Lerchedahl Petersen
e47e77c438 Python: add change note 2023-08-08 12:17:23 +02:00
Rasmus Lerchedahl Petersen
f33aff42ad Python: missing result was fixed 2023-08-08 12:14:57 +02:00
AlexDenisov
75dad4764f Revert "Swift: Route compiler diagnostics through our log." 2023-08-08 11:25:13 +02:00
Rasmus Lerchedahl Petersen
f865fa3050 Python: simplify using getSubscript 2023-08-08 11:16:35 +02:00
Michael Nebel
0ed724eb13 Java: Make a flow summary for Set.clear using WithoutElement and introduce appropriate tests. 2023-08-08 11:10:08 +02:00
Rasmus Wriedt Larsen
4f47461f60 Python: Add requested test 2023-08-08 10:44:48 +02:00
Michael Nebel
f67d5e1dc6 C#: Add tests for the LINQ missed-where and missed-cast queries. 2023-08-08 10:32:16 +02:00
Michael Nebel
1a511c2d52 C#: Update the queries that provide LINQ recommendation. 2023-08-08 10:31:33 +02:00
Anders Schack-Mulligen
ab334f6c1b Java: Always apply heuristic query regardless of existing models. 2023-08-08 10:01:43 +02:00
Anders Schack-Mulligen
cd22bb3505 Java: Add another test case. 2023-08-08 10:00:55 +02:00
erik-krogh
03fbd387df way better hex conversion 2023-08-08 09:08:39 +02:00
erik-krogh
45c39e6072 limit field flow when tracking regex strings in Java 2023-08-08 09:01:23 +02:00
erik-krogh
92db7b047c escape unicode chars in the output for the ReDoS queries 2023-08-08 00:15:54 +02:00
Henry Mercer
0673b19ce1 Merge pull request #13912 from github/release-prep/2.14.2
Release preparation for version 2.14.2
2023-08-07 21:24:56 +01:00
Chad Bentz
d4b5a4d4f4 Merge branch 'main' into csharp-hardcoded-cred-identity-fp 2023-08-07 15:09:01 -04:00
Chad Bentz
7b33574b85 pull dependencies from Microsoft.AspNetCore.App 2023-08-07 18:45:16 +00:00
Geoffrey White
022a06659c Merge pull request #13838 from rdmarsh2/rdmarsh2/swift/set-content
Swift: add SetContent for data flow
2023-08-07 19:15:30 +01:00
github-actions[bot]
79c90fa36a Release preparation for version 2.14.2 2023-08-07 18:08:52 +00:00
Ian Lynagh
3e86c4c39e Kotlin: Allow extractNewExpr to return null 2023-08-07 18:59:51 +01:00
Robert Marsh
65fbcc570c Swift: CFG test for for-try-await 2023-08-07 17:44:57 +00:00
Robert Marsh
eeaa361b12 Merge pull request #13907 from MathiasVP/cleanup-ssa-internals
C++: Small cleanup of `SsaInternals`
2023-08-07 13:16:59 -04:00
Robert Marsh
07650af357 Swift: accept test for CollectionContent rename 2023-08-07 15:04:21 +00:00
Mathias Vorreiter Pedersen
60f2e8a676 C++: Fix QLDoc. 2023-08-07 15:55:43 +01:00
Robert Marsh
146c50049c Finish CollectionContent rename
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2023-08-07 10:26:40 -04:00
Mathias Vorreiter Pedersen
f2f4e1f882 C++: Add more QLDoc. 2023-08-07 15:22:46 +01:00
Mathias Vorreiter Pedersen
e9750af89f Merge pull request #13783 from MathiasVP/type-bounds-for-new-range-analysis
C++: Constant type-bounds in the new range analysis
2023-08-07 15:20:45 +01:00
Mathias Vorreiter Pedersen
291f1a189d C++: Unify the two branches. 2023-08-07 14:23:35 +01:00
Michael Nebel
37a546253e Merge pull request #13688 from michaelnebel/csharp/aspnetcore
C#: Turn RuntimeVersion into a record type.
2023-08-07 15:20:21 +02:00
Jami
5862cd2378 Merge pull request #13889 from jcogs33/jcogs33/fix-some-models
Java: remove duplicate models
2023-08-07 08:46:18 -04:00
Mathias Vorreiter Pedersen
467231e469 Merge pull request #13887 from jketema/float128x
C++: Remove support for `_Float128x` which is not actually supported by gcc
2023-08-07 13:42:24 +01:00
Jeroen Ketema
073d170253 C++: Fix typo in change note 2023-08-07 14:30:35 +02:00
Rasmus Lerchedahl Petersen
957c0d6387 Python: move change note 2023-08-07 14:28:53 +02:00
Jeroen Ketema
e795e1c387 C++: Add change note 2023-08-07 14:24:04 +02:00
Mathias Vorreiter Pedersen
6e6e118d4b C++: Make the branches more identical. 2023-08-07 13:22:46 +01:00
Geoffrey White
dc98dec5b6 Swift: Change note. 2023-08-07 13:16:00 +01:00
Stephan Brandauer
3433437034 Java: automodel application mode: only extract the first argument corresponding to a varargs array 2023-08-07 14:15:17 +02:00
Geoffrey White
ab3f3d03c5 Swift: Model taint into optionals via ForceValueExpr. 2023-08-07 13:11:29 +01:00
Michael Nebel
6bb9e6d122 C#: Address review comments. 2023-08-07 13:40:37 +02:00
Edward Minnix III
58d8a2d77f Merge pull request #13899 from egregius313/egregius313/random-nextbytes-typo-fix
Java: Fix typo in `StdlibRandomSource::getOutput`
2023-08-07 07:36:44 -04:00
Tom Hvitved
2126ab0dde Merge pull request #13901 from hvitved/dataflow/refactor
Data flow: Refactor shared library
2023-08-07 13:22:53 +02:00
Ian Lynagh
0d97c1c54a Merge pull request #13837 from igfoo/igfoo/nullFunLabel
Kotlin: Pass on a parentId and remove some redundant braces
2023-08-07 12:19:22 +01:00
Michael Nebel
e62ec888c0 Merge pull request #13506 from michaelnebel/java/threatmodels
Java: Threat Models
2023-08-07 12:50:01 +02:00
Stephan Brandauer
e1a5eba61b Java: automodel application mode: refactor varargs endpoint class to rely on normal argument node for nicer extracted examples 2023-08-07 12:18:52 +02:00
Stephan Brandauer
650ff8db87 Java: automodel comments 2023-08-07 12:18:51 +02:00
Stephan Brandauer
0781cb78e8 Java: automodel application mode: add isVarargsArray metadata value 2023-08-07 12:18:51 +02:00
Stephan Brandauer
5abf7769a7 Java: automodel application mode: use endpoint class like in framework mode 2023-08-07 12:18:51 +02:00
Rasmus Lerchedahl Petersen
2f9172046b Python: change-note 2023-08-07 11:50:13 +02:00
Rasmus Lerchedahl Petersen
ef1a5cb0fa shared: change-note 2023-08-07 11:50:03 +02:00
Tom Hvitved
34864e1077 Swift: Adjust to data flow refactor 2023-08-07 11:35:23 +02:00
Tom Hvitved
6c989b9c6b Python: Adjust to data flow refactor 2023-08-07 11:35:23 +02:00
Tom Hvitved
693970f243 Java: Adjust to data flow refactor 2023-08-07 11:35:23 +02:00
Tom Hvitved
56e19411d0 Go: Adjust to data flow refactor 2023-08-07 11:35:22 +02:00
Tom Hvitved
05cf796c54 C#: Adjust to data flow refactor 2023-08-07 11:35:21 +02:00
Tom Hvitved
7ef3adcafd C++: Adjust to data flow refactor 2023-08-07 11:35:21 +02:00
Tom Hvitved
db88b7da88 Ruby: Adjust to data flow refactor 2023-08-07 11:35:21 +02:00
Tom Hvitved
b926a7ebba Data flow: Update QL doc 2023-08-07 11:35:21 +02:00
Tom Hvitved
4d14311653 Data flow: Rename DataFlowParameter to InputSig 2023-08-07 11:35:21 +02:00
Tom Hvitved
6208175aa9 Data flow: Move DataFlowParameter into DataFlow.qll 2023-08-07 11:35:21 +02:00
Tom Hvitved
0d33c32d8e Data flow: Move DataFlowImpl(Common).qll into an internal folder 2023-08-07 11:35:21 +02:00
Rasmus Lerchedahl Petersen
4dbaed9ec2 Python: add qldoc 2023-08-07 11:31:22 +02:00
Rasmus Lerchedahl Petersen
b8717b3046 Python: remove incorrect use of "stem" 2023-08-07 11:25:31 +02:00
Mathias Vorreiter Pedersen
e14e0cdbb7 Merge pull request #13888 from github/revert-13757-sources
Revert "Swift: Pragmatic fix for CustomUrlSchemes.qll."
2023-08-07 09:31:10 +01:00
Erik Krogh Kristensen
2300285204 Merge pull request #13898 from github/dependabot/cargo/ql/regex-1.9.3
Bump regex from 1.9.1 to 1.9.3 in /ql
2023-08-07 08:41:43 +02:00
Ed Minnix
23e2eb11dd Change note 2023-08-07 00:23:58 -04:00
Ed Minnix
fe4eef0bcb Fix typo, replace getBytes with nextBytes 2023-08-07 00:16:47 -04:00
dependabot[bot]
6ed4aaf94b Bump regex from 1.9.1 to 1.9.3 in /ql
Bumps [regex](https://github.com/rust-lang/regex) from 1.9.1 to 1.9.3.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.9.1...1.9.3)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-07 03:30:06 +00:00
Mathias Vorreiter Pedersen
33e991b037 C++: Fix QLDoc. 2023-08-06 20:50:19 +01:00
Mathias Vorreiter Pedersen
af07efe14f C++: Accept test changes. 2023-08-05 21:59:08 +02:00
Mathias Vorreiter Pedersen
f0a1742ad6 C++: Fix barriers in 'AllocationToInvalidPointer.qll'. 2023-08-05 21:58:24 +02:00
Mathias Vorreiter Pedersen
7c9d41d3b9 C++: Make 'SizeBarrier' private as promised. 2023-08-05 21:57:57 +02:00
Mathias Vorreiter Pedersen
835b5e349b C++: Accept test changes. 2023-08-05 21:56:51 +02:00
Mathias Vorreiter Pedersen
0f285ccce0 C++: Fix QLDoc. 2023-08-05 21:55:00 +02:00
Mathias Vorreiter Pedersen
c0828a488f C++: Fix barriers in 'InvalidPointerToDereference.qll'. 2023-08-05 21:55:00 +02:00
Chad Bentz
e2e9c810bf Add lib change-notes 2023-08-04 22:11:36 +00:00
Chad Bentz
5a106fd5d6 Removes false positive creds from NetCore Identity 2023-08-04 21:46:35 +00:00
Robert Marsh
3ebbb80a9e Swift: Change note for CollectionContent 2023-08-04 20:19:35 +00:00
Robert Marsh
10bbf441dc Swift: QLDoc for Set.qll 2023-08-04 20:17:56 +00:00
Robert Marsh
ccc3094267 Swift: autoformat 2023-08-04 20:17:08 +00:00
Geoffrey White
c7fb8de5f9 Swift: Test ForceValueExpr content reads. 2023-08-04 21:15:15 +01:00
Jeroen Ketema
daf6ecd12f C++: Update dbscheme stats file 2023-08-04 22:07:00 +02:00
Robert Marsh
6f38769a9b Swift: rename SetContent to CollectionContent 2023-08-04 18:46:43 +00:00
Robert Marsh
024c5cfe2f Swift: add MaD print support for EnumElement 2023-08-04 18:44:42 +00:00
Robert Marsh
0142309cab Swift: add summary read steps in dataflow 2023-08-04 18:44:42 +00:00
Robert Marsh
b301092e34 Swift: model updates for Set 2023-08-04 18:44:42 +00:00
Robert Marsh
de0ec3e3f7 Swift: WIP SetContent for dataflow 2023-08-04 18:44:42 +00:00
Jami Cogswell
19622aec49 Java: remove duplicate 'Files.newOutputStream' ai model 2023-08-04 14:06:57 -04:00
Jami Cogswell
e64d581f7a Java: remove duplicate 'Files.newInputStream' ai model 2023-08-04 14:05:05 -04:00
Jami Cogswell
d2a24dee7f Java: remove duplicate 'Files.delete' ai model 2023-08-04 14:02:59 -04:00
Jami Cogswell
516831aa41 Java: remove duplicate 'Files.move' ai model 2023-08-04 14:01:27 -04:00
Jami Cogswell
c510d33fbf Java: remove duplicate 'Files.deleteIfExists' ai model 2023-08-04 13:52:18 -04:00
Alexandre Boulgakov
761db70d8d Revert "Swift: Pragmatic fix for CustomUrlSchemes.qll." 2023-08-04 18:03:00 +01:00
Mathias Vorreiter Pedersen
abe3a816ce Merge pull request #13851 from MathiasVP/sink-without-states
DataFlow: Support stateless `isSink` in `StateConfigSig`s
2023-08-04 18:01:42 +02:00
Jeroen Ketema
7b3bdee5ea C++: Update dbscheme and add upgrade and downgrade scripts 2023-08-04 17:59:03 +02:00
Jeroen Ketema
ea9f49efa1 C++: Remove support for _Float128x which is not actually supported by gcc 2023-08-04 17:23:11 +02:00
Alexandre Boulgakov
97c688849d Merge pull request #13869 from github/sashabu/swift-logging-compiler
Swift: Route compiler diagnostics through our log.
2023-08-04 16:13:12 +01:00
Mathias Vorreiter Pedersen
2d832db883 C++: Accept test changes. 2023-08-04 16:12:00 +02:00
Mathias Vorreiter Pedersen
9807c0b0a6 C++: Filter type-based reasons out of MCTV queries. 2023-08-04 16:11:35 +02:00
Mathias Vorreiter Pedersen
b14db86ef9 C++: Let 'hasConstantBound' determine a reason. 2023-08-04 16:09:07 +02:00
Mathias Vorreiter Pedersen
050a563580 C++: Infer a constant upper bound whenever we convert to a 'larger' upper bound (and similarly for lower bounds). 2023-08-04 16:03:09 +02:00
Tony Torralba
33eaeb9cf8 Merge pull request #13484 from aegilops/java/experimental/command-injection
Java: Experimental version of Java Command Injection query
2023-08-04 15:48:15 +02:00
Michael Nebel
51c8331c8f Merge pull request #13522 from michaelnebel/csharp/usestubs4
C#: Use stubs for query tests.
2023-08-04 15:40:08 +02:00
Mathias Vorreiter Pedersen
3e9d9e72dc Merge pull request #13880 from MathiasVP/type-bounds-preparation
C++: Add a type-based `SemReason`.
2023-08-04 14:52:16 +02:00
Mathias Vorreiter Pedersen
98e670f25c Update cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-08-04 14:34:03 +02:00
Mathias Vorreiter Pedersen
121d754be4 Update cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-08-04 14:33:58 +02:00
Michael Nebel
9c4d77a925 Java: Address review comments. 2023-08-04 13:47:30 +02:00
Michael Nebel
d3eb9c1325 Java: Add release note and address review comments. 2023-08-04 13:36:43 +02:00
Paul Hodgkinson
5db569da89 Merge branch 'main' into java/experimental/command-injection 2023-08-04 12:11:29 +01:00
Mathias Vorreiter Pedersen
e066e87890 Update shared/dataflow/codeql/dataflow/DataFlowImpl.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2023-08-04 11:32:41 +02:00
Jeroen Ketema
877ee7047d Merge pull request #13884 from jketema/global-var-declspec
C++: Add test for `__declspec` attribute on a global variable
2023-08-04 11:26:10 +02:00
Mathias Vorreiter Pedersen
86dbb507fd C++: Add more comments to explain the meaning of 'combineWith'. 2023-08-04 11:20:17 +02:00
Mathias Vorreiter Pedersen
eb19052a7d Apply suggestions from code review
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2023-08-04 11:10:12 +02:00
Mathias Vorreiter Pedersen
981f67531c DataFlow: Introduce 'revSinkNode'. 2023-08-04 11:09:08 +02:00
Mathias Vorreiter Pedersen
75c333273c C++: Bind 'impl'. Oops. 2023-08-04 10:58:54 +02:00
Mathias Vorreiter Pedersen
d398c8c5a8 C++: Share some code by introducing a parameterized module to construct reasons. 2023-08-04 10:52:18 +02:00
Jeroen Ketema
d80eff330b C++: Add test for __declspec attribute on a global variable 2023-08-04 10:35:32 +02:00
Tony Torralba
586c8803c5 Move the sources back the .ql files
Otherwise they would both apply at the same time, making both versions of the query identical.
2023-08-04 10:02:56 +02:00
Tony Torralba
e9bad321b6 Apply suggestions from code review 2023-08-04 09:21:45 +02:00
Mathias Vorreiter Pedersen
7270b5079b C++: Add a type-based 'SemReason'. 2023-08-03 15:26:10 +02:00
Paul Hodgkinson
fba37aa7c9 Merge branch 'main' into java/experimental/command-injection 2023-08-03 14:12:38 +01:00
Geoffrey White
deb97a6ccc Swift: Improve regex performance with possessive matching (i.e. don't backtrack). 2023-08-03 13:57:49 +01:00
aegilops
fc7f8409be Fix up for code review 2023-08-03 13:50:40 +01:00
aegilops
3658710578 Fixed formatting, committed expected test results 2023-08-03 13:50:40 +01:00
Tom Hvitved
b69188fee9 C#: Adopt shared CFG construction library from shared controlflow pack 2023-08-03 14:12:24 +02:00
Tom Hvitved
e011480114 Merge pull request #13509 from hvitved/cfg-pack
Convert shared CFG construction library to a parameterized module
2023-08-03 14:11:56 +02:00
Mathias Vorreiter Pedersen
9ed8dec87f Merge pull request #13877 from jketema/constant-doc
C++: Improve the QL doc of `isConstant`
2023-08-03 13:41:44 +02:00
Mathias Vorreiter Pedersen
50f5c4d5f6 DataFlow: Don't support stateless sink nodes in partial flow exploration. 2023-08-03 13:30:05 +02:00
Paolo Tranquilli
67cd25184a Merge pull request #12433 from github/alexdenisov+redsun82/tuple-mangling
Swift: properly identify types and declarations in trap files via mangling
2023-08-03 13:27:07 +02:00
Jeroen Ketema
48048d6f38 Merge pull request #13874 from jketema/use-after-free
C++: Improve use-after-free example code
2023-08-03 13:21:12 +02:00
Owen Mansel-Chan
00c704201c Merge pull request #13871 from github/rc/3.10
Merge `rc/3.10` into `main`
2023-08-03 11:24:07 +01:00
Jeroen Ketema
7ff6f09626 C++: Improve the QL doc of isConstant 2023-08-03 12:16:12 +02:00
Jeroen Ketema
0c0720a962 C++: Improve use-after-free example code
* Remove the mismatch between `new` and `free` and use `delete` instead
* Make the function `void`, so people copying the code will not forget
  to add a `return`.
* Balance out the `...` for omitted code.
2023-08-03 11:06:15 +02:00
Tom Hvitved
2ac646770e Merge ControlFlowTreeBase and AstNode 2023-08-03 10:59:26 +02:00
Jeroen Ketema
1ad533a4f8 Merge pull request #13873 from jketema/ir-range-test
C++: Add semantic range analysis test as IR test
2023-08-03 10:58:24 +02:00
Chris Smowton
8702efda1e Merge pull request #13835 from github/smowton/fix/logrus-with-context
Don't treat logrus' WithContext method as a logging function
2023-08-03 09:57:30 +01:00
Tom Hvitved
525ed65b0b Rename getNode to getAstNode 2023-08-03 10:56:50 +02:00
Jeroen Ketema
f7923d93f1 C++: Add semantic range analysis test as IR test
The range analysis test currently fails with the frontend update, because the
generated IR is incorrect after the update.
2023-08-03 10:13:23 +02:00
Anders Schack-Mulligen
0ae81eace3 Java: update fixed test 2023-08-03 10:07:00 +02:00
Asger F
5950865b55 Merge pull request #13755 from github/max-schaefer/js-server-crash-help
JavaScript: Improve qhelp for js/server-crash.
2023-08-03 10:04:08 +02:00
Anders Schack-Mulligen
72171972c3 Apply suggestions from code review
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2023-08-03 10:04:06 +02:00
Anders Schack-Mulligen
84316c41a3 Java: Add more qldoc. 2023-08-03 10:04:06 +02:00
Anders Schack-Mulligen
90052a3ca2 Java: Add proper types for capture nodes. 2023-08-03 10:04:06 +02:00
Anders Schack-Mulligen
e2a0849a0e Java: Add more qldoc. 2023-08-03 10:04:06 +02:00
Anders Schack-Mulligen
37455ec29e Java: Replace ratpack test fix with general heuristic summary. 2023-08-03 10:04:06 +02:00
Anders Schack-Mulligen
c5990311ca Java: Redesign and reimplement variable capture flow. 2023-08-03 10:04:06 +02:00
Anders Schack-Mulligen
70bef64e2a Java: Fix ratpack flow. 2023-08-03 10:04:05 +02:00
Anders Schack-Mulligen
f4a05c183b Shared: Add some qldoc. 2023-08-03 10:04:05 +02:00
Anders Schack-Mulligen
15daa51ee5 Shared: Address review comments and QL4QL alerts. 2023-08-03 10:04:05 +02:00
Anders Schack-Mulligen
a23e77ca58 Java: Disregard heap parameter in any-argument and any-parameter specs. 2023-08-03 10:04:05 +02:00
Anders Schack-Mulligen
9a4de208ef Java: Fix qltests. 2023-08-03 10:04:05 +02:00
Anders Schack-Mulligen
d1a616a70a Java: Add proper support for variable capture flow. 2023-08-03 10:04:02 +02:00
Asger F
c38cbe859d Merge pull request #13737 from asgerf/dynamic/fuzzy-models
Dynamic: add Fuzzy token
2023-08-03 09:58:24 +02:00
Anders Starcke Henriksen
131ae1aae9 Fix name in predicate. 2023-08-03 09:53:40 +02:00
Anders Starcke Henriksen
1c425a5602 Change from package to endpoint. 2023-08-03 09:50:23 +02:00
Anders Starcke Henriksen
9b8d7df370 Add option to filter automodel queries by package. 2023-08-03 09:50:23 +02:00
Tom Hvitved
2f3e52646c Add class wrappers around newtype in Cfg.qll 2023-08-03 09:39:30 +02:00
Tom Hvitved
5d69e14cc1 Rename ControlFlowElement to AstNode 2023-08-03 09:39:30 +02:00
Tom Hvitved
1988397f93 Make shared CFG construction library a parameterized module 2023-08-03 09:39:30 +02:00
Tom Hvitved
5049aafdd8 Copy existing ControlFlowGraphImplShared into new shared controlflow pack 2023-08-03 09:32:37 +02:00
Mathias Vorreiter Pedersen
89aa86a1d6 Merge pull request #13741 from rdmarsh2/rdmarsh2/swift/array-content-flow
Swift: add DataFlow::Content for arrays
2023-08-02 17:37:40 +02:00
Paolo Tranquilli
56869553e8 Swift: route compiler diagnostics through our log
(cherry picked from commit b8c55612e5)
2023-08-02 15:41:54 +01:00
Owen Mansel-Chan
ff5409fec7 Merge pull request #13785 from owen-mc/go/change-golangSpecificParamArgFilter
Go: Avoid using getTarget() as it may not exist
2023-08-02 15:40:40 +01:00
Alexandre Boulgakov
0dafe2d757 Swift: Mangle ArchetypeTypes with different superclasses in different extensions. 2023-08-02 15:18:52 +01:00
Mathias Vorreiter Pedersen
a5f521cfa4 DataFlow: Add change note. 2023-08-02 14:56:57 +02:00
Mathias Vorreiter Pedersen
3007fdab5e Sync identical files. 2023-08-02 14:33:33 +02:00
Mathias Vorreiter Pedersen
096eeeb549 C++: Handle 'isSink' without states in the backwards-compatibility code and in taint-tracking 2023-08-02 14:33:04 +02:00
Mathias Vorreiter Pedersen
b953c4a1cf DataFlow: Allow stateless sinks. 2023-08-02 14:31:18 +02:00
Anders Schack-Mulligen
7bc8bf616f Merge pull request #13863 from aschackmull/dataflow/pack4
Dataflow: Move the shared library to a properly shared qlpack.
2023-08-02 14:19:49 +02:00
Mathias Vorreiter Pedersen
7bea18773c Merge pull request #13857 from github/alexdenisov/unresolved-dot-exprs-patterns
Swift: SubExpr may yield unresolved nodes in certain cases while MatchedExpr is always resolved
2023-08-02 09:35:06 +02:00
Anders Schack-Mulligen
1ad51e754e Dataflow: Rename change note to proper format. 2023-08-02 08:50:51 +02:00
Sarita Iyer
0bd87f9f86 Merge pull request #13840 from github/si-10115-docs-update
Update supported frameworks
2023-08-01 13:05:32 -04:00
Max Schaefer
5124310f14 Update javascript/ql/src/Security/CWE-730/ServerCrash.qhelp
Co-authored-by: Asger F <asgerf@github.com>
2023-08-01 17:03:05 +01:00
Geoffrey White
5f7e5b946d Swift: Codegen. 2023-08-01 16:38:27 +01:00
Geoffrey White
e30ac42e3e Merge branch 'main' into typegetname 2023-08-01 16:36:31 +01:00
Geoffrey White
c8f5ada594 Swift: Fix errors in queries. 2023-08-01 15:50:15 +01:00
Stephan Brandauer
cb55b10edc Merge pull request #13788 from github/kaeluka/automodel-telemetry-testing
Java: Tests for Automodel Extraction Queries
2023-08-01 15:30:26 +02:00
Alex Denisov
9d643ae1ed Swift: record CFG incosistency 2023-08-01 15:06:04 +02:00
Geoffrey White
116006d280 Swift: Fix for type names containing '...'. 2023-08-01 13:57:46 +01:00
Anders Schack-Mulligen
405a3a73d1 Java: Remove irrelevant import. 2023-08-01 14:31:30 +02:00
Geoffrey White
40219aad88 Swift: More robust Type.getName(). 2023-08-01 13:24:10 +01:00
Anders Schack-Mulligen
15da4ee009 Merge pull request #13856 from aschackmull/java/maybebrokencrypto-barrier
Java: Make the barrier in java/potentially-weak-cryptographic-algorithm less restrictive
2023-08-01 14:20:44 +02:00
Alex Denisov
6667d9e45c Swift: SubExpr may yield unresolved nodes in certain cases while MatchedExpr is always resolved 2023-08-01 14:15:33 +02:00
Geoffrey White
655f238017 Swift: Accept test changes. 2023-08-01 13:14:14 +01:00
Anders Schack-Mulligen
199d1431d7 Dataflow: Add change note. 2023-08-01 14:02:34 +02:00
Anders Schack-Mulligen
5946d5e806 Dataflow: Remove sync. 2023-08-01 14:02:34 +02:00
Anders Schack-Mulligen
0544205594 Swift: Adjust to use the qlpack data-flow api. 2023-08-01 14:02:33 +02:00
Anders Schack-Mulligen
73d4b126cf Ruby: Adjust to use the qlpack data-flow api. 2023-08-01 14:02:33 +02:00
Anders Schack-Mulligen
b27a3a81bc Python: Adjust to use the qlpack data-flow api. 2023-08-01 14:02:33 +02:00
Anders Schack-Mulligen
21eb78ea5e Go: Adjust to use the qlpack data-flow api. 2023-08-01 14:02:33 +02:00
Anders Schack-Mulligen
fcb482b870 C/C++: Adjust to use the qlpack data-flow api. 2023-08-01 14:02:33 +02:00
Anders Schack-Mulligen
5c9a839ac7 C#: Adjust to use the qlpack data-flow api. 2023-08-01 13:47:09 +02:00
Anders Schack-Mulligen
c34c667e6b Java: Adjust to use the qlpack data-flow api. 2023-08-01 13:47:09 +02:00
Anders Schack-Mulligen
50e7892498 Dataflow: Autoformat/indent. 2023-08-01 13:47:08 +02:00
Anders Schack-Mulligen
d7ea60e137 Java: Move data flow lib. 2023-08-01 13:47:08 +02:00
Owen Mansel-Chan
dbc6868bc1 Update go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2023-08-01 12:23:49 +01:00
Asger F
9326fbd1dd Merge pull request #13841 from jeongsoolee09/log-injection-mad
JS: Add support for log injection in MaD
2023-08-01 13:09:56 +02:00
Michael Nebel
4568cccd71 Java: Add some unit tests for sourceModelKindConfig. 2023-08-01 12:56:13 +02:00
Michael Nebel
a9bc23fa3e Java: Add threat model configuration related extensible predicates and some initial tuples. 2023-08-01 12:56:13 +02:00
Michael Nebel
7ba8a663bf C#: Base the CSI query test cases on stubs. 2023-08-01 12:55:35 +02:00
Michael Nebel
c3c5fc0981 C#: Base the Configuration query test cases on stubs. 2023-08-01 12:55:35 +02:00
Michael Nebel
324eac7718 C#: Base the Concurrency query test cases on stubs. 2023-08-01 12:55:35 +02:00
Michael Nebel
cf8dc64842 C#: Base the Bad Practices query test cases on stubs. 2023-08-01 12:55:35 +02:00
Michael Nebel
49c8daefca C#: Base the Architecture query test cases on stubs. 2023-08-01 12:55:35 +02:00
Michael Nebel
ab4e643bf8 C#: Turn RuntimeVersion into a record type. 2023-08-01 12:54:55 +02:00
Michael Nebel
ffd1456d67 Java: Update MaD external documentation related to With and Without Element. 2023-08-01 12:03:44 +02:00
Michael Nebel
a8ccc8d980 Java: Update MaD internal documentation. 2023-08-01 12:03:44 +02:00
Michael Nebel
fc66b6ef9c Java: Update test comments to reflect the MaD syntax. 2023-08-01 12:03:44 +02:00
Michael Nebel
99ac98bffc Java: Re-factor a model to use WithElement (this model is already tested in collections/B.java). 2023-08-01 12:03:44 +02:00
Michael Nebel
e97a4a1aea Java: Update telemetry test expected output. 2023-08-01 12:03:44 +02:00
Michael Nebel
0604a85bb1 Java: Add WithoutElement model for List.clear and add appropriate test. 2023-08-01 12:03:44 +02:00
Michael Nebel
21ec83a197 Java: Add MaD support for With[out]Element. 2023-08-01 12:03:44 +02:00
Geoffrey White
b500d8baa1 Swift: QLDoc TupleType. 2023-08-01 11:01:05 +01:00
Alex Ford
2b741448f4 Merge pull request #13309 from maikypedia/maikypedia/ldap-injection
Ruby: Add LDAP Injection query
2023-08-01 10:44:46 +01:00
Cornelius Riemenschneider
41487987b5 Merge pull request #13858 from github/criemen-update-bazel
Update bazel to 6.3.1
2023-08-01 10:44:36 +02:00
Mathias Vorreiter Pedersen
d111fa7e94 Merge pull request #13862 from jketema/ir-test
C++: Add IR test that shows dataflow regression after frontend update
2023-08-01 10:06:49 +02:00
Tony Torralba
b5d08ade59 Formatting 2023-08-01 09:35:25 +02:00
Anders Schack-Mulligen
e73e312e10 Java: Add change note. 2023-08-01 09:28:56 +02:00
Stephan Brandauer
621c05dc4b Java: format 2023-08-01 09:19:03 +02:00
Stephan Brandauer
bc3e78f034 Java: add automodel framework mode test case for newly supported interface-method parameter extraction 2023-08-01 09:18:58 +02:00
Stephan Brandauer
058236877e Java: Drive-by: fix oversight in #13823
In PR #13823, we had rewritten the endpoints that are being considered for framework mode. We used to use `DataFlow::ParameterNode` as endpoints.
However, `ParameterNode`s do not exist for the implicit `this` parameter; they also do not exist for bodiless interface-methods.

In PR #13823, we forgot to model that `this` only exists for non-static methods and to only consider parameters that we have source code for.
2023-08-01 09:18:58 +02:00
Stephan Brandauer
5ad984f22f Java: update text expectations after merging #13823 2023-08-01 09:18:58 +02:00
Stephan Brandauer
da87d82d08 Java: fix a comment 2023-08-01 09:18:58 +02:00
Stephan Brandauer
be629b27ed Java: Automodel package private test case 2023-08-01 09:18:57 +02:00
Stephan Brandauer
f5c4155d63 Java: Automodel tests: update after merging #13818 2023-08-01 09:18:57 +02:00
Stephan Brandauer
44b8ec642e Java: merge framework mode tests into one 2023-08-01 09:18:57 +02:00
Stephan Brandauer
8cc367c45e Java: merge application mode tests into one 2023-08-01 09:18:57 +02:00
Stephan Brandauer
37b6b46dbf Java: update extraction query tests after merging PR #13747 2023-08-01 09:18:57 +02:00
Stephan Brandauer
50603102d1 Java: tests for automodel application mode, test that local calls are not candidates 2023-08-01 09:18:57 +02:00
Stephan Brandauer
457604e37e Java: tests for automodel framework mode negative example extraction 2023-08-01 09:18:57 +02:00
Stephan Brandauer
938a7a788f Java: tests for automodel application mode negative example extraction 2023-08-01 09:18:57 +02:00
Stephan Brandauer
abed936556 Java: tests for automodel framework mode positive example extraction 2023-08-01 09:18:57 +02:00
Stephan Brandauer
1bc222ec40 Java: tests for automodel application mode positive example extraction 2023-08-01 09:18:57 +02:00
Stephan Brandauer
2e89a11949 Java: tests for automodel application mode candidate extraction 2023-08-01 09:18:56 +02:00
Stephan Brandauer
18fe587e75 Java: tests for automodel framework mode candidate extraction 2023-08-01 09:18:56 +02:00
Tony Torralba
2b3cab355d Merge pull request #13859 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-08-01 09:18:20 +02:00
Jeroen Ketema
ef8d95f87d C++: Add IR test that shows dataflow regression after frontend update 2023-08-01 09:01:39 +02:00
Owen Mansel-Chan
5a5e921ee7 Merge pull request #13846 from owen-mc/go/better-baselines
Go: Add language-specific baseline configuration
2023-08-01 07:14:43 +01:00
Owen Mansel-Chan
a8c64443e8 Merge pull request #13645 from porcupineyhairs/goTiming
Go : Improvements to Timing Attacks query
2023-08-01 07:10:42 +01:00
github-actions[bot]
b547ae7c2f Add changed framework coverage reports 2023-08-01 00:18:36 +00:00
Jeongsoo Lee
1d5eb4a960 Update javascript/ql/lib/change-notes/2023-07-28-mad-log-injection.md
Co-authored-by: Asger F <asgerf@github.com>
2023-07-31 15:38:35 -07:00
Cornelius Riemenschneider
caf2180bad Update .bazelversion 2023-08-01 00:15:53 +02:00
Paul Hodgkinson
3bc7cf6ac7 Merge branch 'main' into java/experimental/command-injection 2023-07-31 19:14:55 +01:00
Jeongsoo Lee
9ab2a28de0 Merge branch 'main' into log-injection-mad 2023-07-31 09:55:35 -07:00
Felicity Chapman
df1e8e263b Merge pull request #13854 from github/11185-add-note
CodeQL library update to use modular API interface - Add note and include in articles
2023-07-31 17:22:17 +01:00
Owen Mansel-Chan
d98079d72c Apply suggestions from code review
Co-authored-by: Henry Mercer <henry.mercer@me.com>
2023-07-31 16:49:11 +01:00
Owen Mansel-Chan
216911dad9 Merge branch 'main' into goTiming 2023-07-31 16:15:10 +01:00
Owen Mansel-Chan
3d495bdd43 Add new files to CODEQL_TOOLS in Makefile 2023-07-31 16:12:52 +01:00
Owen Mansel-Chan
47a536c85d Always output valid JSON containing paths-ignore 2023-07-31 16:09:47 +01:00
Alex Ford
af854749d7 Ruby: update Ldapinjection test output 2023-07-31 16:08:15 +01:00
Alex Ford
f437a6f729 Merge branch 'main' into maikypedia/ldap-injection 2023-07-31 16:00:41 +01:00
Alex Ford
558238a9be Ruby: update TaintStep test output 2023-07-31 16:00:27 +01:00
Felicity Chapman
46f80dc5ca Put back a missing colon to fix the link 2023-07-31 15:56:24 +01:00
Alex Ford
f272b0786a Ruby: fix qldoc typo 2023-07-31 14:58:05 +01:00
Alex Ford
7f82aba7d4 qlformat 2023-07-31 14:57:14 +01:00
Alex Ford
2240e4bffb Ruby: fix changenote date format 2023-07-31 14:56:53 +01:00
Felicity Chapman
9a334d3300 Add shortened link to changelog 2023-07-31 14:13:52 +01:00
Anders Schack-Mulligen
e87b8ba3d7 Java: Make the barrier in java/potentially-weak-cryptographic-algorithm less restrictive. 2023-07-31 14:28:53 +02:00
Asger F
a148c7cc87 JS: Mention log-injection sink kind in docs 2023-07-31 14:04:16 +02:00
Geoffrey White
1c64fb16f1 Merge pull request #13756 from geoffw0/sources2
Swift: CustomUrlSchemes test enhancements and minor model improvement
2023-07-31 12:53:03 +01:00
Asger F
da3eb28767 Apply suggestions from code review
Co-authored-by: Jorge <46056498+jorgectf@users.noreply.github.com>
2023-07-31 13:51:59 +02:00
Felicity Chapman
a0c0da78e9 Merge branch 'main' into 11185-add-note 2023-07-31 11:54:00 +01:00
Geoffrey White
c4b782407b Merge pull request #13853 from geoffw0/commandinject
Swift: Autoformat experimental query.
2023-07-31 11:30:20 +01:00
Felicity Chapman
4d05b742d6 Merge branch 'main' into 11185-add-note 2023-07-31 10:58:03 +01:00
Felicity Chapman
32da3c3730 Add main note and include in articles 2023-07-31 10:50:47 +01:00
Geoffrey White
f921076fca Swift: Autoformat. 2023-07-31 10:25:25 +01:00
Tony Torralba
5488abc512 Merge pull request #13850 from atorralba/atorralba/java/unimportant-generated-models
Java: Remove superfluous generated models
2023-07-31 11:25:03 +02:00
Tony Torralba
41f1315da9 Merge pull request #13772 from atorralba/atorralba/java/inputstream-wrapper-read-step
Java: Add taint steps for InputStream wrappers
2023-07-31 11:12:43 +02:00
Geoffrey White
e534afe634 Merge pull request #13726 from maikypedia/maikypedia/swift-command-injection
Swift: Add Command Injection query (CWE-078)
2023-07-31 10:06:22 +01:00
Geoffrey White
12f2539d1d Swift: Use flowTo. 2023-07-31 10:03:25 +01:00
Geoffrey White
20b0969a97 Swift: Restore original Type.toString() behaviour. 2023-07-31 09:51:55 +01:00
Mathias Vorreiter Pedersen
2562f8a297 Merge pull request #13844 from jketema/forgotten-paren
C++: Add forgotten parentheses in ternary IR test
2023-07-31 10:03:06 +02:00
Tony Torralba
3bd4d34a47 Java: Remove superfluous generated models 2023-07-31 09:48:03 +02:00
Porcupiney Hairs
74e5c15eaa Go : Improvements to Timing Attacks query 2023-07-31 06:30:47 +05:30
Owen Mansel-Chan
b5518047fa Go: Add language-specific baseline configuration 2023-07-30 21:52:33 +01:00
Mathias Vorreiter Pedersen
4656130dab Merge pull request #13843 from MathiasVP/revert-13792 2023-07-30 01:18:00 +02:00
Jeroen Ketema
0bc75ea9b7 C++: Add forgotten parentheses in ternary IR test
Without the parentheses, the expressions are parsed as `a ? x : (y = val)`.
2023-07-29 18:44:28 +02:00
Owen Mansel-Chan
93e5b2260e Merge pull request #13834 from owen-mc/go/fix-compiler-error-messages-for-1.20.6
Backport: Compiler error messages changed in Go 1.20.6
2023-07-29 13:45:19 +01:00
Mathias Vorreiter Pedersen
fd1949092c C++: Accept test changes. 2023-07-29 11:29:06 +02:00
Mathias Vorreiter Pedersen
ce9a14b692 Revert "Merge pull request #13792 from MathiasVP/swap-argument-order-in-invalid-ptr-deref"
This reverts commit 1fa6511482, reversing
changes made to 4676ca5a4a.
2023-07-29 11:26:41 +02:00
Jeongsoo Lee
4529d8b75a Add support for log injection in MaD 2023-07-28 22:37:56 +00:00
Sarita Iyer
f6b6a988ca Update supported-frameworks.rst 2023-07-28 17:21:55 -04:00
Robert Marsh
22ae430e65 Swift: accept more test changes from hiding InOutExpr 2023-07-28 20:43:25 +00:00
Robert Marsh
bb4fe2002f Merge branch 'main' into rdmarsh2/swift/array-content-flow 2023-07-28 20:41:23 +00:00
Alexandre Boulgakov
3e7a7fe54e Swift: Mangle ArchetypeTypes with different constraints in different extensions. 2023-07-28 21:39:52 +01:00
Ian Lynagh
01a512b677 Kotlin: Pass on a parentId 2023-07-28 17:46:05 +01:00
Owen Mansel-Chan
0895853a23 Delete unused testing predicate 2023-07-28 17:09:53 +01:00
Ian Lynagh
e8f4aee1cf Kotlin: Remove some redundant braces 2023-07-28 17:02:24 +01:00
Owen Mansel-Chan
00d5cb737c Different approach to avoiding getTarget() 2023-07-28 17:00:36 +01:00
Owen Mansel-Chan
d2b8d836e9 Avoid using getTarget() as it may not exist
Try to also deal with the case that we are calling a function
through a variable that it has been assigned to.
2023-07-28 17:00:34 +01:00
Stephan Brandauer
40eab180cc Merge pull request #13823 from github/kaeluka/support-argument-this-in-frameworkmode-metadata-extraction
Java: Support Argument[this] and parameters of bodiless interface methods in framework mode metadata extraction
2023-07-28 17:38:39 +02:00
Tony Torralba
08cba7dc5f Merge pull request #13713 from pwntester/java/struts2_source_taint_inheriting
[Java] Implement field taint inheritance for Struts2 unmarshalled objects
2023-07-28 16:46:27 +02:00
Robert Marsh
6039af0087 Swift: autoformat 2023-07-28 14:34:57 +00:00
Robert Marsh
7ed520ab54 Swift: update test expectations after hiding InOutExpr 2023-07-28 14:29:24 +00:00
Owen Mansel-Chan
a020189895 Merge pull request #13822 from owen-mc/dataflow/mergepathgraph3-signature-fix
Dataflow: MergePathGraph3 signature fix
2023-07-28 15:15:43 +01:00
Chris Smowton
f08879a2df Format; add change note 2023-07-28 14:16:30 +01:00
Chris Smowton
6fa2d2764d Don't treat logrus' WithContext method as a logging function
This isn't output by the default formatters (though a custom formatter could potentially output things stored in it)
2023-07-28 14:11:03 +01:00
Shati Patel
a98ae8941c Merge pull request #13832 from github/shati-patel/docs-indentation
Docs: Fix indentation in tutorial examples
2023-07-28 14:07:16 +01:00
Tony Torralba
2dff0ce5b4 Merge pull request #13712 from pwntester/java/new_struts2_models
[Java] New models for Struts2 framework
2023-07-28 14:31:25 +02:00
Stephan Brandauer
8bf960bd44 Java: fix QL-for-QL alert 2023-07-28 14:28:47 +02:00
Stephan Brandauer
021eedfdf1 Java: format 2023-07-28 14:26:34 +02:00
Owen Mansel-Chan
84dacbfbfd Compiler error messages changed in Go 1.20.6 2023-07-28 13:13:01 +01:00
Stephan Brandauer
82fd0e45aa Java: support Argument[this] in NotAModelApiParameter 2023-07-28 14:04:53 +02:00
Stephan Brandauer
a9d2f43538 Java: use a newtype for framework mode candidates 2023-07-28 13:51:25 +02:00
Stephan Brandauer
8ed773b240 Java: Framework mode extraction now uses a custom class for endpoints, so we can support both Argument[this] and interface-method parameters 2023-07-28 12:56:39 +02:00
Stephan Brandauer
09c64e8fee Java: Support Argument[this] in framework mode metadata extraction 2023-07-28 12:55:26 +02:00
shati-patel
1694915535 Docs: Fix indentation in tutorial examples 2023-07-28 11:45:39 +01:00
Ian Lynagh
499bd970d3 Merge pull request #13412 from igfoo/igfoo/json_escape
Kotlin: Tweak our JSON escaping
2023-07-28 11:13:51 +01:00
Alvaro Muñoz
c3a2ae2943 Account for public fields/setters 2023-07-28 12:12:07 +02:00
Alvaro Muñoz
c089368557 Merge branch 'java/struts2_source_taint_inheriting' of https://github.com/pwntester/codeql into java/struts2_source_taint_inheriting 2023-07-28 12:05:38 +02:00
Maiky
90ac5b905b 2023-07-28 00:21:02 +02:00
Maiky
2a49219127 Move query to experimental 2023-07-28 00:15:33 +02:00
Geoffrey White
beacade499 Swift: Autoformat. 2023-07-27 22:48:23 +01:00
Geoffrey White
15244e0ee1 Swift: Expand NominalType.getFullName to Type.getFullName (so it is a suitble substitute for the old Type.getName behaviour). 2023-07-27 22:41:46 +01:00
Maiky
2d88ac1846 Suggested Changes 2023-07-27 23:40:52 +02:00
Geoffrey White
e2740fef73 Swift: Add explanatory comment. 2023-07-27 22:12:49 +01:00
Maiky
f5e17d7d39 Add additional Filter Methods 2023-07-27 23:04:55 +02:00
Geoffrey White
2ba983bf4a Swift: Change note. 2023-07-27 22:04:07 +01:00
Maiky
d9800c7bb6 Update CommandInjection.ql 2023-07-27 22:45:50 +02:00
Maiky
d0a912fb02 Update swift/ql/src/queries/Security/CWE-078/CommandInjection.ql
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2023-07-27 22:45:05 +02:00
Geoffrey White
57a55eda75 Swift: QL solution (arguably clearer, seems more performant). 2023-07-27 20:51:49 +01:00
Geoffrey White
82057513c5 Swift: Implement Type.getName() as different from Type.getFullName() (regex solution). 2023-07-27 20:50:21 +01:00
Robert Marsh
c36ce785d8 Merge branch 'main' into rdmarsh2/swift/array-content-flow 2023-07-27 19:18:03 +00:00
Geoffrey White
aa6d7c088b Swift: Add some more diverse test cases. 2023-07-27 19:35:13 +01:00
Geoffrey White
9588e68115 Swift: Add detail and spacing to the NoominalType tests. 2023-07-27 19:17:51 +01:00
Geoffrey White
3eb1bac9df Swift: Update consistency test failure (line numbers). 2023-07-27 16:11:59 +01:00
Geoffrey White
44d785fabf Swift: Make QL-for-QL happy. 2023-07-27 15:37:13 +01:00
Tony Torralba
c239a4399c Changed Struts2ActionSupportClassFieldReadSource to be a FieldValueNode instead of a field read 2023-07-27 10:39:06 +02:00
Alvaro Muñoz
97a4230d5d add change note 2023-07-27 10:39:06 +02:00
Alvaro Muñoz
f3fc56294e implement field taint inheritance for Struts2 unmarshalled objects 2023-07-27 10:39:06 +02:00
Charis Kyriakou
8438fb2310 Merge pull request #13821 from github/charisk/remove-last-updated
Remove last updated information and sorting from MRVA views
2023-07-27 08:31:00 +01:00
Tony Torralba
9d6bc76dc0 Merge pull request #13817 from atorralba/atorralba/java/non-static-fieldvaluenode-step
Java: Allow flow out of FieldValueNodes for non-static fields
2023-07-27 09:14:04 +02:00
Owen Mansel-Chan
9b2b58a823 Sync files 2023-07-26 21:48:10 +01:00
Owen Mansel-Chan
e0cc337c71 Fix DataFlow::MergePathGraph3
Need to get the signatures correct.
2023-07-26 21:48:08 +01:00
Owen Mansel-Chan
f40bcd0cdd Merge pull request #13824 from owen-mc/go/fix-compiler-error-messages-for-1.20.6
Go: Compiler error messages changed in Go 1.20.6
2023-07-26 21:46:54 +01:00
Robert Marsh
bf5ba37348 Swift: Hide InOutExpr 2023-07-26 18:42:27 +00:00
Robert Marsh
e54341a170 Swift: undo commented out line 2023-07-26 17:12:06 +00:00
Chris Smowton
c69a9ea032 Merge pull request #13793 from github/post-release-prep/codeql-cli-2.14.1
Post-release preparation for codeql-cli-2.14.1
2023-07-26 17:22:05 +01:00
Owen Mansel-Chan
778de6b5d2 Compiler error messages changed in Go 1.20.6 2023-07-26 16:55:26 +01:00
Charis Kyriakou
536fd349bd Remove last updated information and sorting from MRVA views 2023-07-26 15:32:16 +01:00
Tony Torralba
8685242c16 Add tests 2023-07-26 14:13:43 +02:00
Stephan Brandauer
24cdc962c2 Merge pull request #13818 from github/kaeluka/fix-erroneous-endpoints-that-are-sinks-and-summary-neutrals
Java: Automodel Fix, Prevent Some Erroneous Endpoints
2023-07-26 12:45:29 +02:00
Jeroen Ketema
a4a492627d Merge pull request #13775 from jketema/print-global
C++: Support printing of global and namespace variables in `PrintAST`
2023-07-26 11:29:39 +02:00
Jeroen Ketema
409471c3b2 C++: Rename getEnclosingDeclaration to getAnEnclosingDeclaration 2023-07-26 09:44:47 +02:00
Tony Torralba
602eb43109 Update partial flow test expectations 2023-07-26 09:32:13 +02:00
Robert Marsh
358737452e Swift: reverse flow steps through InOutExpr 2023-07-25 20:34:36 +00:00
Michael B. Gale
aa59741c38 Merge pull request #13794 from github/mbg/csharp/improve-tracer-command-detection
C#: Limit detection of sub-command names in tracer configuration
2023-07-25 17:01:22 +01:00
Ian Lynagh
532552a7ac Merge pull request #13751 from igfoo/igfoo/getCompilationInfo
Java: Improve the diagnostics consistency query
2023-07-25 16:54:17 +01:00
yoff
2067d393e1 Update shared/yaml/codeql/serverless/ServerLess.qll
Co-authored-by: Alex Ford <alexrford@users.noreply.github.com>
2023-07-25 17:27:45 +02:00
Rasmus Lerchedahl Petersen
b2688bba7d Python: Relax module resolution
Do not require modules to reside in a package
2023-07-25 17:24:04 +02:00
Michael B. Gale
f3c6564dc3 Comment out test that fails on Windows 2023-07-25 16:15:51 +01:00
Stephan Brandauer
08f5774d13 Java: Automodel extraction fix for application mode 2023-07-25 17:11:07 +02:00
Geoffrey White
fbbc2938c3 Merge pull request #13816 from geoffw0/contig2
Swift: Use enum content in withContiguousStorageIfAvailable model.
2023-07-25 15:57:52 +01:00
Stephan Brandauer
698b8d3c5c Java: Automodel extraction fix; previously, we treated endpoints that were marked as sinks, as well as summary-neutrals as 'erroneous' 2023-07-25 16:52:27 +02:00
Geoffrey White
ac3c4fd5ef Swift: Actually I think this is value flow. 2023-07-25 14:44:21 +01:00
Tony Torralba
b8b38e4bbe Java: Allow flow out of FieldValueNodes for non-static fields 2023-07-25 15:37:41 +02:00
Geoffrey White
5188095529 Swift: Use enum content in withContiguousStorageIfAvailable model. 2023-07-25 14:33:20 +01:00
Geoffrey White
aedd073dad Merge pull request #12416 from geoffw0/contig
Swift: Model Sequence.withContiguousStorageIfAvailable
2023-07-25 14:05:07 +01:00
Mathias Vorreiter Pedersen
0a7eecf28c Merge pull request #13795 from geoffw0/enumcontent
Swift: Support EnumContent in models-as-data
2023-07-25 14:43:44 +02:00
Tony Torralba
c9fc5a54c7 Remove generated sinks and sources 2023-07-25 14:42:32 +02:00
Jeroen Ketema
4fcb576099 Merge branch 'main' into print-global 2023-07-25 14:10:33 +02:00
Mathias Vorreiter Pedersen
1f39ec3188 Merge pull request #13815 from MathiasVP/add-missing-result-test
C++: Add `cpp/invalid-pointer-deref` false negative
2023-07-25 13:12:44 +02:00
Mathias Vorreiter Pedersen
cd4ec6c996 C++: Add FN testcase. 2023-07-25 12:13:46 +02:00
Mathias Vorreiter Pedersen
60c7c84018 Merge pull request #13774 from MathiasVP/add-more-invalid-deref-documentation
C++: Add more documentation to the `cpp/invalid-pointer-deref` query
2023-07-25 12:07:25 +02:00
Mathias Vorreiter Pedersen
9f2ee0d7c2 C++: Rename 'delta' to 'deltaDerefSourceAndPai'. 2023-07-25 11:25:24 +02:00
Mathias Vorreiter Pedersen
b1c6ee4396 Update cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 11:20:49 +02:00
Mathias Vorreiter Pedersen
13989dba91 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 11:20:03 +02:00
Mathias Vorreiter Pedersen
099e11fb0c Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 11:19:49 +02:00
Mathias Vorreiter Pedersen
997eb1caf2 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 11:19:14 +02:00
Mathias Vorreiter Pedersen
2caad67980 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 11:18:54 +02:00
Mathias Vorreiter Pedersen
99f6e685c7 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 11:18:46 +02:00
Mathias Vorreiter Pedersen
54afed6e1d C++: Rename 'delta' to 'deltaDerefSourceAndPai'. 2023-07-25 11:04:18 +02:00
Mathias Vorreiter Pedersen
46832d0b17 C++: Rename 'delta1' and 'delta2' in documentation. 2023-07-25 10:50:51 +02:00
Mathias Vorreiter Pedersen
e75f604172 C++: Replace more text with formulas. 2023-07-25 10:48:23 +02:00
Mathias Vorreiter Pedersen
7f7930b3bb Update cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:36:12 +02:00
Mathias Vorreiter Pedersen
af904f5cfe Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:33:57 +02:00
Mathias Vorreiter Pedersen
97809e7646 Update cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:33:38 +02:00
Mathias Vorreiter Pedersen
e1f519fab7 Update cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:33:17 +02:00
Mathias Vorreiter Pedersen
e1763db36c Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:31:37 +02:00
Mathias Vorreiter Pedersen
9f9cf9f765 Update cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:31:06 +02:00
Mathias Vorreiter Pedersen
70ac0a5462 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:30:56 +02:00
Mathias Vorreiter Pedersen
2cfa14b91f Update cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:30:44 +02:00
Mathias Vorreiter Pedersen
5cad8ec0a2 Update cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:30:38 +02:00
Mathias Vorreiter Pedersen
a176ba262b Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:30:21 +02:00
Mathias Vorreiter Pedersen
6ebd5ab3ed Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:25:41 +02:00
Mathias Vorreiter Pedersen
0d116a00fb Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-25 10:25:34 +02:00
Arthur Baars
3767ce5a99 Merge pull request #13763 from aibaars/swift-print-cfg
Swift: improve print-cfg query
2023-07-25 10:02:18 +02:00
Mathias Vorreiter Pedersen
1612ee3e9a C++: Simplify the description of the sink. 2023-07-25 09:19:14 +02:00
Mathias Vorreiter Pedersen
55cfadb1f4 C++: Simplify the description of the source. 2023-07-25 09:13:27 +02:00
Mathias Vorreiter Pedersen
359a9e5fe8 C++: 'Step 1' does not make a lot of sense now that the files have been split. 2023-07-25 09:07:01 +02:00
Geoffrey White
374c157afe Swift: Update the taint aspect of the flowsources test to use sinks like the regular taint test. 2023-07-24 19:17:51 +01:00
Michael B. Gale
e27399c9ef Use --force for dotnet new to fix test 2023-07-24 17:59:44 +01:00
Geoffrey White
27c12de178 Merge pull request #13549 from geoffw0/badfilter
Swift: Query for bad HTML filtering regexps
2023-07-24 17:25:08 +01:00
Stephan Brandauer
2582b084f6 Merge pull request #13747 from github/tausbn/exclude-qualifier-argument-for-existing-models
Java: Exclude qualifier argument for existing models
2023-07-24 16:26:33 +02:00
Rasmus Lerchedahl Petersen
21937e6a27 python: address review comments
- rename `normalise` to `normalizePath`
- factor out `lookupValueOrEmpty`
2023-07-24 16:04:01 +02:00
yoff
c0407ae0be Apply suggestions from code review
Co-authored-by: Alex Ford <alexrford@users.noreply.github.com>
2023-07-24 15:51:27 +02:00
Mathias Vorreiter Pedersen
acb1310e99 C++: Add more documentation. 2023-07-24 15:28:36 +02:00
Geoffrey White
26d4f9f0fd Swift: Rephrase sentence that needed three commas. 2023-07-24 14:15:48 +01:00
Geoffrey White
cd3b519081 Apply suggestions from code review
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2023-07-24 14:11:21 +01:00
Mathias Vorreiter Pedersen
db8b506106 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-24 14:58:06 +02:00
Mathias Vorreiter Pedersen
88b78284ec Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-24 14:57:59 +02:00
Stephan Brandauer
13027a1094 Java: review suggestions from @atorralba 2023-07-24 14:09:10 +02:00
Stephan Brandauer
2f2f507a5d Java: drive-by change: remove obsolete custom queries from application mode characteristics 2023-07-24 13:55:53 +02:00
Jeroen Ketema
0a0e34716e Merge pull request #13811 from jketema/ternary-tests
C++: Add more IR tests for the ternary operator
2023-07-24 12:50:01 +02:00
Mathias Vorreiter Pedersen
4a276c37ac C++: Remove 'TODO' now that the implementation has been fixed. 2023-07-24 12:24:46 +02:00
Mathias Vorreiter Pedersen
4345369e9b C++: Replace 'Barrier2' with 'SizeBarrier' in QLDoc. 2023-07-24 12:22:26 +02:00
Mathias Vorreiter Pedersen
d02a1c2840 C++: Remove paragraph. 2023-07-24 12:20:38 +02:00
Mathias Vorreiter Pedersen
5edc5e7c7b C++: Reflow comments in QLDoc. 2023-07-24 12:15:57 +02:00
Mathias Vorreiter Pedersen
a272eb8447 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-24 12:14:47 +02:00
Mathias Vorreiter Pedersen
9108982b07 C++: Update example in QLDoc. 2023-07-24 12:13:31 +02:00
Mathias Vorreiter Pedersen
9cb09d6e9a Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-24 12:12:00 +02:00
Mathias Vorreiter Pedersen
aa6bf67482 Merge branch 'main' into add-more-invalid-deref-documentation 2023-07-24 12:09:19 +02:00
Mathias Vorreiter Pedersen
1fa6511482 Merge pull request #13792 from MathiasVP/swap-argument-order-in-invalid-ptr-deref
C++: Swap argument order in `cpp/invalid-pointer-deref`
2023-07-24 12:05:38 +02:00
Mathias Vorreiter Pedersen
f0ab3a3c84 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-24 12:04:02 +02:00
Mathias Vorreiter Pedersen
8ab2f89d53 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-07-24 12:03:52 +02:00
Mathias Vorreiter Pedersen
786c6e1c5e Merge branch 'main' into swap-argument-order-in-invalid-ptr-deref 2023-07-24 11:26:27 +02:00
Jeroen Ketema
645028e219 C++: Add more IR tests for the ternary operator 2023-07-24 11:22:27 +02:00
Mathias Vorreiter Pedersen
4676ca5a4a Merge pull request #13789 from MathiasVP/better-names-in-invalid-ptr-deref
C++: Improve names of identifiers in `cpp/invalid-pointer-deref`
2023-07-24 11:17:09 +02:00
Mathias Vorreiter Pedersen
c44507cc42 C++: 'sizeAddend' instead of 'extra'. 2023-07-24 10:57:25 +02:00
Geoffrey White
39b6d927d6 Swift: Make QL-for-QL happy (this line will be deleted at some point anyway). 2023-07-24 09:23:07 +01:00
Geoffrey White
066a6ef7c4 Swift: Change note. 2023-07-24 09:13:56 +01:00
Geoffrey White
b8f67d7e8a Swift: Test changes (not affecting results). 2023-07-24 09:03:01 +01:00
Geoffrey White
b62c86d89c Swift: Autoformat. 2023-07-24 08:45:49 +01:00
Geoffrey White
dc89e0d2b0 Swift: Change note. 2023-07-24 08:28:37 +01:00
Tony Torralba
af8612ecd2 Merge pull request #13797 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-07-24 09:12:25 +02:00
Tony Torralba
6c0d47f122 Update java/ql/lib/semmle/code/java/frameworks/InputStream.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2023-07-24 08:49:37 +02:00
Tony Torralba
4e7438ac5c Make sure that InputStreamWrapperCapturedLocalStep is indeed local 2023-07-24 08:49:37 +02:00
Tony Torralba
d3b3af8ae6 Re-adds jump step
Note that this causes FP flow in the call context test cases
2023-07-24 08:49:37 +02:00
Tony Torralba
36ff54b48b Convert jump step into local step
Note that this has FNs in the test cases where the source is used locally in the nested classes' methods
2023-07-24 08:49:37 +02:00
Tony Torralba
cc5a404149 Add more test cases 2023-07-24 08:49:36 +02:00
Tony Torralba
226103b246 Add local class test 2023-07-24 08:49:36 +02:00
Tony Torralba
f054f73836 Apply suggestions from code review
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2023-07-24 08:49:36 +02:00
Tony Torralba
1de68457ae Move steps to InputStream.qll 2023-07-24 08:49:36 +02:00
Tony Torralba
0156fcc381 Apply suggestions from code review
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2023-07-24 08:49:36 +02:00
Tony Torralba
3a6665b0ed Add change note 2023-07-24 08:49:36 +02:00
Tony Torralba
5330ce12cc Use new TypeInputStream 2023-07-24 08:49:34 +02:00
Tony Torralba
00e0e5a61a Java: Add taint step for InputStream wrappers 2023-07-24 08:48:04 +02:00
github-actions[bot]
419bbbc9ac Add changed framework coverage reports 2023-07-24 00:17:53 +00:00
Geoffrey White
94780aabec Swift: Effect on the taint/core test. 2023-07-21 22:34:59 +01:00
Geoffrey White
1259f8d596 Swift: Clearer syntax and a shortcut for Optional.some. 2023-07-21 22:34:59 +01:00
Geoffrey White
89e7b75ea1 Swift: Flow from optional content through "!". 2023-07-21 22:34:59 +01:00
Geoffrey White
d9187c62fe Swift: Parse MAD enum content. 2023-07-21 22:34:59 +01:00
Geoffrey White
1cfb9bbf34 Swift: Tests for enum content in MAD. 2023-07-21 22:34:58 +01:00
Michael B. Gale
a2f4628522 C#: Add integration test for tracing config fix 2023-07-21 20:14:46 +01:00
Michael B. Gale
ac389067fe C#: Limit detection of sub-command names 2023-07-21 19:05:22 +01:00
github-actions[bot]
f91b7a9342 Post-release preparation for codeql-cli-2.14.1 2023-07-21 16:16:25 +00:00
Mathias Vorreiter Pedersen
742f080a55 C++: This predicate is no longer used. 2023-07-21 16:54:46 +01:00
Mathias Vorreiter Pedersen
d350c0d5c8 C++: Accept test changes. 2023-07-21 16:54:46 +01:00
Mathias Vorreiter Pedersen
0859c4f926 C++: Fix swapped arguments in 'invalidPointerToDerefSource'. 2023-07-21 16:54:38 +01:00
Mathias Vorreiter Pedersen
69ea7d92cd Merge pull request #13790 from MathiasVP/add-invalid-ptr-false-positive
C++: Add false positive to `cpp/invalid-pointer-deref`
2023-07-21 16:42:53 +01:00
Mathias Vorreiter Pedersen
d905b1e006 C++: Add false positive. 2023-07-21 15:38:38 +01:00
Mathias Vorreiter Pedersen
83aef6fc16 C++: Write formulas instead of 'non-strictly upper bounded by'. 2023-07-21 14:56:40 +01:00
Mathias Vorreiter Pedersen
108cd7f078 C++: Use more descriptive names for identifiers in 'cpp/invalid-pointer-deref'. 2023-07-21 14:55:45 +01:00
Geoffrey White
d13170de98 Swift: Model return values. 2023-07-21 14:23:40 +01:00
Geoffrey White
52e84ba12b Swift: Add some more test cases, including handling return propagation. 2023-07-21 13:53:14 +01:00
Geoffrey White
7c0c820684 Swift: Accept fixed spurious result. 2023-07-21 11:26:11 +01:00
Geoffrey White
6110243306 Swift: Fix .expected and autoformat after merge. 2023-07-21 11:17:19 +01:00
Mathias Vorreiter Pedersen
5270cf6c41 C++: Update documentation based on PR feedback. 2023-07-21 11:09:01 +01:00
Geoffrey White
8a314dd2cf Merge branch 'main' into contig 2023-07-21 10:56:46 +01:00
Jeroen Ketema
4f57852ba0 Merge pull request #13787 from jketema/ssa-text-case
C++: Add IR SSA test case for the ternary operator
2023-07-21 11:26:26 +02:00
Mathias Vorreiter Pedersen
a7ee27ec22 C++: Fix 'begin'/'base' confusion. 2023-07-21 10:20:24 +01:00
Mathias Vorreiter Pedersen
6c3c4c302e Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2023-07-21 10:19:04 +01:00
Anders Schack-Mulligen
412cf558f2 Merge pull request #13743 from aschackmull/docs/dataflow-api
Docs: Update data flow documentation to the new API.
2023-07-21 11:07:52 +02:00
Mathias Vorreiter Pedersen
4075dacd52 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll 2023-07-21 09:55:23 +01:00
Stephan Brandauer
79da723878 Java: only assume that _manual_ MaD sinks have been fully modeled 2023-07-21 10:43:07 +02:00
Tony Torralba
3d515b18df Merge pull request #13769 from atorralba/atorralba/java/avoid-inputstream-low-confidence-dispatch
Java: Avoid low-confidence dispatch to InputStream methods
2023-07-21 10:42:34 +02:00
Mathias Vorreiter Pedersen
369cee9ed9 Update cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2023-07-21 09:32:14 +01:00
Jeroen Ketema
4c9c5d8f0c C++: Add IR SSA test case for the ternary operator 2023-07-21 10:22:34 +02:00
Geoffrey White
75c5d16406 Swift: Add a couple more test cases. 2023-07-20 16:13:57 +01:00
Geoffrey White
ec650b80fd Swift: Fix mistakes in ts in the tests and test comments. 2023-07-20 15:37:41 +01:00
Jeroen Ketema
7c429fb924 C++: Remove redundant case from shouldPrintDeclaration
A configuration should always exist, because it does not have a charpred
that could prevent this.
2023-07-20 16:11:17 +02:00
Geoffrey White
61079e07c1 Swift: Effect of merging the regex parse mode improvements from main. 2023-07-20 14:18:48 +01:00
Geoffrey White
252d969efd Merge branch 'main' into badfilter 2023-07-20 14:03:57 +01:00
Jeroen Ketema
e76dc4a1f9 C++: Support printing of global and namespace variables in PrintAST 2023-07-20 11:43:55 +02:00
Robert Marsh
41ad1ed8b4 Swift: fix cartesian product in array readStep 2023-07-19 19:12:34 +00:00
Robert Marsh
ec9997781c Swift: add test for assignment to nested arrays 2023-07-19 19:12:03 +00:00
Robert Marsh
883543fd77 Swift: force high precision for arraycontent 2023-07-19 16:31:32 +00:00
Jeroen Ketema
2a63116fc2 C++: Rename shouldPrintFunction to shouldPrintDeclaration 2023-07-19 16:55:43 +02:00
Mathias Vorreiter Pedersen
922f4d5496 C++: Add more documentation to the 'cpp/invalid-pointer-deref' query. 2023-07-19 14:42:20 +01:00
Tony Torralba
238cb26624 Add change note 2023-07-19 15:37:33 +02:00
Tony Torralba
29543f5726 Change InputStream.read from neutral to summary 2023-07-19 14:44:18 +02:00
Tony Torralba
2dbbcc2413 Java: Avoid low-confidence dispatch to InputStream methods
Also adds a neutral model for `InputStream.read`, which offers a high-confidence alternative for this method.
2023-07-19 11:30:53 +02:00
Anders Schack-Mulligen
afc46576f0 Docs: Review fix. 2023-07-19 09:14:33 +02:00
Robert Marsh
093c6905dd Swift: only read ArrayContent from subscript keypaths 2023-07-18 19:42:54 +00:00
Arthur Baars
99d8ae720f Swift: improve print-cfg query 2023-07-18 16:49:58 +02:00
Robert Marsh
bcc45658b3 Swift: Change note for ArrayContent 2023-07-18 14:12:53 +00:00
Robert Marsh
1fac08ef6c Swift: add qldoc for ArrayContent and Array models 2023-07-18 14:08:33 +00:00
Robert Marsh
dfa5e18988 Swift: autoformat 2023-07-18 14:01:30 +00:00
Paul Hodgkinson
c7084b6d8e Merge branch 'main' into java/experimental/command-injection 2023-07-18 11:38:44 +01:00
Robert Marsh
81a25b23ba Swift: fix tests for array concatenation 2023-07-17 19:10:46 +00:00
Robert Marsh
d4b635d674 Swift: add ArrayContent summary support 2023-07-17 19:09:05 +00:00
Robert Marsh
169326ffe5 Swift: support array keypath reads in dataflow 2023-07-17 18:05:06 +00:00
Robert Marsh
0b35be284e Swift: additional dataflow tests for arrays 2023-07-17 18:03:20 +00:00
Geoffrey White
05cb429635 Swift: Add CfgConsistency.expected. 2023-07-17 15:59:18 +01:00
Robert Marsh
ef9376d39c Swift: more ArrayContent tests 2023-07-17 14:58:40 +00:00
Geoffrey White
70a9fe3974 Swift: Change note. 2023-07-17 15:42:56 +01:00
Geoffrey White
eca2c21af5 Swift: Model referrerURL. 2023-07-17 15:42:51 +01:00
Geoffrey White
bc4724b1fb Swift: Test the customurlschemes fields that inherit taint. 2023-07-17 15:39:02 +01:00
Ian Lynagh
8a0286ec34 Java: Improve the diagnostics consistency query
Diagnostics can be easier to read if you see them in the order in which
they were generated. By selecting the compilation and indexes, they get
sorted by the testsuite driver.

d.getCompilationInfo(c, f, i) would be a bit more natural as
d = c.getDiagnostic(f, i), but currently we don't import Diagnostic into
the default ('import java') namespace, and I don't think it's worth
changing that for this.
2023-07-17 15:37:05 +01:00
Max Schaefer
9432fec612 JavaScript: Improve qhelp for js/server-crash.
The examples now use `fs.access` instead of the deprecated `fs.exists`. I have also rewritten the async/await example, since as of Node.js v15 the default behaviour for uncaught exceptions has changed to terminating the process instead of logging a warning, making the previous advice incorrect.
2023-07-17 14:44:23 +01:00
Maiky
3f36d3244b Fix singleton set literal 2023-07-15 00:18:21 +02:00
Maiky
378313332b Fix sink 2023-07-14 20:55:24 +02:00
Taus
6b425f1395 Java: Revert definition of isNeutral
Reverts the change made in
daf2743143

With the change in the aforementioned commit, we were extracting candidates for endpoints that
had a neutral _summary_ model. These are bad candidates, as they have already been triaged.
2023-07-14 14:45:22 +02:00
Taus
6793bc6c6b Java: Exclude qualifier argument for existing models
Excludes candadites for `Argument[this]` where we already have a model that covers a
different argument of the containing call.
2023-07-14 14:26:21 +02:00
Alex Ford
a524735236 Merge branch 'main' into maikypedia/ldap-injection 2023-07-14 12:05:17 +01:00
Rasmus Wriedt Larsen
0db535bdd7 Python: Minor naming update 2023-07-14 12:54:54 +02:00
Asger F
2c3117a981 JS: Add documentation for Fuzzy component 2023-07-14 11:33:06 +02:00
Anders Schack-Mulligen
aaea1ad2fa Docs: Switch to PascalCase. 2023-07-14 10:18:42 +02:00
Anders Schack-Mulligen
2947f176ef Docs: Update data flow documentation to the new API. 2023-07-14 09:59:08 +02:00
Robert Marsh
42cc6448cc Swift: add DataFlow::Content for arrays 2023-07-13 20:16:21 +00:00
Asger F
eb5c600a6b Python: fix some whitespace 2023-07-13 15:42:34 +02:00
Asger F
2b0a8097e6 Python: implement Fuzzy for Python 2023-07-13 15:42:34 +02:00
Asger F
f1c82b650f Ruby: Implement Fuzzy for Ruby 2023-07-13 15:42:34 +02:00
Asger F
919cb07c1e Sync ApiGraphModels.qll 2023-07-13 15:42:33 +02:00
Asger F
f3fab587a9 JS: Add Fuzzy token in identifying access path 2023-07-13 14:01:06 +02:00
Rasmus Wriedt Larsen
991d5cc54b Python: Fix test of HttpResponse.getBody() 2023-07-13 13:57:08 +02:00
Rasmus Wriedt Larsen
64a7206f3e Python: Improve aiohttp FileResponse/StreamResponse modeling
However, notice that the concepts tests use the HttpResponse location
for the `responseBody` tag, which seems a little odd in this situation,
where they are actually separate. Will fix in next commit.
2023-07-13 13:57:08 +02:00
Rasmus Wriedt Larsen
15269c9166 Python: Add StreamResponse test 2023-07-13 13:57:08 +02:00
Rasmus Wriedt Larsen
0f9ab8f53e Python: Fixup tests
But notice that keyword argument is not handled yet
2023-07-13 13:57:08 +02:00
Asger F
7c9e1ad6ec JS: Fix accidental recursion in Vue model
The API graph entry point depended on API::Node.

This was due to depending on the the TComponent newtype which has a branch that depends on API::Node
2023-07-13 13:41:21 +02:00
Alvaro Muñoz
362e8f7dd2 remove unrelated file 2023-07-13 13:29:06 +02:00
Alvaro Muñoz
ee1ba71e5d add tests 2023-07-13 13:07:12 +02:00
Alvaro Muñoz
10cd649ba7 address code review feedback 2023-07-13 12:24:19 +02:00
Alvaro Muñoz
69efddbaef Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-07-13 12:23:00 +02:00
Maiky
1559b7da3c Update Frameworks.qll 2023-07-12 17:45:45 +02:00
Alvaro Muñoz
7a717555aa fix qldocs 2023-07-12 17:27:17 +02:00
Alvaro Muñoz
733e625080 fix change note 2023-07-12 17:26:12 +02:00
Alvaro Muñoz
f2cc2af276 aiohttp improvements 2023-07-12 17:19:56 +02:00
yoff
76455d628e Update python/ql/lib/semmle/python/frameworks/ServerLess.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-07-12 16:50:13 +02:00
Maiky
c9fadd98f4 Support CommandInjectionAdditionalFlowStep and fix doc errors 2023-07-12 16:48:27 +02:00
Rasmus Lerchedahl Petersen
02c41f3dcf JavaScript: Use shared library for serverless 2023-07-12 16:46:34 +02:00
Maiky
d7d9ffc449 Doc error
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2023-07-12 16:44:17 +02:00
Rasmus Lerchedahl Petersen
4d2ce6b2e0 python: create shared serverless module and use it
Modelled on the javascript serverless module, but
- The predicate that reports YAML files is now public
  so languages can implement their own file conventions.
- It also reports framework and runtime.
- The conveninece predicates with files still exist,
  but they only report the path.
- Handler mapping conventions are now documented.
- Use parameterised serverless module in Python,
  tests now pass.
2023-07-12 16:42:01 +02:00
Rasmus Lerchedahl Petersen
a892e83c8e python: add simple test for AWS lambda
made space for other serverless frameworks in the directory `serverless`
2023-07-12 16:42:00 +02:00
Alvaro Muñoz
ff1ae7d9c6 add change note 2023-07-12 11:05:25 +02:00
Alvaro Muñoz
0247278bad add change note 2023-07-12 11:03:24 +02:00
Maiky
cea3477ac2 Qhelp and examples 2023-07-12 02:13:07 +02:00
Maiky
c255f8717d Change hasFlowPath to flowPath
Co-authored-by: Alex Ford <alexrford@users.noreply.github.com>
2023-07-11 19:20:54 +02:00
Maiky
c4f72dd2f2 Change make to global
Co-authored-by: Alex Ford <alexrford@users.noreply.github.com>
2023-07-11 19:20:34 +02:00
Alvaro Muñoz
e8563e5dfd fix row 2023-07-11 10:47:23 +02:00
Alvaro Muñoz
2ce1192ee6 implement field taint inheritance for Struts2 unmarshalled objects 2023-07-11 10:28:14 +02:00
Geoffrey White
f45b89a3cc Swift: Add a few more variant test cases. 2023-07-11 09:26:37 +01:00
Alvaro Muñoz
047d486509 add new struts2 models 2023-07-11 10:23:26 +02:00
Maiky
e45a31744f Initial commit 2023-07-09 04:17:35 +02:00
Maiky
a3c58c66e9 Using DataFlow::ConfigSig instead of TaintTracking::Configuration 2023-07-06 03:14:49 +02:00
Paul Hodgkinson
bfbb77a796 Merge branch 'main' into java/experimental/command-injection 2023-06-29 09:51:14 +01:00
aegilops
8dbb0a51c0 Rewrote tests to work 2023-06-29 09:47:03 +01:00
aegilops
01798f63f8 Switched to new dataflow and added a test (but it doesn't produce results yet) 2023-06-28 17:14:39 +01:00
Alexandre Boulgakov
30615308b4 Swift: Mangle AssociatedTypeDecl. 2023-06-28 13:09:09 +01:00
Alexandre Boulgakov
b807d005ec Swift: Add missing #include. 2023-06-28 12:50:01 +01:00
Alexandre Boulgakov
4ed90d5234 Swift: Remove AbstractTypeParamDecl mangling.
AbstractTypeParamDecl itself was removed in 36b3f0ee12.
2023-06-28 12:34:01 +01:00
Alexandre Boulgakov
81372d0b63 Merge commit '36d86787e6fbbb158a148f93eb63f829134fd6b1' into alexdenisov+redsun82/tuple-mangling 2023-06-28 12:21:59 +01:00
Geoffrey White
922fc3aba7 Swift: Correct qhelp link to example. 2023-06-23 17:10:31 +01:00
Geoffrey White
c11ce4ce68 Swift: Add change note. 2023-06-23 16:59:26 +01:00
Geoffrey White
958ae24a61 Swift: Update the qhelp and example. 2023-06-23 16:59:25 +01:00
Geoffrey White
e74eccdd97 Swift: Get the query 'working' (though lots of issues with results right now). 2023-06-23 16:59:25 +01:00
Geoffrey White
38ecfd8233 Swift: Copy the query, qhelp, example from Ruby. 2023-06-23 16:59:25 +01:00
Geoffrey White
df58902674 Swift: Duplicate some of the Regex cases with different constructions. 2023-06-23 16:59:25 +01:00
Geoffrey White
d5f4939719 Swift: Add tests for bad tag filter query. 2023-06-23 16:21:10 +01:00
aegilops
23bf8470ce Removed .md and made class change 2023-06-19 17:29:17 +01:00
aegilops
8c9ccab9c9 Autoformat 2023-06-19 11:53:53 +01:00
Paul Hodgkinson
72d9d4736e Merge branch 'main' into java/experimental/command-injection 2023-06-19 11:51:45 +01:00
aegilops
2112d73a6a Autoformat 2023-06-19 11:50:54 +01:00
aegilops
1a108fb1c9 Changed to for constant string 2023-06-19 11:46:08 +01:00
aegilops
7c235e3786 Fixed linting issues. Will not fix instanceof, that is necessary 2023-06-19 11:41:23 +01:00
aegilops
8c73fbeabe Formatted 2023-06-16 17:33:21 +01:00
aegilops
55eeb00309 Added experimental tag 2023-06-16 17:27:01 +01:00
aegilops
b6c35dd88c Added experimental version of Java Command Injection query, to be more sensitive to unusual code constructs 2023-06-16 17:12:53 +01:00
Paolo Tranquilli
c612a7a16b Revert "Swift: deduplicate accessors and params correctly"
This reverts commit bab4eeeb55.
2023-06-12 17:14:20 +02:00
Paolo Tranquilli
1d32f6efc3 Merge branch 'main' into alexdenisov+redsun82/tuple-mangling 2023-06-12 16:49:45 +02:00
Paolo Tranquilli
bab4eeeb55 Swift: deduplicate accessors and params correctly 2023-06-12 16:48:03 +02:00
Paolo Tranquilli
c42e65cbaf Merge branch 'main' into alexdenisov+redsun82/tuple-mangling 2023-06-09 14:37:20 +02:00
Ian Lynagh
22fe055e53 Kotlin: Tweak our JSON escaping
We were escaping '/', but I don't think there is any need to do so. It
just happens to have a nice escape in the spec. Escaping it might
filenames annoying to work with.

I've also added escaping for the other control characters that we're
meant to escape.
2023-06-08 15:20:30 +01:00
Paolo Tranquilli
0b09fdae43 Merge branch 'main' into alexdenisov+redsun82/tuple-mangling 2023-06-07 10:40:38 +02:00
Arthur Baars
e93b44670f Ruby: printCfg: only show graph for selected CfgScope 2023-05-31 16:08:01 +02:00
Paolo Tranquilli
edb822279b Swift: update comments to the mangler 2023-05-31 10:12:31 +02:00
Paolo Tranquilli
70ff401f21 Swift: replace internal swift mangler with our own
Our mangler is split in two version:
* `SwiftTrapMangler`, with the same behaviour as the previous
  `SwiftMangler`, constructing mangled names with trap label references
* `SwiftRecursiveMangler` that replaces trap label references with
  recursive calls to its own `mangle` functions, effectively rolling out
  the entire chain of references

The latter is used to create lazy trap file names. Hashing is used to
avoid excessively long filenames.
2023-05-31 09:52:20 +02:00
Paolo Tranquilli
ab3b87a3f2 Swift: add nested generic function to test 2023-05-31 09:52:20 +02:00
Paolo Tranquilli
2183d380db Swift: implement review suggestions 2023-05-30 10:30:44 +02:00
Maiky
a8f887e3f9 naming error 2023-05-29 16:33:58 +02:00
Maiky
2d8318dc02 remove unnecessary imports and edit .qhelp 2023-05-28 17:40:31 +02:00
Maiky
065b69460d remove space 2023-05-28 17:34:16 +02:00
Maiky
5e33f14ff1 Undo Concepts changes 2023-05-28 17:33:05 +02:00
Maiky
d45d046fa7 Add test file and .expected 2023-05-28 17:29:34 +02:00
Maiky
d8bc818d5a add Change note 2023-05-28 16:50:36 +02:00
Maiky
dfbf259e2d typo 2023-05-26 18:14:49 +02:00
Maiky
9ab6eabd15 add filterTaintStep, qhelp file and test files 2023-05-26 18:13:58 +02:00
Paolo Tranquilli
15047368e8 Swift: add a warning to unmangled types 2023-05-26 15:12:21 +02:00
Paolo Tranquilli
3f7c4dec25 Swift: add a header comment to SwiftMangler 2023-05-26 15:05:40 +02:00
Paolo Tranquilli
d81dc274f6 Swift: make a TODO more assertive as there is a draft PR already 2023-05-26 14:45:29 +02:00
Paolo Tranquilli
05ed66ad8f Swift: remove debugging print 2023-05-26 14:42:02 +02:00
Paolo Tranquilli
5a2433244e Swift: remove now passing PrintAstConsistency check 2023-05-26 08:58:49 +02:00
Paolo Tranquilli
b0882a9e5f Merge branch 'main' into alexdenisov+redsun82/tuple-mangling 2023-05-26 08:40:16 +02:00
Maiky
026d94c457 Add LDAP Injection query (incomplete) 2023-05-25 22:51:25 +02:00
Paolo Tranquilli
2fb6cdc19b Merge branch 'main' into alexdenisov+redsun82/tuple-mangling 2023-05-24 11:16:59 +02:00
Paolo Tranquilli
c65c65557d Swift: accept string representation changes in test 2023-05-02 10:49:31 +02:00
Paolo Tranquilli
3685590a12 Swift: remove version control markers 2023-05-02 10:45:43 +02:00
Paolo Tranquilli
7adcd0d043 Swift: small tweak to visitBuiltinType 2023-05-02 10:45:43 +02:00
Paolo Tranquilli
87c73879cb Swift: add explanation to getExtensionIndex 2023-05-02 10:45:43 +02:00
Paolo Tranquilli
826d7c7dbe Swift: preload extension indexes
Finding each extension declaration separately within its parent seemed
to create an `O(n^2)` noticeable performance problem. This is solved
by preloading indexes and storing them in a map, so as to iterate
through the parent of an extension only once per parent instead of once
per extension.
2023-05-02 10:45:43 +02:00
Paolo Tranquilli
146591934a Swift: clean up SwiftMangler 2023-05-02 10:45:43 +02:00
Paolo Tranquilli
f6a6958c03 Swift: mangle ParameterizedProtocolType 2023-05-02 10:45:43 +02:00
Alex Denisov
92c20be038 Swift: change indexing for extension declarations to make them more stable 2023-05-02 10:45:42 +02:00
Alex Denisov
6c954eae3c Swift: handle isolated types 2023-05-02 10:45:42 +02:00
Paolo Tranquilli
dfbc248e78 Swift: mangle opened archetype and fix global actor 2023-05-02 10:45:42 +02:00
Paolo Tranquilli
0aed7d56c2 Swift: more mangling 2023-05-02 10:45:42 +02:00
Paolo Tranquilli
2592129d83 Swift: mangle remaining unmangled types appearing during test run 2023-05-02 10:45:42 +02:00
Paolo Tranquilli
c8ca6057d3 Swift: mangle several new things 2023-05-02 10:45:40 +02:00
Paolo Tranquilli
4ac91ea1b2 Swift: mangle function types, type paramters, metatypes, dependent member types 2023-05-02 10:39:46 +02:00
Paolo Tranquilli
dcca0278b8 Swift: add more functions to deduplication test 2023-05-02 09:54:59 +02:00
Paolo Tranquilli
ab5b267a39 Swift: add GenericFunctionType to deduplication test 2023-05-02 09:54:04 +02:00
Paolo Tranquilli
2eb82fede7 Swift: restrict Type.ql for deduplication test 2023-05-02 09:52:34 +02:00
Paolo Tranquilli
b6146478dc Swift: mangle nominal and bound generic types 2023-05-02 09:49:48 +02:00
Paolo Tranquilli
1274aaaf9c Swift: mangle GenericTypeDecl 2023-05-02 09:49:48 +02:00
Paolo Tranquilli
476cf72710 Swift: mangle AnyGenericType 2023-05-02 09:49:48 +02:00
Paolo Tranquilli
348bc964be Swift: turn current decl mangling into visitor 2023-05-02 09:49:48 +02:00
Paolo Tranquilli
b269bd5010 Swift: mangle builtin and tuple types 2023-05-02 09:49:48 +02:00
Geoffrey White
9a27016663 Swift: Make QL-for-QL happy. 2023-03-14 10:24:55 +00:00
Geoffrey White
f1905f21b2 Swift: Remove special case from swift/unsafe-js-eval. 2023-03-06 21:02:42 +00:00
Geoffrey White
4380495eed Swift: Model Sequence.withContiguousSrtorageIfAvailable. 2023-03-06 20:59:17 +00:00
934 changed files with 46791 additions and 66113 deletions

View File

@@ -1 +1 @@
6.1.2
6.3.1

View File

@@ -1,24 +1,4 @@
{
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll"
],
"DataFlowImpl Java/C++/C#/Go/Python/Ruby/Swift": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll"
],
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift Legacy Configuration": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll",
@@ -42,7 +22,6 @@
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
@@ -53,16 +32,6 @@
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll"
],
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift Common": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll"
],
"TaintTracking Java/C++/C#/Go/Python/Ruby/Swift": [
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll",
@@ -514,11 +483,6 @@
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
],
"CFG": [
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
"ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll",
"swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll"
],
"TypeTracker": [
"python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll",
"ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll"

View File

@@ -327,7 +327,7 @@ namespace Semmle.Autobuild.Cpp.Tests
{
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0;
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"""] = 0;
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program^ Files^ ^(x86^)\Microsoft^ Visual^ Studio^ 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"""] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;

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: Remove _Float128 type
compatibility: full

View File

@@ -1,3 +1,22 @@
## 0.9.1
No user-facing changes.
## 0.9.0
### Breaking Changes
* The `shouldPrintFunction` predicate from `PrintAstConfiguration` has been replaced by `shouldPrintDeclaration`. Users should now override `shouldPrintDeclaration` if they want to limit the declarations that should be printed.
* The `shouldPrintFunction` predicate from `PrintIRConfiguration` has been replaced by `shouldPrintDeclaration`. Users should now override `shouldPrintDeclaration` if they want to limit the declarations that should be printed.
### Major Analysis Improvements
* The `PrintAST` library now also prints global and namespace variables and their initializers.
### Minor Analysis Improvements
* The `_Float128x` type is no longer exposed as a builtin type. As this type could not occur any code base, this should only affect queries that explicitly looked at the builtin types.
## 0.8.1
### Deprecated APIs

View File

@@ -0,0 +1,14 @@
## 0.9.0
### Breaking Changes
* The `shouldPrintFunction` predicate from `PrintAstConfiguration` has been replaced by `shouldPrintDeclaration`. Users should now override `shouldPrintDeclaration` if they want to limit the declarations that should be printed.
* The `shouldPrintFunction` predicate from `PrintIRConfiguration` has been replaced by `shouldPrintDeclaration`. Users should now override `shouldPrintDeclaration` if they want to limit the declarations that should be printed.
### Major Analysis Improvements
* The `PrintAST` library now also prints global and namespace variables and their initializers.
### Minor Analysis Improvements
* The `_Float128x` type is no longer exposed as a builtin type. As this type could not occur any code base, this should only affect queries that explicitly looked at the builtin types.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.8.1
lastReleaseVersion: 0.9.1

View File

@@ -18,10 +18,10 @@ external string selectedSourceFile();
class Cfg extends PrintAstConfiguration {
/**
* Holds if the AST for `func` should be printed.
* Print All functions from the selected file.
* Holds if the AST for `decl` should be printed.
* Print All declarations from the selected file.
*/
override predicate shouldPrintFunction(Function func) {
func.getFile() = getFileBySourceArchiveName(selectedSourceFile())
override predicate shouldPrintDeclaration(Declaration decl) {
decl.getFile() = getFileBySourceArchiveName(selectedSourceFile())
}
}

View File

@@ -1,11 +1,12 @@
name: codeql/cpp-all
version: 0.8.1
version: 0.9.1
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
library: true
upgrades: upgrades
dependencies:
codeql/dataflow: ${workspace}
codeql/ssa: ${workspace}
codeql/tutorial: ${workspace}
codeql/util: ${workspace}

View File

@@ -6,11 +6,9 @@ private import PrintAST
* that requests that function, or no `PrintASTConfiguration` exists.
*/
private predicate shouldPrintDeclaration(Declaration decl) {
not decl instanceof Function
not (decl instanceof Function or decl instanceof GlobalOrNamespaceVariable)
or
not exists(PrintAstConfiguration c)
or
exists(PrintAstConfiguration config | config.shouldPrintFunction(decl))
exists(PrintAstConfiguration config | config.shouldPrintDeclaration(decl))
}
/**

View File

@@ -9,13 +9,13 @@ import cpp
import PrintAST
/**
* Temporarily tweak this class or make a copy to control which functions are
* Temporarily tweak this class or make a copy to control which declarations are
* printed.
*/
class Cfg extends PrintAstConfiguration {
/**
* TWEAK THIS PREDICATE AS NEEDED.
* Holds if the AST for `func` should be printed.
* Holds if the AST for `decl` should be printed.
*/
override predicate shouldPrintFunction(Function func) { any() }
override predicate shouldPrintDeclaration(Declaration decl) { any() }
}

View File

@@ -1,9 +1,9 @@
/**
* Provides queries to pretty-print a C++ AST as a graph.
*
* By default, this will print the AST for all functions in the database. To change this behavior,
* extend `PrintASTConfiguration` and override `shouldPrintFunction` to hold for only the functions
* you wish to view the AST for.
* By default, this will print the AST for all functions and global and namespace variables in
* the database. To change this behavior, extend `PrintASTConfiguration` and override
* `shouldPrintDeclaration` to hold for only the declarations you wish to view the AST for.
*/
import cpp
@@ -12,7 +12,7 @@ private import semmle.code.cpp.Print
private newtype TPrintAstConfiguration = MkPrintAstConfiguration()
/**
* The query can extend this class to control which functions are printed.
* The query can extend this class to control which declarations are printed.
*/
class PrintAstConfiguration extends TPrintAstConfiguration {
/**
@@ -21,14 +21,16 @@ class PrintAstConfiguration extends TPrintAstConfiguration {
string toString() { result = "PrintASTConfiguration" }
/**
* Holds if the AST for `func` should be printed. By default, holds for all
* functions.
* Holds if the AST for `decl` should be printed. By default, holds for all
* functions and global and namespace variables. Currently, does not support any
* other declaration types.
*/
predicate shouldPrintFunction(Function func) { any() }
predicate shouldPrintDeclaration(Declaration decl) { any() }
}
private predicate shouldPrintFunction(Function func) {
exists(PrintAstConfiguration config | config.shouldPrintFunction(func))
private predicate shouldPrintDeclaration(Declaration decl) {
exists(PrintAstConfiguration config | config.shouldPrintDeclaration(decl)) and
(decl instanceof Function or decl instanceof GlobalOrNamespaceVariable)
}
bindingset[s]
@@ -69,7 +71,7 @@ private predicate locationSortKeys(Locatable ast, string file, int line, int col
)
}
private Function getEnclosingFunction(Locatable ast) {
private Declaration getAnEnclosingDeclaration(Locatable ast) {
result = ast.(Expr).getEnclosingFunction()
or
result = ast.(Stmt).getEnclosingFunction()
@@ -78,6 +80,10 @@ private Function getEnclosingFunction(Locatable ast) {
or
result = ast.(Parameter).getFunction()
or
result = ast.(Expr).getEnclosingDeclaration()
or
result = ast.(Initializer).getDeclaration()
or
result = ast
}
@@ -86,21 +92,21 @@ private Function getEnclosingFunction(Locatable ast) {
* nodes for things like parameter lists and constructor init lists.
*/
private newtype TPrintAstNode =
TAstNode(Locatable ast) { shouldPrintFunction(getEnclosingFunction(ast)) } or
TAstNode(Locatable ast) { shouldPrintDeclaration(getAnEnclosingDeclaration(ast)) } or
TDeclarationEntryNode(DeclStmt stmt, DeclarationEntry entry) {
// We create a unique node for each pair of (stmt, entry), to avoid having one node with
// multiple parents due to extractor bug CPP-413.
stmt.getADeclarationEntry() = entry and
shouldPrintFunction(stmt.getEnclosingFunction())
shouldPrintDeclaration(stmt.getEnclosingFunction())
} or
TParametersNode(Function func) { shouldPrintFunction(func) } or
TParametersNode(Function func) { shouldPrintDeclaration(func) } or
TConstructorInitializersNode(Constructor ctor) {
ctor.hasEntryPoint() and
shouldPrintFunction(ctor)
shouldPrintDeclaration(ctor)
} or
TDestructorDestructionsNode(Destructor dtor) {
dtor.hasEntryPoint() and
shouldPrintFunction(dtor)
shouldPrintDeclaration(dtor)
}
/**
@@ -158,10 +164,10 @@ class PrintAstNode extends TPrintAstNode {
/**
* Holds if this node should be printed in the output. By default, all nodes
* within a function are printed, but the query can override
* `PrintASTConfiguration.shouldPrintFunction` to filter the output.
* within functions and global and namespace variables are printed, but the query
* can override `PrintASTConfiguration.shouldPrintDeclaration` to filter the output.
*/
final predicate shouldPrint() { shouldPrintFunction(this.getEnclosingFunction()) }
final predicate shouldPrint() { shouldPrintDeclaration(this.getEnclosingDeclaration()) }
/**
* Gets the children of this node.
@@ -229,10 +235,15 @@ class PrintAstNode extends TPrintAstNode {
abstract string getChildAccessorPredicateInternal(int childIndex);
/**
* Gets the `Function` that contains this node.
* Gets the `Declaration` that contains this node.
*/
private Function getEnclosingFunction() {
result = this.getParent*().(FunctionNode).getFunction()
private Declaration getEnclosingDeclaration() { result = this.getParent*().getDeclaration() }
/**
* Gets the `Declaration` this node represents.
*/
private Declaration getDeclaration() {
result = this.(AstNode).getAst() and shouldPrintDeclaration(result)
}
}
@@ -571,16 +582,53 @@ class DestructorDestructionsNode extends PrintAstNode, TDestructorDestructionsNo
final Destructor getDestructor() { result = dtor }
}
abstract private class FunctionOrGlobalOrNamespaceVariableNode extends AstNode {
override string toString() { result = qlClass(ast) + getIdentityString(ast) }
private int getOrder() {
this =
rank[result](FunctionOrGlobalOrNamespaceVariableNode node, Declaration decl, string file,
int line, int column |
node.getAst() = decl and
locationSortKeys(decl, file, line, column)
|
node order by file, line, column, getIdentityString(decl)
)
}
override string getProperty(string key) {
result = super.getProperty(key)
or
key = "semmle.order" and result = this.getOrder().toString()
}
}
/**
* A node representing a `GlobalOrNamespaceVariable`.
*/
class GlobalOrNamespaceVariableNode extends FunctionOrGlobalOrNamespaceVariableNode {
GlobalOrNamespaceVariable var;
GlobalOrNamespaceVariableNode() { var = ast }
override PrintAstNode getChildInternal(int childIndex) {
childIndex = 0 and
result.(AstNode).getAst() = var.getInitializer()
}
override string getChildAccessorPredicateInternal(int childIndex) {
childIndex = 0 and result = "getInitializer()"
}
}
/**
* A node representing a `Function`.
*/
class FunctionNode extends AstNode {
class FunctionNode extends FunctionOrGlobalOrNamespaceVariableNode {
Function func;
FunctionNode() { func = ast }
override string toString() { result = qlClass(func) + getIdentityString(func) }
override PrintAstNode getChildInternal(int childIndex) {
childIndex = 0 and
result.(ParametersNode).getFunction() = func
@@ -604,31 +652,10 @@ class FunctionNode extends AstNode {
or
childIndex = 3 and result = "<destructions>"
}
private int getOrder() {
this =
rank[result](FunctionNode node, Function function, string file, int line, int column |
node.getAst() = function and
locationSortKeys(function, file, line, column)
|
node order by file, line, column, getIdentityString(function)
)
}
override string getProperty(string key) {
result = super.getProperty(key)
or
key = "semmle.order" and result = this.getOrder().toString()
}
/**
* Gets the `Function` this node represents.
*/
final Function getFunction() { result = func }
}
private string getChildAccessorWithoutConversions(Locatable parent, Element child) {
shouldPrintFunction(getEnclosingFunction(parent)) and
shouldPrintDeclaration(getAnEnclosingDeclaration(parent)) and
(
exists(Stmt s | s = parent |
namedStmtChildPredicates(s, child, result)
@@ -647,7 +674,7 @@ private string getChildAccessorWithoutConversions(Locatable parent, Element chil
}
private predicate namedStmtChildPredicates(Locatable s, Element e, string pred) {
shouldPrintFunction(getEnclosingFunction(s)) and
shouldPrintDeclaration(getAnEnclosingDeclaration(s)) and
(
exists(int n | s.(BlockStmt).getStmt(n) = e and pred = "getStmt(" + n + ")")
or
@@ -735,7 +762,7 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
}
private predicate namedExprChildPredicates(Expr expr, Element ele, string pred) {
shouldPrintFunction(expr.getEnclosingFunction()) and
shouldPrintDeclaration(expr.getEnclosingDeclaration()) and
(
expr.(Access).getTarget() = ele and pred = "getTarget()"
or

View File

@@ -814,9 +814,6 @@ private predicate floatingPointTypeMapping(
// _Float128
kind = 49 and base = 2 and domain = TRealDomain() and realKind = 49 and extended = false
or
// _Float128x
kind = 50 and base = 2 and domain = TRealDomain() and realKind = 50 and extended = true
or
// _Float16
kind = 52 and base = 2 and domain = TRealDomain() and realKind = 52 and extended = false
or

View File

@@ -26,6 +26,8 @@ import cpp
* global (inter-procedural) data flow analyses.
*/
deprecated module DataFlow {
import semmle.code.cpp.dataflow.internal.DataFlow
private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific
private import codeql.dataflow.DataFlow
import DataFlowMake<CppOldDataFlow>
import semmle.code.cpp.dataflow.internal.DataFlowImpl1
}

View File

@@ -1,433 +0,0 @@
/**
* Provides an implementation of global (interprocedural) data flow. This file
* re-exports the local (intraprocedural) data flow analysis from
* `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed
* through the `Global` and `GlobalWithState` modules.
*/
private import DataFlowImplCommon
private import DataFlowImplSpecific::Private
import DataFlowImplSpecific::Public
import DataFlowImplCommonPublic
private import DataFlowImpl
/** An input configuration for data flow. */
signature module ConfigSig {
/**
* Holds if `source` is a relevant data flow source.
*/
predicate isSource(Node source);
/**
* Holds if `sink` is a relevant data flow sink.
*/
predicate isSink(Node sink);
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
default predicate isBarrier(Node node) { none() }
/** Holds if data flow into `node` is prohibited. */
default predicate isBarrierIn(Node node) { none() }
/** Holds if data flow out of `node` is prohibited. */
default predicate isBarrierOut(Node node) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
default predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
/**
* Holds if an arbitrary number of implicit read steps of content `c` may be
* taken at `node`.
*/
default predicate allowImplicitRead(Node node, ContentSet c) { none() }
/**
* Holds if `node` should never be skipped over in the `PathGraph` and in path
* explanations.
*/
default predicate neverSkip(Node node) {
isAdditionalFlowStep(node, _) or isAdditionalFlowStep(_, node)
}
/**
* Gets the virtual dispatch branching limit when calculating field flow.
* This can be overridden to a smaller value to improve performance (a
* value of 0 disables field flow), or a larger value to get more results.
*/
default int fieldFlowBranchLimit() { result = 2 }
/**
* Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths.
*
* - `FeatureHasSourceCallContext`:
* Assume that sources have some existing call context to disallow
* conflicting return-flow directly following the source.
* - `FeatureHasSinkCallContext`:
* Assume that sinks have some existing call context to disallow
* conflicting argument-to-parameter flow directly preceding the sink.
* - `FeatureEqualSourceSinkCallContext`:
* Implies both of the above and additionally ensures that the entire flow
* path preserves the call context.
*
* These features are generally not relevant for typical end-to-end data flow
* queries, but should only be used for constructing paths that need to
* somehow be pluggable in another path context.
*/
default FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `flowPath`. */
default predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `flowPath`. */
default predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if hidden nodes should be included in the data flow graph.
*
* This feature should only be used for debugging or when the data flow graph
* is not visualized (as it is in a `path-problem` query).
*/
default predicate includeHiddenNodes() { none() }
}
/** An input configuration for data flow using flow state. */
signature module StateConfigSig {
bindingset[this]
class FlowState;
/**
* Holds if `source` is a relevant data flow source with the given initial
* `state`.
*/
predicate isSource(Node source, FlowState state);
/**
* Holds if `sink` is a relevant data flow sink accepting `state`.
*/
predicate isSink(Node sink, FlowState state);
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
default predicate isBarrier(Node node) { none() }
/**
* Holds if data flow through `node` is prohibited when the flow state is
* `state`.
*/
default predicate isBarrier(Node node, FlowState state) { none() }
/** Holds if data flow into `node` is prohibited. */
default predicate isBarrierIn(Node node) { none() }
/** Holds if data flow out of `node` is prohibited. */
default predicate isBarrierOut(Node node) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
default predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
* This step is only applicable in `state1` and updates the flow state to `state2`.
*/
default predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
none()
}
/**
* Holds if an arbitrary number of implicit read steps of content `c` may be
* taken at `node`.
*/
default predicate allowImplicitRead(Node node, ContentSet c) { none() }
/**
* Holds if `node` should never be skipped over in the `PathGraph` and in path
* explanations.
*/
default predicate neverSkip(Node node) {
isAdditionalFlowStep(node, _) or
isAdditionalFlowStep(_, node) or
isAdditionalFlowStep(node, _, _, _) or
isAdditionalFlowStep(_, _, node, _)
}
/**
* Gets the virtual dispatch branching limit when calculating field flow.
* This can be overridden to a smaller value to improve performance (a
* value of 0 disables field flow), or a larger value to get more results.
*/
default int fieldFlowBranchLimit() { result = 2 }
/**
* Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths.
*
* - `FeatureHasSourceCallContext`:
* Assume that sources have some existing call context to disallow
* conflicting return-flow directly following the source.
* - `FeatureHasSinkCallContext`:
* Assume that sinks have some existing call context to disallow
* conflicting argument-to-parameter flow directly preceding the sink.
* - `FeatureEqualSourceSinkCallContext`:
* Implies both of the above and additionally ensures that the entire flow
* path preserves the call context.
*
* These features are generally not relevant for typical end-to-end data flow
* queries, but should only be used for constructing paths that need to
* somehow be pluggable in another path context.
*/
default FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `flowPath`. */
default predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `flowPath`. */
default predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if hidden nodes should be included in the data flow graph.
*
* This feature should only be used for debugging or when the data flow graph
* is not visualized (as it is in a `path-problem` query).
*/
default predicate includeHiddenNodes() { none() }
}
/**
* Gets the exploration limit for `partialFlow` and `partialFlowRev`
* measured in approximate number of interprocedural steps.
*/
signature int explorationLimitSig();
/**
* The output of a global data flow computation.
*/
signature module GlobalFlowSig {
/**
* A `Node` augmented with a call context (except for sinks) and an access path.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode;
/**
* Holds if data can flow from `source` to `sink`.
*
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate flowPath(PathNode source, PathNode sink);
/**
* Holds if data can flow from `source` to `sink`.
*/
predicate flow(Node source, Node sink);
/**
* Holds if data can flow from some source to `sink`.
*/
predicate flowTo(Node sink);
/**
* Holds if data can flow from some source to `sink`.
*/
predicate flowToExpr(DataFlowExpr sink);
}
/**
* Constructs a global data flow computation.
*/
module Global<ConfigSig Config> implements GlobalFlowSig {
private module C implements FullStateConfigSig {
import DefaultState<Config>
import Config
}
import Impl<C>
}
/** DEPRECATED: Use `Global` instead. */
deprecated module Make<ConfigSig Config> implements GlobalFlowSig {
import Global<Config>
}
/**
* Constructs a global data flow computation using flow state.
*/
module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig {
private module C implements FullStateConfigSig {
import Config
}
import Impl<C>
}
/** DEPRECATED: Use `GlobalWithState` instead. */
deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig {
import GlobalWithState<Config>
}
signature class PathNodeSig {
/** Gets a textual representation of this element. */
string toString();
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
);
/** Gets the underlying `Node`. */
Node getNode();
}
signature module PathGraphSig<PathNodeSig PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
predicate edges(PathNode a, PathNode b);
/** Holds if `n` is a node in the graph of data flow path explanations. */
predicate nodes(PathNode n, string key, string val);
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
}
/**
* Constructs a `PathGraph` from two `PathGraph`s by disjoint union.
*/
module MergePathGraph<
PathNodeSig PathNode1, PathNodeSig PathNode2, PathGraphSig<PathNode1> Graph1,
PathGraphSig<PathNode2> Graph2>
{
private newtype TPathNode =
TPathNode1(PathNode1 p) or
TPathNode2(PathNode2 p)
/** A node in a graph of path explanations that is formed by disjoint union of the two given graphs. */
class PathNode extends TPathNode {
/** Gets this as a projection on the first given `PathGraph`. */
PathNode1 asPathNode1() { this = TPathNode1(result) }
/** Gets this as a projection on the second given `PathGraph`. */
PathNode2 asPathNode2() { this = TPathNode2(result) }
/** Gets a textual representation of this element. */
string toString() {
result = this.asPathNode1().toString() or
result = this.asPathNode2().toString()
}
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.asPathNode1().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or
this.asPathNode2().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
Node getNode() {
result = this.asPathNode1().getNode() or
result = this.asPathNode2().getNode()
}
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) {
Graph1::edges(a.asPathNode1(), b.asPathNode1()) or
Graph2::edges(a.asPathNode2(), b.asPathNode2())
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
Graph1::nodes(n.asPathNode1(), key, val) or
Graph2::nodes(n.asPathNode2(), key, val)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Graph1::subpaths(arg.asPathNode1(), par.asPathNode1(), ret.asPathNode1(), out.asPathNode1()) or
Graph2::subpaths(arg.asPathNode2(), par.asPathNode2(), ret.asPathNode2(), out.asPathNode2())
}
}
}
/**
* Constructs a `PathGraph` from three `PathGraph`s by disjoint union.
*/
module MergePathGraph3<
PathNodeSig PathNode1, PathNodeSig PathNode2, PathNodeSig PathNode3,
PathGraphSig<PathNode1> Graph1, PathGraphSig<PathNode2> Graph2, PathGraphSig<PathNode3> Graph3>
{
private module MergedInner = MergePathGraph<PathNode1, PathNode2, Graph1, Graph2>;
private module Merged =
MergePathGraph<MergedInner::PathNode, PathNode3, MergedInner::PathGraph, Graph3>;
/** A node in a graph of path explanations that is formed by disjoint union of the three given graphs. */
class PathNode instanceof Merged::PathNode {
/** Gets this as a projection on the first given `PathGraph`. */
PathNode1 asPathNode1() { result = super.asPathNode1().asPathNode1() }
/** Gets this as a projection on the second given `PathGraph`. */
PathNode2 asPathNode2() { result = super.asPathNode1().asPathNode2() }
/** Gets this as a projection on the third given `PathGraph`. */
PathNode3 asPathNode3() { result = super.asPathNode2() }
/** Gets a textual representation of this element. */
string toString() { result = super.toString() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
Node getNode() { result = super.getNode() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph = Merged::PathGraph;
}

View File

@@ -5,8 +5,8 @@ private import DataFlowUtil
/**
* Gets a function that might be called by `call`.
*/
Function viableCallable(Call call) {
result = call.getTarget()
Function viableCallable(DataFlowCall call) {
result = call.(Call).getTarget()
or
// If the target of the call does not have a body in the snapshot, it might
// be because the target is just a header declaration, and the real target
@@ -58,13 +58,13 @@ private predicate functionSignature(Function f, string qualifiedName, int nparam
* Holds if the set of viable implementations that can be called by `call`
* might be improved by knowing the call context.
*/
predicate mayBenefitFromCallContext(Call call, Function f) { none() }
predicate mayBenefitFromCallContext(DataFlowCall call, Function f) { none() }
/**
* Gets a viable dispatch target of `call` in the context `ctx`. This is
* restricted to those `call`s for which a context might make a difference.
*/
Function viableImplInCallContext(Call call, Call ctx) { none() }
Function viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() }
/** A parameter position represented by an integer. */
class ParameterPosition extends int {

File diff suppressed because it is too large Load Diff

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -1,6 +1,9 @@
/**
* Provides C++-specific definitions for use in the data flow library.
*/
private import codeql.dataflow.DataFlow
module Private {
import DataFlowPrivate
import DataFlowDispatch
@@ -9,3 +12,10 @@ module Private {
module Public {
import DataFlowUtil
}
module CppOldDataFlow implements InputSig {
import Private
import Public
Node exprNode(DataFlowExpr e) { result = Public::exprNode(e) }
}

View File

@@ -153,10 +153,11 @@ predicate jumpStep(Node n1, Node n2) { none() }
* Thus, `node2` references an object with a field `f` that contains the
* value of `node1`.
*/
predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
predicate storeStep(Node node1, ContentSet f, Node node2) {
exists(ClassAggregateLiteral aggr, Field field |
// The following line requires `node2` to be both an `ExprNode` and a
// The following lines requires `node2` to be both an `ExprNode` and a
// `PostUpdateNode`, which means it must be an `ObjectInitializerNode`.
node2 instanceof PostUpdateNode and
node2.asExpr() = aggr and
f.(FieldContent).getField() = field and
aggr.getAFieldExpr(field) = node1.asExpr()
@@ -167,12 +168,13 @@ predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
node1.asExpr() = a and
a.getLValue() = fa
) and
node2.getPreUpdateNode().asExpr() = fa.getQualifier() and
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = fa.getQualifier() and
f.(FieldContent).getField() = fa.getTarget()
)
or
exists(ConstructorFieldInit cfi |
node2.getPreUpdateNode().(PreConstructorInitThis).getConstructorFieldInit() = cfi and
node2.(PostUpdateNode).getPreUpdateNode().(PreConstructorInitThis).getConstructorFieldInit() =
cfi and
f.(FieldContent).getField() = cfi.getTarget() and
node1.asExpr() = cfi.getExpr()
)
@@ -183,7 +185,7 @@ predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
* Thus, `node1` references an object with a field `f` whose value ends up in
* `node2`.
*/
predicate readStep(Node node1, Content f, Node node2) {
predicate readStep(Node node1, ContentSet f, Node node2) {
exists(FieldAccess fr |
node1.asExpr() = fr.getQualifier() and
fr.getTarget() = f.(FieldContent).getField() and
@@ -195,7 +197,7 @@ predicate readStep(Node node1, Content f, Node node2) {
/**
* Holds if values stored inside content `c` are cleared at node `n`.
*/
predicate clearsContent(Node n, Content c) {
predicate clearsContent(Node n, ContentSet c) {
none() // stub implementation
}
@@ -235,12 +237,6 @@ class CastNode extends Node {
CastNode() { none() } // stub implementation
}
/**
* Holds if `n` should never be skipped over in the `PathGraph` and in path
* explanations.
*/
predicate neverSkipInPathGraph(Node n) { none() }
class DataFlowCallable = Function;
class DataFlowExpr = Expr;
@@ -265,8 +261,6 @@ class DataFlowCall extends Expr instanceof Call {
predicate isUnreachableInCall(Node n, DataFlowCall call) { none() } // stub implementation
int accessPathLimit() { result = 5 }
/**
* Holds if access paths with `c` at their head always should be tracked at high
* precision. This disables adaptive access path precision for such access paths.

View File

@@ -24,6 +24,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp
Config::allowImplicitRead(node, c)
or
(
Config::isSink(node) or
Config::isSink(node, _) or
Config::isAdditionalFlowStep(node, _) or
Config::isAdditionalFlowStep(node, _, _, _)

View File

@@ -26,6 +26,8 @@ import cpp
* global (inter-procedural) data flow analyses.
*/
module DataFlow {
import semmle.code.cpp.ir.dataflow.internal.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific
private import codeql.dataflow.DataFlow
import DataFlowMake<CppDataFlow>
import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl1
}

View File

@@ -152,7 +152,19 @@ class Expr extends StmtParent, @expr {
else result = this.getValue()
}
/** Holds if this expression has a value that can be determined at compile time. */
/**
* Holds if this expression has a value that can be determined at compile time.
*
* An expression has a value that can be determined at compile time when:
* - it is a compile-time constant, e.g., a literal value or the result of a constexpr
* compile-time constant;
* - it is an address of a (member) function, an address of a constexpr variable
* initialized to a constant address, or an address of an lvalue, or any of the
* previous with a constant value added to or subtracted from the address;
* - it is a reference to a (member) function, a reference to a constexpr variable
* initialized to a constant address, or a reference to an lvalue;
* - it is a non-template parameter of a uninstantiated template.
*/
cached
predicate isConstant() {
valuebind(_, underlyingElement(this))

View File

@@ -4,8 +4,8 @@
* This file contains the actual implementation of `PrintIR.ql`. For test cases and very small
* databases, `PrintIR.ql` can be run directly to dump the IR for the entire database. For most
* uses, however, it is better to write a query that imports `PrintIR.qll`, extends
* `PrintIRConfiguration`, and overrides `shouldPrintFunction()` to select a subset of functions to
* dump.
* `PrintIRConfiguration`, and overrides `shouldPrintDeclaration()` to select a subset of declarations
* to dump.
*/
import implementation.aliased_ssa.PrintIR

View File

@@ -22,6 +22,8 @@
import cpp
module DataFlow {
import semmle.code.cpp.ir.dataflow.internal.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific
private import codeql.dataflow.DataFlow
import DataFlowMake<CppDataFlow>
import semmle.code.cpp.ir.dataflow.internal.DataFlowImpl1
}

View File

@@ -1,433 +0,0 @@
/**
* Provides an implementation of global (interprocedural) data flow. This file
* re-exports the local (intraprocedural) data flow analysis from
* `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed
* through the `Global` and `GlobalWithState` modules.
*/
private import DataFlowImplCommon
private import DataFlowImplSpecific::Private
import DataFlowImplSpecific::Public
import DataFlowImplCommonPublic
private import DataFlowImpl
/** An input configuration for data flow. */
signature module ConfigSig {
/**
* Holds if `source` is a relevant data flow source.
*/
predicate isSource(Node source);
/**
* Holds if `sink` is a relevant data flow sink.
*/
predicate isSink(Node sink);
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
default predicate isBarrier(Node node) { none() }
/** Holds if data flow into `node` is prohibited. */
default predicate isBarrierIn(Node node) { none() }
/** Holds if data flow out of `node` is prohibited. */
default predicate isBarrierOut(Node node) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
default predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
/**
* Holds if an arbitrary number of implicit read steps of content `c` may be
* taken at `node`.
*/
default predicate allowImplicitRead(Node node, ContentSet c) { none() }
/**
* Holds if `node` should never be skipped over in the `PathGraph` and in path
* explanations.
*/
default predicate neverSkip(Node node) {
isAdditionalFlowStep(node, _) or isAdditionalFlowStep(_, node)
}
/**
* Gets the virtual dispatch branching limit when calculating field flow.
* This can be overridden to a smaller value to improve performance (a
* value of 0 disables field flow), or a larger value to get more results.
*/
default int fieldFlowBranchLimit() { result = 2 }
/**
* Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths.
*
* - `FeatureHasSourceCallContext`:
* Assume that sources have some existing call context to disallow
* conflicting return-flow directly following the source.
* - `FeatureHasSinkCallContext`:
* Assume that sinks have some existing call context to disallow
* conflicting argument-to-parameter flow directly preceding the sink.
* - `FeatureEqualSourceSinkCallContext`:
* Implies both of the above and additionally ensures that the entire flow
* path preserves the call context.
*
* These features are generally not relevant for typical end-to-end data flow
* queries, but should only be used for constructing paths that need to
* somehow be pluggable in another path context.
*/
default FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `flowPath`. */
default predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `flowPath`. */
default predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if hidden nodes should be included in the data flow graph.
*
* This feature should only be used for debugging or when the data flow graph
* is not visualized (as it is in a `path-problem` query).
*/
default predicate includeHiddenNodes() { none() }
}
/** An input configuration for data flow using flow state. */
signature module StateConfigSig {
bindingset[this]
class FlowState;
/**
* Holds if `source` is a relevant data flow source with the given initial
* `state`.
*/
predicate isSource(Node source, FlowState state);
/**
* Holds if `sink` is a relevant data flow sink accepting `state`.
*/
predicate isSink(Node sink, FlowState state);
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
default predicate isBarrier(Node node) { none() }
/**
* Holds if data flow through `node` is prohibited when the flow state is
* `state`.
*/
default predicate isBarrier(Node node, FlowState state) { none() }
/** Holds if data flow into `node` is prohibited. */
default predicate isBarrierIn(Node node) { none() }
/** Holds if data flow out of `node` is prohibited. */
default predicate isBarrierOut(Node node) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
default predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
* This step is only applicable in `state1` and updates the flow state to `state2`.
*/
default predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
none()
}
/**
* Holds if an arbitrary number of implicit read steps of content `c` may be
* taken at `node`.
*/
default predicate allowImplicitRead(Node node, ContentSet c) { none() }
/**
* Holds if `node` should never be skipped over in the `PathGraph` and in path
* explanations.
*/
default predicate neverSkip(Node node) {
isAdditionalFlowStep(node, _) or
isAdditionalFlowStep(_, node) or
isAdditionalFlowStep(node, _, _, _) or
isAdditionalFlowStep(_, _, node, _)
}
/**
* Gets the virtual dispatch branching limit when calculating field flow.
* This can be overridden to a smaller value to improve performance (a
* value of 0 disables field flow), or a larger value to get more results.
*/
default int fieldFlowBranchLimit() { result = 2 }
/**
* Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths.
*
* - `FeatureHasSourceCallContext`:
* Assume that sources have some existing call context to disallow
* conflicting return-flow directly following the source.
* - `FeatureHasSinkCallContext`:
* Assume that sinks have some existing call context to disallow
* conflicting argument-to-parameter flow directly preceding the sink.
* - `FeatureEqualSourceSinkCallContext`:
* Implies both of the above and additionally ensures that the entire flow
* path preserves the call context.
*
* These features are generally not relevant for typical end-to-end data flow
* queries, but should only be used for constructing paths that need to
* somehow be pluggable in another path context.
*/
default FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `flowPath`. */
default predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `flowPath`. */
default predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if hidden nodes should be included in the data flow graph.
*
* This feature should only be used for debugging or when the data flow graph
* is not visualized (as it is in a `path-problem` query).
*/
default predicate includeHiddenNodes() { none() }
}
/**
* Gets the exploration limit for `partialFlow` and `partialFlowRev`
* measured in approximate number of interprocedural steps.
*/
signature int explorationLimitSig();
/**
* The output of a global data flow computation.
*/
signature module GlobalFlowSig {
/**
* A `Node` augmented with a call context (except for sinks) and an access path.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode;
/**
* Holds if data can flow from `source` to `sink`.
*
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate flowPath(PathNode source, PathNode sink);
/**
* Holds if data can flow from `source` to `sink`.
*/
predicate flow(Node source, Node sink);
/**
* Holds if data can flow from some source to `sink`.
*/
predicate flowTo(Node sink);
/**
* Holds if data can flow from some source to `sink`.
*/
predicate flowToExpr(DataFlowExpr sink);
}
/**
* Constructs a global data flow computation.
*/
module Global<ConfigSig Config> implements GlobalFlowSig {
private module C implements FullStateConfigSig {
import DefaultState<Config>
import Config
}
import Impl<C>
}
/** DEPRECATED: Use `Global` instead. */
deprecated module Make<ConfigSig Config> implements GlobalFlowSig {
import Global<Config>
}
/**
* Constructs a global data flow computation using flow state.
*/
module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig {
private module C implements FullStateConfigSig {
import Config
}
import Impl<C>
}
/** DEPRECATED: Use `GlobalWithState` instead. */
deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig {
import GlobalWithState<Config>
}
signature class PathNodeSig {
/** Gets a textual representation of this element. */
string toString();
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
);
/** Gets the underlying `Node`. */
Node getNode();
}
signature module PathGraphSig<PathNodeSig PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
predicate edges(PathNode a, PathNode b);
/** Holds if `n` is a node in the graph of data flow path explanations. */
predicate nodes(PathNode n, string key, string val);
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
}
/**
* Constructs a `PathGraph` from two `PathGraph`s by disjoint union.
*/
module MergePathGraph<
PathNodeSig PathNode1, PathNodeSig PathNode2, PathGraphSig<PathNode1> Graph1,
PathGraphSig<PathNode2> Graph2>
{
private newtype TPathNode =
TPathNode1(PathNode1 p) or
TPathNode2(PathNode2 p)
/** A node in a graph of path explanations that is formed by disjoint union of the two given graphs. */
class PathNode extends TPathNode {
/** Gets this as a projection on the first given `PathGraph`. */
PathNode1 asPathNode1() { this = TPathNode1(result) }
/** Gets this as a projection on the second given `PathGraph`. */
PathNode2 asPathNode2() { this = TPathNode2(result) }
/** Gets a textual representation of this element. */
string toString() {
result = this.asPathNode1().toString() or
result = this.asPathNode2().toString()
}
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.asPathNode1().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or
this.asPathNode2().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
Node getNode() {
result = this.asPathNode1().getNode() or
result = this.asPathNode2().getNode()
}
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) {
Graph1::edges(a.asPathNode1(), b.asPathNode1()) or
Graph2::edges(a.asPathNode2(), b.asPathNode2())
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
Graph1::nodes(n.asPathNode1(), key, val) or
Graph2::nodes(n.asPathNode2(), key, val)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Graph1::subpaths(arg.asPathNode1(), par.asPathNode1(), ret.asPathNode1(), out.asPathNode1()) or
Graph2::subpaths(arg.asPathNode2(), par.asPathNode2(), ret.asPathNode2(), out.asPathNode2())
}
}
}
/**
* Constructs a `PathGraph` from three `PathGraph`s by disjoint union.
*/
module MergePathGraph3<
PathNodeSig PathNode1, PathNodeSig PathNode2, PathNodeSig PathNode3,
PathGraphSig<PathNode1> Graph1, PathGraphSig<PathNode2> Graph2, PathGraphSig<PathNode3> Graph3>
{
private module MergedInner = MergePathGraph<PathNode1, PathNode2, Graph1, Graph2>;
private module Merged =
MergePathGraph<MergedInner::PathNode, PathNode3, MergedInner::PathGraph, Graph3>;
/** A node in a graph of path explanations that is formed by disjoint union of the three given graphs. */
class PathNode instanceof Merged::PathNode {
/** Gets this as a projection on the first given `PathGraph`. */
PathNode1 asPathNode1() { result = super.asPathNode1().asPathNode1() }
/** Gets this as a projection on the second given `PathGraph`. */
PathNode2 asPathNode2() { result = super.asPathNode1().asPathNode2() }
/** Gets this as a projection on the third given `PathGraph`. */
PathNode3 asPathNode3() { result = super.asPathNode2() }
/** Gets a textual representation of this element. */
string toString() { result = super.toString() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
Node getNode() { result = super.getNode() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph = Merged::PathGraph;
}

View File

@@ -9,7 +9,7 @@ private import DataFlowImplCommon as DataFlowImplCommon
* Gets a function that might be called by `call`.
*/
cached
Function viableCallable(CallInstruction call) {
DataFlowCallable viableCallable(DataFlowCall call) {
DataFlowImplCommon::forceCachingInSameStage() and
result = call.getStaticCallTarget()
or
@@ -235,7 +235,7 @@ private predicate functionSignature(Function f, string qualifiedName, int nparam
* Holds if the set of viable implementations that can be called by `call`
* might be improved by knowing the call context.
*/
predicate mayBenefitFromCallContext(CallInstruction call, Function f) {
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable f) {
mayBenefitFromCallContext(call, f, _)
}
@@ -259,7 +259,7 @@ private predicate mayBenefitFromCallContext(
* Gets a viable dispatch target of `call` in the context `ctx`. This is
* restricted to those `call`s for which a context might make a difference.
*/
Function viableImplInCallContext(CallInstruction call, CallInstruction ctx) {
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
result = viableCallable(call) and
exists(int i, Function f |
mayBenefitFromCallContext(pragma[only_bind_into](call), f, i) and

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -276,6 +276,8 @@ private module Config implements FullStateConfigSig {
getConfig(state).isSource(source) and getState(state) instanceof FlowStateEmpty
}
predicate isSink(Node sink) { none() }
predicate isSink(Node sink, FlowState state) {
getConfig(state).isSink(sink, getState(state))
or

View File

@@ -1,6 +1,9 @@
/**
* Provides IR-specific definitions for use in the data flow library.
*/
private import codeql.dataflow.DataFlow
module Private {
import DataFlowPrivate
import DataFlowDispatch
@@ -9,3 +12,10 @@ module Private {
module Public {
import DataFlowUtil
}
module CppDataFlow implements InputSig {
import Private
import Public
Node exprNode(DataFlowExpr e) { result = Public::exprNode(e) }
}

View File

@@ -681,9 +681,7 @@ predicate storeStepImpl(Node node1, Content c, PostFieldUpdateNode node2, boolea
* Thus, `node2` references an object with a field `f` that contains the
* value of `node1`.
*/
predicate storeStep(Node node1, Content c, PostFieldUpdateNode node2) {
storeStepImpl(node1, c, node2, _)
}
predicate storeStep(Node node1, ContentSet c, Node node2) { storeStepImpl(node1, c, node2, _) }
/**
* Holds if `operandFrom` flows to `operandTo` using a sequence of conversion-like
@@ -744,7 +742,7 @@ predicate nodeHasInstruction(Node node, Instruction instr, int indirectionIndex)
* Thus, `node1` references an object with a field `f` whose value ends up in
* `node2`.
*/
predicate readStep(Node node1, Content c, Node node2) {
predicate readStep(Node node1, ContentSet c, Node node2) {
exists(FieldAddress fa1, Operand operand, int numberOfLoads, int indirectionIndex2 |
nodeHasOperand(node2, operand, indirectionIndex2) and
// The `1` here matches the `node2.getIndirectionIndex() = 1` conjunct
@@ -767,7 +765,7 @@ predicate readStep(Node node1, Content c, Node node2) {
/**
* Holds if values stored inside content `c` are cleared at node `n`.
*/
predicate clearsContent(Node n, Content c) {
predicate clearsContent(Node n, ContentSet c) {
n =
any(PostUpdateNode pun, Content d | d.impliesClearOf(c) and storeStepImpl(_, d, pun, true) | pun)
.getPreUpdateNode() and
@@ -792,7 +790,7 @@ predicate clearsContent(Node n, Content c) {
storeStepImpl(_, d, pun, true) and
pun.getPreUpdateNode() = n
|
c.getIndirectionIndex() = d.getIndirectionIndex()
c.(Content).getIndirectionIndex() = d.getIndirectionIndex()
)
)
}
@@ -833,12 +831,6 @@ class CastNode extends Node {
CastNode() { none() } // stub implementation
}
/**
* Holds if `n` should never be skipped over in the `PathGraph` and in path
* explanations.
*/
predicate neverSkipInPathGraph(Node n) { none() }
/**
* A function that may contain code or a variable that may contain itself. When
* flow crosses from one _enclosing callable_ to another, the interprocedural
@@ -853,7 +845,7 @@ class DataFlowType = Type;
/** A function call relevant for data flow. */
class DataFlowCall extends CallInstruction {
Function getEnclosingCallable() { result = this.getEnclosingFunction() }
DataFlowCallable getEnclosingCallable() { result = this.getEnclosingFunction() }
}
module IsUnreachableInCall {
@@ -924,8 +916,6 @@ module IsUnreachableInCall {
import IsUnreachableInCall
int accessPathLimit() { result = 5 }
/**
* Holds if access paths with `c` at their head always should be tracked at high
* precision. This disables adaptive access path precision for such access paths.
@@ -1088,7 +1078,7 @@ private IRVariable getIRVariableForParameterNode(ParameterNode p) {
/** Holds if `v` is the source variable corresponding to the parameter represented by `p`. */
pragma[nomagic]
private predicate parameterNodeHasSourceVariable(ParameterNode p, Ssa::SourceIRVariable v) {
private predicate parameterNodeHasSourceVariable(ParameterNode p, Ssa::SourceVariable v) {
v.getIRVariable() = getIRVariableForParameterNode(p) and
exists(Position pos | p.isParameterOf(_, pos) |
pos instanceof DirectPosition and

View File

@@ -781,26 +781,12 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
override Expr getDefinedExpr() { result = operand.getDef().getUnconvertedResultExpression() }
}
pragma[nomagic]
predicate indirectReturnOutNodeOperand0(CallInstruction call, Operand operand, int indirectionIndex) {
Ssa::hasRawIndirectInstruction(call, indirectionIndex) and
operandForFullyConvertedCall(operand, call)
}
pragma[nomagic]
predicate indirectReturnOutNodeInstruction0(
CallInstruction call, Instruction instr, int indirectionIndex
) {
Ssa::hasRawIndirectInstruction(call, indirectionIndex) and
instructionForFullyConvertedCall(instr, call)
}
/**
* Holds if `node` is an indirect operand with columns `(operand, indirectionIndex)`, and
* `operand` represents a use of the fully converted value of `call`.
*/
private predicate hasOperand(Node node, CallInstruction call, int indirectionIndex, Operand operand) {
indirectReturnOutNodeOperand0(call, operand, indirectionIndex) and
operandForFullyConvertedCall(operand, call) and
hasOperandAndIndex(node, operand, indirectionIndex)
}
@@ -813,7 +799,7 @@ private predicate hasOperand(Node node, CallInstruction call, int indirectionInd
private predicate hasInstruction(
Node node, CallInstruction call, int indirectionIndex, Instruction instr
) {
indirectReturnOutNodeInstruction0(call, instr, indirectionIndex) and
instructionForFullyConvertedCall(instr, call) and
hasInstructionAndIndex(node, instr, indirectionIndex)
}
@@ -1534,6 +1520,25 @@ private module Cached {
)
}
/**
* Holds if `operand.getDef() = instr`, but there exists a `StoreInstruction` that
* writes to an address that is equivalent to the value computed by `instr` in
* between `instr` and `operand`, and therefore there should not be flow from `*instr`
* to `*operand`.
*/
pragma[nomagic]
private predicate isStoredToBetween(Instruction instr, Operand operand) {
simpleOperandLocalFlowStep(pragma[only_bind_into](instr), pragma[only_bind_into](operand)) and
exists(StoreInstruction store, IRBlock block, int storeIndex, int instrIndex, int operandIndex |
store.getDestinationAddress() = instr and
block.getInstruction(storeIndex) = store and
block.getInstruction(instrIndex) = instr and
block.getInstruction(operandIndex) = operand.getUse() and
instrIndex < storeIndex and
storeIndex < operandIndex
)
}
private predicate indirectionInstructionFlow(
RawIndirectInstruction nodeFrom, IndirectOperand nodeTo
) {
@@ -1543,7 +1548,8 @@ private module Cached {
simpleOperandLocalFlowStep(pragma[only_bind_into](instr), pragma[only_bind_into](operand))
|
hasOperandAndIndex(nodeTo, operand, pragma[only_bind_into](indirectionIndex)) and
hasInstructionAndIndex(nodeFrom, instr, pragma[only_bind_into](indirectionIndex))
hasInstructionAndIndex(nodeFrom, instr, pragma[only_bind_into](indirectionIndex)) and
not isStoredToBetween(instr, operand)
)
}

View File

@@ -10,32 +10,35 @@ private import ssa0.SsaInternals as SsaInternals0
import SsaInternalsCommon
private module SourceVariables {
int getMaxIndirectionForIRVariable(IRVariable var) {
exists(Type type, boolean isGLValue |
var.getLanguageType().hasType(type, isGLValue) and
if isGLValue = true
then result = 1 + getMaxIndirectionsForType(type)
else result = getMaxIndirectionsForType(type)
)
}
cached
private newtype TSourceVariable =
TSourceIRVariable(BaseIRVariable baseVar, int ind) {
ind = [0 .. getMaxIndirectionForIRVariable(baseVar.getIRVariable())]
} or
TCallVariable(AllocationInstruction call, int ind) {
ind = [0 .. countIndirectionsForCppType(getResultLanguageType(call))]
TMkSourceVariable(SsaInternals0::SourceVariable base, int ind) {
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
}
abstract class SourceVariable extends TSourceVariable {
class SourceVariable extends TSourceVariable {
SsaInternals0::SourceVariable base;
int ind;
bindingset[ind]
SourceVariable() { any() }
SourceVariable() { this = TMkSourceVariable(base, ind) }
/** Gets the IR variable associated with this `SourceVariable`, if any. */
IRVariable getIRVariable() { result = base.(BaseIRVariable).getIRVariable() }
/**
* Gets the base source variable (i.e., the variable without any
* indirections) of this source variable.
*/
SsaInternals0::SourceVariable getBaseVariable() { result = base }
/** Gets a textual representation of this element. */
abstract string toString();
string toString() {
ind = 0 and
result = this.getBaseVariable().toString()
or
ind > 0 and
result = this.getBaseVariable().toString() + " indirection"
}
/**
* Gets the number of loads performed on the base source variable
@@ -43,65 +46,19 @@ private module SourceVariables {
*/
int getIndirection() { result = ind }
/**
* Gets the base source variable (i.e., the variable without any
* indirections) of this source variable.
*/
abstract BaseSourceVariable getBaseVariable();
/** Holds if this variable is a glvalue. */
predicate isGLValue() { none() }
predicate isGLValue() { ind = 0 }
/**
* Gets the type of this source variable. If `isGLValue()` holds, then
* the type of this source variable should be thought of as "pointer
* to `getType()`".
*/
abstract DataFlowType getType();
}
class SourceIRVariable extends SourceVariable, TSourceIRVariable {
BaseIRVariable var;
SourceIRVariable() { this = TSourceIRVariable(var, ind) }
IRVariable getIRVariable() { result = var.getIRVariable() }
override BaseIRVariable getBaseVariable() { result.getIRVariable() = this.getIRVariable() }
override string toString() {
ind = 0 and
result = this.getIRVariable().toString()
or
ind > 0 and
result = this.getIRVariable().toString() + " indirection"
DataFlowType getType() {
if this.isGLValue()
then result = base.getType()
else result = getTypeImpl(base.getType(), ind - 1)
}
override predicate isGLValue() { ind = 0 }
override DataFlowType getType() {
if ind = 0 then result = var.getType() else result = getTypeImpl(var.getType(), ind - 1)
}
}
class CallVariable extends SourceVariable, TCallVariable {
AllocationInstruction call;
CallVariable() { this = TCallVariable(call, ind) }
AllocationInstruction getCall() { result = call }
override BaseCallVariable getBaseVariable() { result.getCallInstruction() = call }
override string toString() {
ind = 0 and
result = "Call"
or
ind > 0 and
result = "Call indirection"
}
override DataFlowType getType() { result = getTypeImpl(call.getResultType(), ind) }
}
}
@@ -137,8 +94,9 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
cached
private newtype TDefOrUseImpl =
TDefImpl(Operand address, int indirectionIndex) {
exists(Instruction base | isDef(_, _, address, base, _, indirectionIndex) |
TDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) {
isDef(_, _, address, base, _, indirectionIndex) and
(
// We only include the definition if the SSA pruning stage
// concluded that the definition is live after the write.
any(SsaInternals0::Def def).getAddressOperand() = address
@@ -148,8 +106,8 @@ private newtype TDefOrUseImpl =
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
)
} or
TUseImpl(Operand operand, int indirectionIndex) {
isUse(_, operand, _, _, indirectionIndex) and
TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) {
isUse(_, operand, base, _, indirectionIndex) and
not isDef(_, _, operand, _, _, _)
} or
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
@@ -236,7 +194,7 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl {
/**
* Gets the instruction that computes the base of this definition or use.
* This is always a `VariableAddressInstruction` or an `AllocationInstruction`.
* This is always a `VariableAddressInstruction` or an `CallInstruction`.
*/
abstract BaseSourceVariableInstruction getBase();
@@ -308,15 +266,17 @@ abstract class DefImpl extends DefOrUseImpl {
}
private class DirectDef extends DefImpl, TDefImpl {
DirectDef() { this = TDefImpl(address, ind) }
BaseSourceVariableInstruction base;
override BaseSourceVariableInstruction getBase() { isDef(_, _, address, result, _, _) }
DirectDef() { this = TDefImpl(base, address, ind) }
override int getIndirection() { isDef(_, _, address, _, result, ind) }
override BaseSourceVariableInstruction getBase() { result = base }
override Node0Impl getValue() { isDef(_, result, address, _, _, _) }
override int getIndirection() { isDef(_, _, address, base, result, ind) }
override predicate isCertain() { isDef(true, _, address, _, _, ind) }
override Node0Impl getValue() { isDef(_, result, address, base, _, _) }
override predicate isCertain() { isDef(true, _, address, base, _, ind) }
}
private class IteratorDef extends DefImpl, TIteratorDef {
@@ -359,6 +319,7 @@ abstract class UseImpl extends DefOrUseImpl {
abstract private class OperandBasedUse extends UseImpl {
Operand operand;
BaseSourceVariableInstruction base;
bindingset[ind]
OperandBasedUse() { any() }
@@ -366,50 +327,44 @@ abstract private class OperandBasedUse extends UseImpl {
final override predicate hasIndexInBlock(IRBlock block, int index) {
// See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
// predicate's implementation.
exists(BaseSourceVariableInstruction base | base = this.getBase() |
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
then
exists(Operand op, int indirectionIndex, int indirection |
indirectionIndex = this.getIndirectionIndex() and
indirection = this.getIndirection() 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)
)
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
then
exists(Operand op, int indirectionIndex, int indirection |
indirectionIndex = this.getIndirectionIndex() and
indirection = this.getIndirection() 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)
}
final override BaseSourceVariableInstruction getBase() { result = base }
final Operand getOperand() { result = operand }
final override Cpp::Location getLocation() { result = operand.getLocation() }
}
private class DirectUse extends OperandBasedUse, TUseImpl {
DirectUse() { this = TUseImpl(operand, ind) }
DirectUse() { this = TUseImpl(base, operand, ind) }
override int getIndirection() { isUse(_, operand, _, result, ind) }
override int getIndirection() { isUse(_, operand, base, result, ind) }
override BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, ind) }
override predicate isCertain() { isUse(true, operand, _, _, ind) }
override predicate isCertain() { isUse(true, operand, base, _, ind) }
override Node getNode() { nodeHasOperand(result, operand, ind) }
}
private class IteratorUse extends OperandBasedUse, TIteratorUse {
BaseSourceVariableInstruction container;
IteratorUse() { this = TIteratorUse(operand, base, ind) }
IteratorUse() { this = TIteratorUse(operand, container, ind) }
override int getIndirection() { isIteratorUse(container, operand, result, ind) }
override BaseSourceVariableInstruction getBase() { result = container }
override int getIndirection() { isIteratorUse(base, operand, result, ind) }
override predicate isCertain() { none() }

View File

@@ -6,6 +6,7 @@ private import DataFlowImplCommon as DataFlowImplCommon
private import DataFlowUtil
private import semmle.code.cpp.models.interfaces.PointerWrapper
private import DataFlowPrivate
private import semmle.code.cpp.ir.ValueNumbering
/**
* Holds if `operand` is an operand that is not used by the dataflow library.
@@ -146,14 +147,6 @@ int countIndirectionsForCppType(LanguageType langType) {
)
}
/**
* A `CallInstruction` that calls an allocation function such
* as `malloc` or `operator new`.
*/
class AllocationInstruction extends CallInstruction {
AllocationInstruction() { this.getStaticCallTarget() instanceof Cpp::AllocationFunction }
}
private predicate isIndirectionType(Type t) { t instanceof Indirection }
private predicate hasUnspecifiedBaseType(Indirection t, Type base) {
@@ -368,17 +361,22 @@ newtype TBaseSourceVariable =
// Each IR variable gets its own source variable
TBaseIRVariable(IRVariable var) or
// Each allocation gets its own source variable
TBaseCallVariable(AllocationInstruction call)
TBaseCallVariable(CallInstruction call) { not call.getResultIRType() instanceof IRVoidType }
abstract class BaseSourceVariable extends TBaseSourceVariable {
abstract private class AbstractBaseSourceVariable extends TBaseSourceVariable {
/** Gets a textual representation of this element. */
abstract string toString();
/** Gets the type of this base source variable. */
abstract DataFlowType getType();
final DataFlowType getType() { this.getLanguageType().hasUnspecifiedType(result, _) }
/** Gets the `CppType` of this base source variable. */
abstract CppType getLanguageType();
}
class BaseIRVariable extends BaseSourceVariable, TBaseIRVariable {
final class BaseSourceVariable = AbstractBaseSourceVariable;
class BaseIRVariable extends AbstractBaseSourceVariable, TBaseIRVariable {
IRVariable var;
IRVariable getIRVariable() { result = var }
@@ -387,19 +385,19 @@ class BaseIRVariable extends BaseSourceVariable, TBaseIRVariable {
override string toString() { result = var.toString() }
override DataFlowType getType() { result = var.getType() }
override CppType getLanguageType() { result = var.getLanguageType() }
}
class BaseCallVariable extends BaseSourceVariable, TBaseCallVariable {
AllocationInstruction call;
class BaseCallVariable extends AbstractBaseSourceVariable, TBaseCallVariable {
CallInstruction call;
BaseCallVariable() { this = TBaseCallVariable(call) }
AllocationInstruction getCallInstruction() { result = call }
CallInstruction getCallInstruction() { result = call }
override string toString() { result = call.toString() }
override DataFlowType getType() { result = call.getResultType() }
override CppType getLanguageType() { result = getResultLanguageType(call) }
}
/**
@@ -499,8 +497,7 @@ private class BaseIRVariableInstruction extends BaseSourceVariableInstruction,
override BaseIRVariable getBaseSourceVariable() { result.getIRVariable() = this.getIRVariable() }
}
private class BaseAllocationInstruction extends BaseSourceVariableInstruction, AllocationInstruction
{
private class BaseCallInstruction extends BaseSourceVariableInstruction, CallInstruction {
override BaseCallVariable getBaseSourceVariable() { result.getCallInstruction() = this }
}
@@ -868,7 +865,7 @@ private module Cached {
* to a specific address.
*/
private predicate isCertainAddress(Operand operand) {
operand.getDef() instanceof VariableAddressInstruction
valueNumberOfOperand(operand).getAnInstruction() instanceof VariableAddressInstruction
or
operand.getType() instanceof Cpp::ReferenceType
}

View File

@@ -15,15 +15,12 @@ private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.internal.SsaInternalsCommon
private module SourceVariables {
class SourceVariable instanceof BaseSourceVariable {
string toString() { result = BaseSourceVariable.super.toString() }
class SourceVariable extends BaseSourceVariable {
/**
* Gets the base source variable of this `SourceVariable`.
*/
BaseSourceVariable getBaseVariable() { result = this }
}
class SourceIRVariable = BaseIRVariable;
class CallVariable = BaseCallVariable;
}
import SourceVariables

View File

@@ -24,6 +24,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp
Config::allowImplicitRead(node, c)
or
(
Config::isSink(node) or
Config::isSink(node, _) or
Config::isAdditionalFlowStep(node, _) or
Config::isAdditionalFlowStep(node, _, _, _)

View File

@@ -4,8 +4,8 @@
* This file contains the actual implementation of `PrintIR.ql`. For test cases and very small
* databases, `PrintIR.ql` can be run directly to dump the IR for the entire database. For most
* uses, however, it is better to write a query that imports `PrintIR.qll`, extends
* `PrintIRConfiguration`, and overrides `shouldPrintFunction()` to select a subset of functions to
* dump.
* `PrintIRConfiguration`, and overrides `shouldPrintDeclaration()` to select a subset of declarations
* to dump.
*/
private import internal.IRInternal
@@ -16,7 +16,7 @@ import Imports::IRConfiguration
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
/**
* The query can extend this class to control which functions are printed.
* The query can extend this class to control which declarations are printed.
*/
class PrintIRConfiguration extends TPrintIRConfiguration {
/** Gets a textual representation of this configuration. */
@@ -24,9 +24,9 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
/**
* Holds if the IR for `func` should be printed. By default, holds for all
* functions.
* functions, global and namespace variables, and static local variables.
*/
predicate shouldPrintFunction(Language::Declaration decl) { any() }
predicate shouldPrintDeclaration(Language::Declaration decl) { any() }
}
/**
@@ -34,12 +34,12 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
*/
private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) {
shouldPrintFunction(func)
shouldPrintDeclaration(func)
}
}
private predicate shouldPrintFunction(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
private predicate shouldPrintDeclaration(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintDeclaration(decl))
}
private predicate shouldPrintInstruction(Instruction i) {
@@ -90,10 +90,10 @@ private string getOperandPropertyString(Operand operand) {
}
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
TPrintableIRFunction(IRFunction irFunc) { shouldPrintDeclaration(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintDeclaration(block.getEnclosingFunction()) } or
TPrintableInstruction(Instruction instr) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
shouldPrintInstruction(instr) and shouldPrintDeclaration(instr.getEnclosingFunction())
}
/**

View File

@@ -4,8 +4,8 @@
* This file contains the actual implementation of `PrintIR.ql`. For test cases and very small
* databases, `PrintIR.ql` can be run directly to dump the IR for the entire database. For most
* uses, however, it is better to write a query that imports `PrintIR.qll`, extends
* `PrintIRConfiguration`, and overrides `shouldPrintFunction()` to select a subset of functions to
* dump.
* `PrintIRConfiguration`, and overrides `shouldPrintDeclaration()` to select a subset of declarations
* to dump.
*/
private import internal.IRInternal
@@ -16,7 +16,7 @@ import Imports::IRConfiguration
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
/**
* The query can extend this class to control which functions are printed.
* The query can extend this class to control which declarations are printed.
*/
class PrintIRConfiguration extends TPrintIRConfiguration {
/** Gets a textual representation of this configuration. */
@@ -24,9 +24,9 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
/**
* Holds if the IR for `func` should be printed. By default, holds for all
* functions.
* functions, global and namespace variables, and static local variables.
*/
predicate shouldPrintFunction(Language::Declaration decl) { any() }
predicate shouldPrintDeclaration(Language::Declaration decl) { any() }
}
/**
@@ -34,12 +34,12 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
*/
private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) {
shouldPrintFunction(func)
shouldPrintDeclaration(func)
}
}
private predicate shouldPrintFunction(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
private predicate shouldPrintDeclaration(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintDeclaration(decl))
}
private predicate shouldPrintInstruction(Instruction i) {
@@ -90,10 +90,10 @@ private string getOperandPropertyString(Operand operand) {
}
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
TPrintableIRFunction(IRFunction irFunc) { shouldPrintDeclaration(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintDeclaration(block.getEnclosingFunction()) } or
TPrintableInstruction(Instruction instr) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
shouldPrintInstruction(instr) and shouldPrintDeclaration(instr.getEnclosingFunction())
}
/**

View File

@@ -4,8 +4,8 @@
* This file contains the actual implementation of `PrintIR.ql`. For test cases and very small
* databases, `PrintIR.ql` can be run directly to dump the IR for the entire database. For most
* uses, however, it is better to write a query that imports `PrintIR.qll`, extends
* `PrintIRConfiguration`, and overrides `shouldPrintFunction()` to select a subset of functions to
* dump.
* `PrintIRConfiguration`, and overrides `shouldPrintDeclaration()` to select a subset of declarations
* to dump.
*/
private import internal.IRInternal
@@ -16,7 +16,7 @@ import Imports::IRConfiguration
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
/**
* The query can extend this class to control which functions are printed.
* The query can extend this class to control which declarations are printed.
*/
class PrintIRConfiguration extends TPrintIRConfiguration {
/** Gets a textual representation of this configuration. */
@@ -24,9 +24,9 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
/**
* Holds if the IR for `func` should be printed. By default, holds for all
* functions.
* functions, global and namespace variables, and static local variables.
*/
predicate shouldPrintFunction(Language::Declaration decl) { any() }
predicate shouldPrintDeclaration(Language::Declaration decl) { any() }
}
/**
@@ -34,12 +34,12 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
*/
private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) {
shouldPrintFunction(func)
shouldPrintDeclaration(func)
}
}
private predicate shouldPrintFunction(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
private predicate shouldPrintDeclaration(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintDeclaration(decl))
}
private predicate shouldPrintInstruction(Instruction i) {
@@ -90,10 +90,10 @@ private string getOperandPropertyString(Operand operand) {
}
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
TPrintableIRFunction(IRFunction irFunc) { shouldPrintDeclaration(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintDeclaration(block.getEnclosingFunction()) } or
TPrintableInstruction(Instruction instr) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
shouldPrintInstruction(instr) and shouldPrintDeclaration(instr.getEnclosingFunction())
}
/**

View File

@@ -574,16 +574,6 @@ module RangeStage<
)
}
/** Holds if `e >= 1` as determined by sign analysis. */
private predicate strictlyPositiveIntegralExpr(SemExpr e) {
semStrictlyPositive(e) and getTrackedType(e) instanceof SemIntegerType
}
/** Holds if `e <= -1` as determined by sign analysis. */
private predicate strictlyNegativeIntegralExpr(SemExpr e) {
semStrictlyNegative(e) and getTrackedType(e) instanceof SemIntegerType
}
/**
* Holds if `e1 + delta` is a valid bound for `e2`.
* - `upper = true` : `e2 <= e1 + delta`
@@ -597,27 +587,6 @@ module RangeStage<
delta = D::fromInt(0) and
(upper = true or upper = false)
or
exists(SemExpr x, SemSubExpr sub |
e2 = sub and
sub.getLeftOperand() = e1 and
sub.getRightOperand() = x
|
// `x instanceof ConstantIntegerExpr` is covered by valueFlowStep
not x instanceof SemConstantIntegerExpr and
if strictlyPositiveIntegralExpr(x)
then upper = true and delta = D::fromInt(-1)
else
if semPositive(x)
then upper = true and delta = D::fromInt(0)
else
if strictlyNegativeIntegralExpr(x)
then upper = false and delta = D::fromInt(1)
else
if semNegative(x)
then upper = false and delta = D::fromInt(0)
else none()
)
or
e2.(SemRemExpr).getRightOperand() = e1 and
semPositive(e1) and
delta = D::fromInt(-1) and
@@ -1137,6 +1106,23 @@ module RangeStage<
b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound
)
or
exists(D::Delta dLeft, D::Delta dRight, boolean fbeLeft, boolean fbeRight |
boundedSubOperandLeft(e, upper, b, dLeft, fbeLeft, origdelta, reason) and
boundedSubOperandRight(e, upper, dRight, fbeRight) and
// when `upper` is `true` we have:
// left <= b + dLeft
// right >= 0 + dRight
// left - right <= b + dLeft - (0 + dRight)
// = b + (dLeft - dRight)
// and when `upper` is `false` we have:
// left >= b + dLeft
// right <= 0 + dRight
// left - right >= b + dLeft - (0 + dRight)
// = b + (dLeft - dRight)
delta = D::fromFloat(D::toFloat(dLeft) - D::toFloat(dRight)) and
fromBackEdge = fbeLeft.booleanOr(fbeRight)
)
or
exists(
SemRemExpr rem, D::Delta d_max, D::Delta d1, D::Delta d2, boolean fbe1, boolean fbe2,
D::Delta od1, D::Delta od2, SemReason r1, SemReason r2
@@ -1201,6 +1187,37 @@ module RangeStage<
)
}
/**
* Holds if `sub = left - right` and `left <= b + delta` if `upper` is `true`
* and `left >= b + delta` is `upper` is `false`.
*/
pragma[nomagic]
private predicate boundedSubOperandLeft(
SemSubExpr sub, boolean upper, SemBound b, D::Delta delta, boolean fromBackEdge,
D::Delta origdelta, SemReason reason
) {
// `semValueFlowStep` already handles the case where one of the operands is a constant.
not semValueFlowStep(sub, _, _) and
bounded(sub.getLeftOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
}
/**
* Holds if `sub = left - right` and `right <= 0 + delta` if `upper` is `false`
* and `right >= 0 + delta` is `upper` is `true`.
*
* Note that the boolean value of `upper` is flipped compared to many other predicates in
* this file. This ensures a clean join at the call-site.
*/
pragma[nomagic]
private predicate boundedSubOperandRight(
SemSubExpr sub, boolean upper, D::Delta delta, boolean fromBackEdge
) {
// `semValueFlowStep` already handles the case where one of the operands is a constant.
not semValueFlowStep(sub, _, _) and
bounded(sub.getRightOperand(), any(SemZeroBound zb), delta, upper.booleanNot(), fromBackEdge, _,
_)
}
pragma[nomagic]
private predicate boundedRemExpr(
SemRemExpr rem, boolean upper, D::Delta delta, boolean fromBackEdge, D::Delta origdelta,

View File

@@ -1,6 +1,54 @@
/**
* This file provides the first phase of the `cpp/invalid-pointer-deref` query that identifies flow
* from an allocation to a pointer-arithmetic instruction that constructs a pointer that is out of bounds.
*
* Consider the following snippet:
* ```cpp
* 1. char* base = (char*)malloc(size);
* 2. char* end = base + size;
* 3. for(int *p = base; p <= end; p++) {
* 4. use(*p); // BUG: Should have been bounded by `p < end`.
* 5. }
* ```
* this file identifies the flow from `new int[size]` to `base + size`.
*
* This is done using the product-flow library. The configuration tracks flow from the pair
* `(allocation, size of allocation)` to a pair `(a, b)` where there exists a pointer-arithmetic instruction
* `pai = a + r` such that `b` is a dataflow node where `b <= r`. Because there will be a dataflow-path from
* `allocation` to `a` this means that the `pai` will compute a pointer that is some number of elements beyond
* the end position of the allocation. See `pointerAddInstructionHasBounds` for the implementation of this.
*
* In the above example, the pair `(a, b)` is `(base, size)` with `base` and `size` coming from the expression
* `base + size` on line 2, which is also the pointer-arithmetic instruction. In general, the pair does not necessarily
* correspond directly to the operands of the pointer-arithmetic instruction.
* In the following example, the pair is again `(base, size)`, but with `base` coming from line 3 and `size` from line 2,
* and the pointer-arithmetic instruction being `base + n` on line 3:
* ```cpp
* 1. int* base = new int[size];
* 2. if(n <= size) {
* 3. int* end = base + n;
* 4. for(int* p = base; p <= end; ++p) {
* 5. *p = 0; // BUG: Should have been bounded by `p < end`.
* 6. }
* 7. }
* ```
*
* Handling false positives:
*
* Consider a snippet such as:
* ```cpp
* 1. int* base = new int[size];
* 2. int n = condition() ? size : 0;
* 3. if(n >= size) return;
* 4. int* end = base + n;
* 5. for(int* p = base; p <= end; ++p) {
* 6. *p = 0; // This is fine since `end < base + size`
* 7. }
* ```
* In order to remove this false positive we define a barrier (see `SizeBarrier::SizeBarrierConfig`) that finds the
* possible guards that compares a value to the size of the allocation. In the above example, this is the `(n >= size)`
* guard on line 3. `SizeBarrier::getABarrierNode` then defines any node that is guarded by such a guard as a barrier
* in the dataflow configuration.
*/
private import cpp
@@ -42,51 +90,74 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
* ```
* In this case, the sink pair identified by the product flow library (without any additional barriers)
* would be `(p, n)` (where `n` is the `n` in `p[n]`), because there exists a pointer-arithmetic
* instruction `pai` such that:
* 1. The left-hand of `pai` flows from the allocation, and
* 2. The right-hand of `pai` is non-strictly upper bounded by `n` (where `n` is the `n` in `p[n]`)
* instruction `pai = a + b` such that:
* 1. the allocation flows to `a`, and
* 2. `b <= n` where `n` is the `n` in `p[n]`
* but because there's a strict comparison that compares `n` against the size of the allocation this
* snippet is fine.
*/
module Barrier2 {
private class FlowState2 = int;
private module BarrierConfig2 implements DataFlow::ConfigSig {
private module SizeBarrier {
private module SizeBarrierConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// The sources is the same as in the sources for the second
// projection in the `AllocToInvalidPointerConfig` module.
hasSize(_, source, _)
}
/**
* Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`.
*/
additional predicate isSink(
DataFlow::Node left, DataFlow::Node right, IRGuardCondition g, FlowState2 state,
boolean testIsTrue
DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue
) {
// The sink is any "large" side of a relational comparison.
g.comparesLt(left.asOperand(), right.asOperand(), state, true, testIsTrue)
// The sink is any "large" side of a relational comparison. i.e., the `large` expression
// in a guard such as `small <= large + k`.
g.comparesLt(small.asOperand(), large.asOperand(), k + 1, true, testIsTrue)
}
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
}
private import DataFlow::Global<BarrierConfig2>
module SizeBarrierFlow = DataFlow::Global<SizeBarrierConfig>;
private FlowState2 getAFlowStateForNode(DataFlow::Node node) {
private int getASizeAddend(DataFlow::Node node) {
exists(DataFlow::Node source |
flow(source, node) and
SizeBarrierFlow::flow(source, node) and
hasSize(_, source, result)
)
}
/**
* Holds if `small <= large + k` holds if `g` evaluates to `edge`.
*/
private predicate operandGuardChecks(
IRGuardCondition g, Operand left, Operand right, FlowState2 state, boolean edge
IRGuardCondition g, Operand small, DataFlow::Node large, int k, boolean edge
) {
exists(DataFlow::Node nLeft, DataFlow::Node nRight, FlowState2 state0 |
nRight.asOperand() = right and
nLeft.asOperand() = left and
BarrierConfig2::isSink(nLeft, nRight, g, state0, edge) and
state = getAFlowStateForNode(nRight) and
state0 <= state
SizeBarrierFlow::flowTo(large) and
SizeBarrierConfig::isSink(DataFlow::operandNode(small), large, g, k, edge)
}
/**
* Gets an instruction `instr` that is guarded by a check such as `instr <= small + delta` where
* `small <= _ + k` and `small` is the "small side" of of a relational comparison that checks
* whether `small <= size` where `size` is the size of an allocation.
*/
Instruction getABarrierInstruction0(int delta, int k) {
exists(
IRGuardCondition g, ValueNumber value, Operand small, boolean edge, DataFlow::Node large
|
// We know:
// 1. result <= value + delta (by `bounded`)
// 2. value <= large + k (by `operandGuardChecks`).
// So:
// result <= value + delta (by 1.)
// <= large + k + delta (by 2.)
small = value.getAUse() and
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](small), large,
pragma[only_bind_into](k), pragma[only_bind_into](edge)) and
bounded(result, value.getAnInstruction(), delta) and
g.controls(result.getBlock(), edge) and
k < getASizeAddend(large)
)
}
@@ -94,13 +165,14 @@ module Barrier2 {
* Gets an instruction that is guarded by a guard condition which ensures that
* the value of the instruction is upper-bounded by size of some allocation.
*/
Instruction getABarrierInstruction(FlowState2 state) {
exists(IRGuardCondition g, ValueNumber value, Operand use, boolean edge |
use = value.getAUse() and
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](use), _,
pragma[only_bind_into](state), pragma[only_bind_into](edge)) and
result = value.getAnInstruction() and
g.controls(result.getBlock(), edge)
bindingset[state]
pragma[inline_late]
Instruction getABarrierInstruction(int state) {
exists(int delta, int k |
state > k + delta and
// result <= "size of allocation" + delta + k
// < "size of allocation" + state
result = getABarrierInstruction0(delta, k)
)
}
@@ -108,16 +180,16 @@ module Barrier2 {
* Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that
* the value of the node is upper-bounded by size of some allocation.
*/
DataFlow::Node getABarrierNode(FlowState2 state) {
result.asOperand() = getABarrierInstruction(state).getAUse()
}
/**
* Gets the block of a node that is guarded (see `getABarrierInstruction` or
* `getABarrierNode` for the definition of what it means to be guarded).
*/
IRBlock getABarrierBlock(FlowState2 state) {
result.getAnInstruction() = getABarrierInstruction(state)
DataFlow::Node getABarrierNode(int state) {
exists(DataFlow::Node source, int delta, int k |
SizeBarrierFlow::flow(source, result) and
hasSize(_, source, state) and
result.asInstruction() = SizeBarrier::getABarrierInstruction0(delta, k) and
state > k + delta
// so now we have:
// result <= "size of allocation" + delta + k
// < "size of allocation" + state
)
}
}
@@ -151,24 +223,8 @@ private module InterestingPointerAddInstruction {
}
/**
* A product-flow configuration for flow from an (allocation, size) pair to a
* pointer-arithmetic operation that is non-strictly upper-bounded by `allocation + size`.
*
* The goal of this query is to find patterns such as:
* ```cpp
* 1. char* begin = (char*)malloc(size);
* 2. char* end = begin + size;
* 3. for(int *p = begin; p <= end; p++) {
* 4. use(*p);
* 5. }
* ```
*
* We do this by splitting the task up into two configurations:
* 1. `AllocToInvalidPointerConfig` find flow from `malloc(size)` to `begin + size`, and
* 2. `InvalidPointerToDerefConfig` finds flow from `begin + size` to an `end` (on line 3).
*
* Finally, the range-analysis library will find a load from (or store to) an address that
* is non-strictly upper-bounded by `end` (which in this case is `*p`).
* A product-flow configuration for flow from an `(allocation, size)` pair to a
* pointer-arithmetic operation `pai` such that `pai <= allocation + size`.
*/
private module Config implements ProductFlow::StateConfigSig {
class FlowState1 = Unit;
@@ -176,7 +232,7 @@ private module Config implements ProductFlow::StateConfigSig {
class FlowState2 = int;
predicate isSourcePair(
DataFlow::Node source1, FlowState1 state1, DataFlow::Node source2, FlowState2 state2
DataFlow::Node allocSource, FlowState1 unit, DataFlow::Node sizeSource, FlowState2 sizeAddend
) {
// In the case of an allocation like
// ```cpp
@@ -184,21 +240,21 @@ private module Config implements ProductFlow::StateConfigSig {
// ```
// we use `state2` to remember that there was an offset (in this case an offset of `1`) added
// to the size of the allocation. This state is then checked in `isSinkPair`.
exists(state1) and
hasSize(source1.asConvertedExpr(), source2, state2)
exists(unit) and
hasSize(allocSource.asConvertedExpr(), sizeSource, sizeAddend)
}
predicate isSinkPair(
DataFlow::Node sink1, FlowState1 state1, DataFlow::Node sink2, FlowState2 state2
DataFlow::Node allocSink, FlowState1 unit, DataFlow::Node sizeSink, FlowState2 sizeAddend
) {
exists(state1) and
exists(unit) and
// We check that the delta computed by the range analysis matches the
// state value that we set in `isSourcePair`.
pointerAddInstructionHasBounds0(_, sink1, sink2, state2)
pointerAddInstructionHasBounds0(_, allocSink, sizeSink, sizeAddend)
}
predicate isBarrier2(DataFlow::Node node, FlowState2 state) {
node = Barrier2::getABarrierNode(state)
node = SizeBarrier::getABarrierNode(state)
}
predicate isBarrierIn1(DataFlow::Node node) { isSourcePair(node, _, _, _) }
@@ -211,7 +267,7 @@ private module Config implements ProductFlow::StateConfigSig {
private module AllocToInvalidPointerFlow = ProductFlow::GlobalWithState<Config>;
/**
* Holds if `pai` is non-strictly upper bounded by `sink2 + delta` and `sink1` is the
* Holds if `pai` is non-strictly upper bounded by `sizeSink + delta` and `allocSink` is the
* left operand of the pointer-arithmetic operation.
*
* For example in,
@@ -220,37 +276,37 @@ private module AllocToInvalidPointerFlow = ProductFlow::GlobalWithState<Config>;
* ```
* We will have:
* - `pai` is `p + (size + 1)`,
* - `sink1` is `p`
* - `sink2` is `size`
* - `allocSink` is `p`
* - `sizeSink` is `size`
* - `delta` is `1`.
*/
pragma[nomagic]
private predicate pointerAddInstructionHasBounds0(
PointerAddInstruction pai, DataFlow::Node sink1, DataFlow::Node sink2, int delta
PointerAddInstruction pai, DataFlow::Node allocSink, DataFlow::Node sizeSink, int delta
) {
InterestingPointerAddInstruction::isInteresting(pragma[only_bind_into](pai)) and
exists(Instruction right, Instruction instr2 |
exists(Instruction right, Instruction sizeInstr |
pai.getRight() = right and
pai.getLeft() = sink1.asInstruction() and
instr2 = sink2.asInstruction() and
// pai.getRight() <= sink2 + delta
bounded1(right, instr2, delta) and
not right = Barrier2::getABarrierInstruction(delta) and
not instr2 = Barrier2::getABarrierInstruction(delta)
pai.getLeft() = allocSink.asInstruction() and
sizeInstr = sizeSink.asInstruction() and
// pai.getRight() <= sizeSink + delta
bounded1(right, sizeInstr, delta) and
not right = SizeBarrier::getABarrierInstruction(delta) and
not sizeInstr = SizeBarrier::getABarrierInstruction(delta)
)
}
/**
* Holds if `allocation` flows to `sink1` and `sink1` represents the left-hand
* side of the pointer-arithmetic instruction `pai`, and the right-hand side of `pai`
* is non-strictly upper bounded by the size of `alllocation` + `delta`.
* Holds if `allocation` flows to `allocSink` and `allocSink` represents the left operand
* of the pointer-arithmetic instruction `pai = a + b` (i.e., `allocSink = a`), and
* `b <= allocation + delta`.
*/
pragma[nomagic]
predicate pointerAddInstructionHasBounds(
DataFlow::Node allocation, PointerAddInstruction pai, DataFlow::Node sink1, int delta
DataFlow::Node allocation, PointerAddInstruction pai, DataFlow::Node allocSink, int delta
) {
exists(DataFlow::Node sink2 |
AllocToInvalidPointerFlow::flow(allocation, _, sink1, sink2) and
pointerAddInstructionHasBounds0(pai, sink1, sink2, delta)
exists(DataFlow::Node sizeSink |
AllocToInvalidPointerFlow::flow(allocation, _, allocSink, sizeSink) and
pointerAddInstructionHasBounds0(pai, allocSink, sizeSink, delta)
)
}

View File

@@ -2,6 +2,78 @@
* This file provides the second phase of the `cpp/invalid-pointer-deref` query that identifies flow
* from the out-of-bounds pointer identified by the `AllocationToInvalidPointer.qll` library to
* a dereference of the out-of-bounds pointer.
*
* Consider the following snippet:
* ```cpp
* 1. char* base = (char*)malloc(size);
* 2. char* end = base + size;
* 3. for(char *p = base; p <= end; p++) {
* 4. use(*p); // BUG: Should have been bounded by `p < end`.
* 5. }
* ```
* this file identifies the flow from `base + size` to `end`. We call `base + size` the "dereference source" and `end`
* the "dereference sink" (even though `end` is not actually dereferenced we will use this term because we will perform
* dataflow to find a use of a pointer `x` such that `x <= end` which is dereferenced. In the above example, `x` is `p`
* on line 4).
*
* Merely _constructing_ a pointer that's out-of-bounds is fine if the pointer is never dereferenced (in reality, the
* standard only guarantees that it is safe to move the pointer one element past the last element, but we ignore that
* here). So this step is about identifying which of the out-of-bounds pointers found by `pointerAddInstructionHasBounds`
* in `AllocationToInvalidPointer.qll` are actually being dereferenced. We do this using a regular dataflow
* configuration (see `InvalidPointerToDerefConfig`).
*
* The dataflow traversal defines the set of sources as any dataflow node `n` such that there exists a pointer-arithmetic
* instruction `pai` found by `AllocationToInvalidPointer.qll` and a `n.asInstruction() >= pai + deltaDerefSourceAndPai`.
* Here, `deltaDerefSourceAndPai` is the constant difference between the source we track for finding a dereference and the
* pointer-arithmetic instruction.
*
* The set of sinks is defined as any dataflow node `n` such that `addr <= n.asInstruction() + deltaDerefSinkAndDerefAddress`
* for some address operand `addr` and constant difference `deltaDerefSinkAndDerefAddress`. Since an address operand is
* always consumed by an instruction that performs a dereference this lets us identify a "bad dereference". We call the
* instruction that consumes the address operand the "operation".
*
* For example, consider the flow from `base + size` to `end` above. The sink is `end` on line 3 because
* `p <= end.asInstruction() + deltaDerefSinkAndDerefAddress`, where `p` is the address operand in `use(*p)` and
* `deltaDerefSinkAndDerefAddress >= 0`. The load attached to `*p` is the "operation". To ensure that the path makes
* intuitive sense, we only pick operations that are control-flow reachable from the dereference sink.
*
* To compute how many elements the dereference is beyond the end position of the allocation, we sum the two deltas
* `deltaDerefSourceAndPai` and `deltaDerefSinkAndDerefAddress`. This is done in the `operationIsOffBy` predicate
* (which is the only predicate exposed by this file).
*
* Handling false positives:
*
* Consider the following snippet:
* ```cpp
* 1. char *p = new char[size];
* 2. char *end = p + size;
* 3. if (p < end) {
* 4. p += 1;
* 5. }
* 6. if (p < end) {
* 7. int val = *p; // GOOD
* 8. }
* ```
* this is safe because `p` is guarded to be strictly less than `end` on line 6 before the dereference on line 7. However, if we
* run the query on the above without further modifications we would see an alert on line 7. This is because range analysis infers
* that `p <= end` after the increment on line 4, and thus the result of `p += 1` is seen as a valid dereference source. This
* node then flows to `p` on line 6 (which is a valid dereference sink since it non-strictly upper bounds an address operand), and
* range analysis then infers that the address operand of `*p` (i.e., `p`) is non-strictly upper bounded by `p`, and thus reports
* an alert on line 7.
*
* In order to handle the above false positive, we define a barrier that identifies guards such as `p < end` that ensures that a value
* is less than the pointer-arithmetic instruction that computed the invalid pointer. This is done in the `InvalidPointerToDerefBarrier`
* module. Since the node we are tracking is not necessarily _equal_ to the pointer-arithmetic instruction, but rather satisfies
* `node.asInstruction() <= pai + deltaDerefSourceAndPai`, we need to account for the delta when checking if a guard is sufficiently
* strong to infer that a future dereference is safe. To do this, we check that the guard guarantees that a node `n` satisfies
* `n < node + k` where `node` is a node such that `node <= pai`. Thus, we know that any node `m` such that `m <= n + delta` where
* `delta + k <= 0` will be safe because:
* ```
* m <= n + delta
* < node + k + delta
* <= pai + k + delta
* <= pai
* ```
*/
private import cpp
@@ -13,16 +85,19 @@ private import RangeAnalysisUtil
private module InvalidPointerToDerefBarrier {
private module BarrierConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// The sources is the same as in the sources for `InvalidPointerToDerefConfig`.
invalidPointerToDerefSource(_, _, source, _)
additional predicate isSource(DataFlow::Node source, PointerArithmeticInstruction pai) {
invalidPointerToDerefSource(_, pai, _, _) and
// source <= pai
bounded2(source.asInstruction(), pai, any(int d | d <= 0))
}
predicate isSource(DataFlow::Node source) { isSource(source, _) }
additional predicate isSink(
DataFlow::Node left, DataFlow::Node right, IRGuardCondition g, int state, boolean testIsTrue
DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue
) {
// The sink is any "large" side of a relational comparison.
g.comparesLt(left.asOperand(), right.asOperand(), state, true, testIsTrue)
g.comparesLt(small.asOperand(), large.asOperand(), k, true, testIsTrue)
}
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
@@ -30,102 +105,120 @@ private module InvalidPointerToDerefBarrier {
private module BarrierFlow = DataFlow::Global<BarrierConfig>;
private int getInvalidPointerToDerefSourceDelta(DataFlow::Node node) {
exists(DataFlow::Node source |
BarrierFlow::flow(source, node) and
invalidPointerToDerefSource(_, _, source, result)
)
}
/**
* Holds if `g` ensures that `small < large + k` if `g` evaluates to `edge`.
*
* Additionally, it also holds that `large <= pai`. Thus, when `g` evaluates to `edge`
* it holds that `small < pai + k`.
*/
private predicate operandGuardChecks(
IRGuardCondition g, Operand left, Operand right, int state, boolean edge
PointerArithmeticInstruction pai, IRGuardCondition g, Operand small, int k, boolean edge
) {
exists(DataFlow::Node nLeft, DataFlow::Node nRight, int state0 |
nRight.asOperand() = right and
nLeft.asOperand() = left and
BarrierConfig::isSink(nLeft, nRight, g, state0, edge) and
state = getInvalidPointerToDerefSourceDelta(nRight) and
state0 <= state
exists(DataFlow::Node source, DataFlow::Node nSmall, DataFlow::Node nLarge |
nSmall.asOperand() = small and
BarrierConfig::isSource(source, pai) and
BarrierFlow::flow(source, nLarge) and
BarrierConfig::isSink(nSmall, nLarge, g, k, edge)
)
}
Instruction getABarrierInstruction(int state) {
exists(IRGuardCondition g, ValueNumber value, Operand use, boolean edge |
/**
* Gets an instruction `instr` such that `instr < pai`.
*/
Instruction getABarrierInstruction(PointerArithmeticInstruction pai) {
exists(IRGuardCondition g, ValueNumber value, Operand use, boolean edge, int delta, int k |
use = value.getAUse() and
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](use), _, state,
pragma[only_bind_into](edge)) and
result = value.getAnInstruction() and
g.controls(result.getBlock(), edge)
// value < pai + k
operandGuardChecks(pai, pragma[only_bind_into](g), pragma[only_bind_into](use),
pragma[only_bind_into](k), pragma[only_bind_into](edge)) and
// result <= value + delta
bounded(result, value.getAnInstruction(), delta) and
g.controls(result.getBlock(), edge) and
delta + k <= 0
// combining the above we have: result < pai + k + delta <= pai
)
}
DataFlow::Node getABarrierNode() { result.asOperand() = getABarrierInstruction(_).getAUse() }
DataFlow::Node getABarrierNode(PointerArithmeticInstruction pai) {
result.asOperand() = getABarrierInstruction(pai).getAUse()
}
pragma[nomagic]
IRBlock getABarrierBlock(int state) { result.getAnInstruction() = getABarrierInstruction(state) }
/**
* Gets an address operand whose definition `instr` satisfies `instr < pai`.
*/
AddressOperand getABarrierAddressOperand(PointerArithmeticInstruction pai) {
result.getDef() = getABarrierInstruction(pai)
}
}
/**
* A configuration to track flow from a pointer-arithmetic operation found
* by `AllocToInvalidPointerConfig` to a dereference of the pointer.
*/
private module InvalidPointerToDerefConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { invalidPointerToDerefSource(_, _, source, _) }
private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
class FlowState extends PointerArithmeticInstruction {
FlowState() { invalidPointerToDerefSource(_, this, _, _) }
}
predicate isSource(DataFlow::Node source, FlowState pai) {
invalidPointerToDerefSource(_, pai, source, _)
}
pragma[inline]
predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _, _) }
predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _, _, _) }
predicate isSink(DataFlow::Node sink, FlowState pai) { none() }
predicate isBarrier(DataFlow::Node node) {
node = any(DataFlow::SsaPhiNode phi | not phi.isPhiRead()).getAnInput(true)
or
node = InvalidPointerToDerefBarrier::getABarrierNode()
}
predicate isBarrier(DataFlow::Node node, FlowState pai) {
// `node = getABarrierNode(pai)` ensures that node < pai, so this node is safe to dereference.
// Note that this is the only place where the `FlowState` is used in this configuration.
node = InvalidPointerToDerefBarrier::getABarrierNode(pai)
}
}
private import DataFlow::Global<InvalidPointerToDerefConfig>
private import DataFlow::GlobalWithState<InvalidPointerToDerefConfig>
/**
* Holds if `source1` is dataflow node that represents an allocation that flows to the
* left-hand side of the pointer-arithmetic `pai`, and `derefSource` is a dataflow node with
* a pointer-value that is non-strictly upper bounded by `pai + delta`.
* Holds if `allocSource` is dataflow node that represents an allocation that flows to the
* left-hand side of the pointer-arithmetic `pai`, and `derefSource <= pai + derefSourcePaiDelta`.
*
* For example, if `pai` is a pointer-arithmetic operation `p + size` in an expression such
* as `(p + size) + 1` and `derefSource` is the node representing `(p + size) + 1`. In this
* case `delta` is 1.
* case `derefSourcePaiDelta` is 1.
*/
private predicate invalidPointerToDerefSource(
DataFlow::Node source1, PointerArithmeticInstruction pai, DataFlow::Node derefSource, int delta
DataFlow::Node allocSource, PointerArithmeticInstruction pai, DataFlow::Node derefSource,
int deltaDerefSourceAndPai
) {
exists(int delta0 |
// Note that `delta` is not necessarily equal to `delta0`:
// `delta0` is the constant offset added to the size of the allocation, and
// delta is the constant difference between the pointer-arithmetic instruction
// and the instruction computing the address for which we will search for a dereference.
AllocToInvalidPointer::pointerAddInstructionHasBounds(source1, pai, _, delta0) and
bounded2(derefSource.asInstruction(), pai, delta) and
delta >= 0 and
// TODO: This condition will go away once #13725 is merged, and then we can make `Barrier2`
// private to `AllocationToInvalidPointer.qll`.
not derefSource.getBasicBlock() = AllocToInvalidPointer::Barrier2::getABarrierBlock(delta0)
)
// Note that `deltaDerefSourceAndPai` is not necessarily equal to `rhsSizeDelta`:
// `rhsSizeDelta` is the constant offset added to the size of the allocation, and
// `deltaDerefSourceAndPai` is the constant difference between the pointer-arithmetic instruction
// and the instruction computing the address for which we will search for a dereference.
AllocToInvalidPointer::pointerAddInstructionHasBounds(allocSource, pai, _, _) and
// derefSource <= pai + deltaDerefSourceAndPai
bounded2(derefSource.asInstruction(), pai, deltaDerefSourceAndPai) and
deltaDerefSourceAndPai >= 0
}
/**
* Holds if `sink` is a sink for `InvalidPointerToDerefConfig` and `i` is a `StoreInstruction` that
* writes to an address that non-strictly upper-bounds `sink`, or `i` is a `LoadInstruction` that
* reads from an address that non-strictly upper-bounds `sink`.
* writes to an address `addr` such that `addr <= sink`, or `i` is a `LoadInstruction` that
* reads from an address `addr` such that `addr <= sink`.
*/
pragma[inline]
private predicate isInvalidPointerDerefSink(
DataFlow::Node sink, Instruction i, string operation, int delta
DataFlow::Node sink, AddressOperand addr, Instruction i, string operation,
int deltaDerefSinkAndDerefAddress
) {
exists(AddressOperand addr, Instruction s, IRBlock b |
exists(Instruction s |
s = sink.asInstruction() and
bounded(addr.getDef(), s, delta) and
delta >= 0 and
i.getAnOperand() = addr and
b = i.getBlock() and
not b = InvalidPointerToDerefBarrier::getABarrierBlock(delta)
bounded(addr.getDef(), s, deltaDerefSinkAndDerefAddress) and
deltaDerefSinkAndDerefAddress >= 0 and
i.getAnOperand() = addr
|
i instanceof StoreInstruction and
operation = "write"
@@ -151,9 +244,11 @@ private Instruction getASuccessor(Instruction instr) {
instr.getBlock().getASuccessor+() = result.getBlock()
}
private predicate paiForDereferenceSink(PointerArithmeticInstruction pai, DataFlow::Node derefSink) {
private predicate paiForDereferenceSink(
PointerArithmeticInstruction pai, DataFlow::Node derefSink, int deltaDerefSourceAndPai
) {
exists(DataFlow::Node derefSource |
invalidPointerToDerefSource(_, pai, derefSource, _) and
invalidPointerToDerefSource(_, pai, derefSource, deltaDerefSourceAndPai) and
flow(derefSource, derefSink)
)
}
@@ -165,13 +260,15 @@ private predicate paiForDereferenceSink(PointerArithmeticInstruction pai, DataFl
*/
private predicate derefSinkToOperation(
DataFlow::Node derefSink, PointerArithmeticInstruction pai, DataFlow::Node operation,
string description, int delta
string description, int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress
) {
exists(Instruction i |
paiForDereferenceSink(pai, pragma[only_bind_into](derefSink)) and
isInvalidPointerDerefSink(derefSink, i, description, delta) and
i = getASuccessor(derefSink.asInstruction()) and
operation.asInstruction() = i
exists(Instruction operationInstr, AddressOperand addr |
paiForDereferenceSink(pai, pragma[only_bind_into](derefSink), deltaDerefSourceAndPai) and
isInvalidPointerDerefSink(derefSink, addr, operationInstr, description,
deltaDerefSinkAndDerefAddress) and
operationInstr = getASuccessor(derefSink.asInstruction()) and
operation.asInstruction() = operationInstr and
not addr = InvalidPointerToDerefBarrier::getABarrierAddressOperand(pai)
)
}
@@ -190,7 +287,8 @@ predicate operationIsOffBy(
exists(int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress |
invalidPointerToDerefSource(allocation, pai, derefSource, deltaDerefSourceAndPai) and
flow(derefSource, derefSink) and
derefSinkToOperation(derefSink, pai, operation, description, deltaDerefSinkAndDerefAddress) and
derefSinkToOperation(derefSink, pai, operation, description, deltaDerefSourceAndPai,
deltaDerefSinkAndDerefAddress) and
delta = deltaDerefSourceAndPai + deltaDerefSinkAndDerefAddress
)
}

View File

@@ -18,7 +18,7 @@ private Instruction getABoundIn(SemBound b, IRFunction func) {
* Holds if `i <= b + delta`.
*/
pragma[inline]
private predicate boundedImpl(Instruction i, Instruction b, int delta) {
private predicate boundedImplCand(Instruction i, Instruction b, int delta) {
exists(SemBound bound, IRFunction func |
semBounded(getSemanticExpr(i), bound, delta, true, _) and
b = getABoundIn(bound, func) and
@@ -26,6 +26,15 @@ private predicate boundedImpl(Instruction i, Instruction b, int delta) {
)
}
/**
* Holds if `i <= b + delta` and `delta` is the smallest integer that satisfies
* this condition.
*/
pragma[inline]
private predicate boundedImpl(Instruction i, Instruction b, int delta) {
delta = min(int cand | boundedImplCand(i, b, cand))
}
/**
* Holds if `i <= b + delta`.
*

View File

@@ -608,7 +608,7 @@ case @builtintype.kind of
| 47 = @std_float64 // _Float64
| 48 = @float64x // _Float64x
| 49 = @std_float128 // _Float128
| 50 = @float128x // _Float128x
// ... 50 _Float128x
| 51 = @char8_t
| 52 = @float16 // _Float16
| 53 = @complex_float16 // _Complex _Float16

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
class BuiltinType extends @builtintype {
string toString() { none() }
}
predicate isFloat128xBuiltinType(BuiltinType type) {
exists(int kind | builtintypes(type, _, kind, _, _, _) | kind = 50)
}
from BuiltinType type, string name, int kind, int kind_new, int size, int sign, int alignment
where
builtintypes(type, name, kind, size, sign, alignment) and
if isFloat128xBuiltinType(type) then kind_new = 1 else kind_new = kind
select type, name, kind_new, size, sign, alignment

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Remove _Float128 type
compatibility: partial
builtintypes.rel: run builtintypes.qlo

View File

@@ -1,3 +1,11 @@
## 0.7.3
No user-facing changes.
## 0.7.2
No user-facing changes.
## 0.7.1
### Minor Analysis Improvements

View File

@@ -1,9 +1,10 @@
int f() {
void f() {
char* buf = new char[SIZE];
....
...
if (error) {
free(buf); //error handling has freed the buffer
delete buf; //error handling has freed the buffer
}
...
log_contents(buf); //but it is still used here for logging
...
}

View File

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

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.7.1
lastReleaseVersion: 0.7.3

View File

@@ -15,6 +15,51 @@
* external/cwe/cwe-787
*/
/*
* High-level description of the query:
*
* The goal of this query is to identify issues such as:
* ```cpp
* 1. int* base = new int[size];
* 2. int* end = base + size;
* 3. for(int* p = base; p <= end; ++p) {
* 4. *p = 0; // BUG: Should have been bounded by `p < end`.
* 5. }
* ```
* In order to do this, we split the problem into three subtasks:
* 1. First, we find flow from `new int[size]` to `base + size`.
* 2. Then, we find flow from `base + size` to `end` (on line 3).
* 3. Finally, we use range-analysis to find a write to (or read from) a pointer that may be greater than or equal to `end`.
*
* Step 1 is implemented in `AllocationToInvalidPointer.qll`, and step 2 is implemented by
* `InvalidPointerToDereference.qll`. See those files for the description of these.
*
* This file imports both libraries and defines a final dataflow configuration that constructs the full path from
* the allocation to the dereference of the out-of-bounds pointer. This is done for several reasons:
* 1. It means the user is able to inspect the entire path from the allocation to the dereference, which can be useful
* to understand the problem highlighted.
* 2. It ensures that the call-contexts line up correctly when we transition from step 1 to step 2. See the
* `test_missing_call_context_1` and `test_missing_call_context_2` tests for how this may flag false positives
* without this final configuration.
*
* The source of the final path is an allocation that is:
* 1. identified as flowing to an invalid pointer (by `AllocationToInvalidPointer`), and
* 2. for which the invalid pointer flows to a dereference (as identified by `InvalidPointerToDereference`).
*
* The path can be described in 3 "chunks":
* 1. One path from the allocation to the construction of the invalid pointer
* 2. Another path from the construction of the invalid pointer to the final pointer that is about to be dereferenced.
* 3. Finally, a single step from the dataflow node that represents the final pointer to the dereference.
*
* Step 1 happens when the flow state is `TInitial`, and step 2 and 3 happen when the flow state is `TPointerArith(pai)`
* where the pointer-arithmetic instruction `pai` tracks the instruction that generated the out-of-bounds pointer. This
* instruction is used in the construction of the alert message.
*
* The set of pointer-arithmetic instructions that define the `TPointerArith` flow state is restricted to be the pointer-
* arithmetic instructions that both receive flow from the allocation (as identified by `AllocationToInvalidPointer.qll`),
* and further flow to a dereference (as identified by `InvalidPointerToDereference.qll`).
*/
import cpp
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.ir.IR

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.7.1
version: 0.7.3
groups:
- cpp
- queries

View File

@@ -1308,6 +1308,11 @@ union_etc.cpp:
# 6| Type = [IntType] int
# 6| ValueCategory = prvalue(load)
# 6| getStmt(1): [ReturnStmt] return ...
# 7| [GlobalVariable] S s
# 7| getInitializer(): [Initializer] initializer for s
# 7| getExpr(): [ConstructorCall] call to S
# 7| Type = [VoidType] void
# 7| ValueCategory = prvalue
# 9| [CopyAssignmentOperator] C& C::operator=(C const&)
# 9| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
@@ -1332,6 +1337,7 @@ union_etc.cpp:
# 12| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] U &&
# 14| [GlobalVariable] C c
# 16| [CopyAssignmentOperator] U& U::operator=(U const&)
# 16| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
@@ -1356,6 +1362,7 @@ union_etc.cpp:
# 18| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] C &&
# 20| [GlobalVariable] U u
# 22| [TopLevelFunction] int foo()
# 22| <params>:
# 22| getEntryPoint(): [BlockStmt] { ... }

View File

@@ -69,12 +69,6 @@ edges
| test.cpp:322:19:322:27 | ... + ... | test.cpp:325:24:325:26 | end |
| test.cpp:324:23:324:26 | temp | test.cpp:324:23:324:32 | ... + ... |
| test.cpp:324:23:324:32 | ... + ... | test.cpp:325:15:325:19 | temp2 |
| test.cpp:351:9:351:11 | arr | test.cpp:351:9:351:14 | access to array |
| test.cpp:351:9:351:11 | arr | test.cpp:351:18:351:25 | access to array |
| test.cpp:351:18:351:20 | arr | test.cpp:351:9:351:14 | access to array |
| test.cpp:351:18:351:20 | arr | test.cpp:351:18:351:25 | access to array |
| test.cpp:351:29:351:31 | arr | test.cpp:351:9:351:14 | access to array |
| test.cpp:351:29:351:31 | arr | test.cpp:351:18:351:25 | access to array |
nodes
| test.cpp:34:5:34:24 | access to array | semmle.label | access to array |
| test.cpp:34:10:34:12 | buf | semmle.label | buf |
@@ -167,11 +161,6 @@ nodes
| test.cpp:325:15:325:19 | temp2 | semmle.label | temp2 |
| test.cpp:325:24:325:26 | end | semmle.label | end |
| test.cpp:325:24:325:26 | end | semmle.label | end |
| test.cpp:351:9:351:11 | arr | semmle.label | arr |
| test.cpp:351:9:351:14 | access to array | semmle.label | access to array |
| test.cpp:351:18:351:20 | arr | semmle.label | arr |
| test.cpp:351:18:351:25 | access to array | semmle.label | access to array |
| test.cpp:351:29:351:31 | arr | semmle.label | arr |
subpaths
#select
| test.cpp:35:5:35:22 | PointerAdd: access to array | test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:35:5:35:26 | Store: ... = ... | write |
@@ -194,6 +183,3 @@ subpaths
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:330:13:330:24 | Store: ... = ... | write |
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:331:13:331:24 | Store: ... = ... | write |
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:333:13:333:24 | Store: ... = ... | write |
| test.cpp:351:18:351:25 | PointerAdd: access to array | test.cpp:351:9:351:11 | arr | test.cpp:351:18:351:25 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:348:9:348:11 | arr | arr | test.cpp:351:18:351:25 | Load: access to array | read |
| test.cpp:351:18:351:25 | PointerAdd: access to array | test.cpp:351:18:351:20 | arr | test.cpp:351:18:351:25 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:348:9:348:11 | arr | arr | test.cpp:351:18:351:25 | Load: access to array | read |
| test.cpp:351:18:351:25 | PointerAdd: access to array | test.cpp:351:29:351:31 | arr | test.cpp:351:18:351:25 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:348:9:348:11 | arr | arr | test.cpp:351:18:351:25 | Load: access to array | read |

View File

@@ -348,7 +348,7 @@ int positiveRange(int x) {
int arr[128];
for(int i=127-offset; i>= 0; i--) {
arr[i] = arr[i+1] + arr[i+offset]; // GOOD [FALSE POSITIVE]
arr[i] = arr[i+1] + arr[i+offset]; // GOOD
}
return arr[0];
}

View File

@@ -129,7 +129,6 @@ edges
| test.cpp:271:14:271:21 | ... + ... | test.cpp:271:14:271:21 | ... + ... |
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
| test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | ... = ... |
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
| test.cpp:355:14:355:27 | new[] | test.cpp:357:24:357:30 | ... + ... |
@@ -214,13 +213,26 @@ edges
| test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... |
| test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... |
| test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... |
| test.cpp:652:14:652:27 | new[] | test.cpp:656:3:656:6 | ... ++ |
| test.cpp:652:14:652:27 | new[] | test.cpp:656:3:656:6 | ... ++ |
| test.cpp:652:14:652:27 | new[] | test.cpp:662:3:662:11 | ... = ... |
| test.cpp:656:3:656:6 | ... ++ | test.cpp:656:3:656:6 | ... ++ |
| test.cpp:656:3:656:6 | ... ++ | test.cpp:662:3:662:11 | ... = ... |
| test.cpp:656:3:656:6 | ... ++ | test.cpp:662:3:662:11 | ... = ... |
| test.cpp:667:14:667:31 | new[] | test.cpp:675:7:675:23 | ... = ... |
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
| test.cpp:698:5:698:10 | ... += ... | test.cpp:698:5:698:10 | ... += ... |
| test.cpp:698:5:698:10 | ... += ... | test.cpp:701:15:701:16 | * ... |
| test.cpp:705:18:705:18 | q | test.cpp:705:18:705:18 | q |
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
| test.cpp:711:13:711:26 | new[] | test.cpp:714:11:714:11 | q |
| test.cpp:714:11:714:11 | q | test.cpp:705:18:705:18 | q |
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
| test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... |
| test.cpp:732:16:732:26 | ... + ... | test.cpp:732:16:732:26 | ... + ... |
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
| test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array |
| test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array |
| test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array |
| test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array |
| test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array |
nodes
| test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc |
| test.cpp:5:15:5:22 | ... + ... | semmle.label | ... + ... |
@@ -313,8 +325,6 @@ nodes
| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... |
| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... |
| test.cpp:274:5:274:10 | ... = ... | semmle.label | ... = ... |
| test.cpp:304:15:304:26 | new[] | semmle.label | new[] |
| test.cpp:308:5:308:29 | ... = ... | semmle.label | ... = ... |
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
@@ -364,12 +374,26 @@ nodes
| test.cpp:559:5:559:19 | ... = ... | semmle.label | ... = ... |
| test.cpp:642:14:642:31 | new[] | semmle.label | new[] |
| test.cpp:647:5:647:19 | ... = ... | semmle.label | ... = ... |
| test.cpp:652:14:652:27 | new[] | semmle.label | new[] |
| test.cpp:656:3:656:6 | ... ++ | semmle.label | ... ++ |
| test.cpp:656:3:656:6 | ... ++ | semmle.label | ... ++ |
| test.cpp:662:3:662:11 | ... = ... | semmle.label | ... = ... |
| test.cpp:667:14:667:31 | new[] | semmle.label | new[] |
| test.cpp:675:7:675:23 | ... = ... | semmle.label | ... = ... |
| test.cpp:695:13:695:26 | new[] | semmle.label | new[] |
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
| test.cpp:701:15:701:16 | * ... | semmle.label | * ... |
| test.cpp:705:18:705:18 | q | semmle.label | q |
| test.cpp:705:18:705:18 | q | semmle.label | q |
| test.cpp:706:12:706:13 | * ... | semmle.label | * ... |
| test.cpp:711:13:711:26 | new[] | semmle.label | new[] |
| test.cpp:714:11:714:11 | q | semmle.label | q |
| test.cpp:730:12:730:28 | new[] | semmle.label | new[] |
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
| test.cpp:733:5:733:12 | ... = ... | semmle.label | ... = ... |
| test.cpp:754:18:754:31 | new[] | semmle.label | new[] |
| test.cpp:767:16:767:29 | access to array | semmle.label | access to array |
| test.cpp:767:16:767:29 | access to array | semmle.label | access to array |
| test.cpp:772:16:772:29 | access to array | semmle.label | access to array |
| test.cpp:772:16:772:29 | access to array | semmle.label | access to array |
| test.cpp:781:14:781:27 | new[] | semmle.label | new[] |
| test.cpp:786:18:786:27 | access to array | semmle.label | access to array |
subpaths
#select
| test.cpp:6:14:6:15 | * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size |
@@ -391,7 +415,6 @@ subpaths
| test.cpp:254:9:254:16 | ... = ... | test.cpp:248:24:248:30 | call to realloc | test.cpp:254:9:254:16 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:248:24:248:30 | call to realloc | call to realloc | test.cpp:254:11:254:11 | i | i |
| test.cpp:264:13:264:14 | * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len |
| test.cpp:274:5:274:10 | ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len |
| test.cpp:308:5:308:29 | ... = ... | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:304:15:304:26 | new[] | new[] | test.cpp:308:8:308:10 | ... + ... | ... + ... |
| test.cpp:358:14:358:26 | * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
| test.cpp:359:14:359:32 | * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
| test.cpp:384:13:384:16 | * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size |
@@ -403,5 +426,11 @@ subpaths
| test.cpp:548:5:548:19 | ... = ... | test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:543:14:543:27 | new[] | new[] | test.cpp:548:8:548:14 | src_pos | src_pos |
| test.cpp:559:5:559:19 | ... = ... | test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:554:14:554:27 | new[] | new[] | test.cpp:559:8:559:14 | src_pos | src_pos |
| test.cpp:647:5:647:19 | ... = ... | test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:642:14:642:31 | new[] | new[] | test.cpp:647:8:647:14 | src_pos | src_pos |
| test.cpp:662:3:662:11 | ... = ... | test.cpp:652:14:652:27 | new[] | test.cpp:662:3:662:11 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:652:14:652:27 | new[] | new[] | test.cpp:653:19:653:22 | size | size |
| test.cpp:675:7:675:23 | ... = ... | test.cpp:667:14:667:31 | new[] | test.cpp:675:7:675:23 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:667:14:667:31 | new[] | new[] | test.cpp:675:10:675:18 | ... ++ | ... ++ |
| test.cpp:701:15:701:16 | * ... | test.cpp:695:13:695:26 | new[] | test.cpp:701:15:701:16 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:695:13:695:26 | new[] | new[] | test.cpp:696:19:696:22 | size | size |
| test.cpp:706:12:706:13 | * ... | test.cpp:711:13:711:26 | new[] | test.cpp:706:12:706:13 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:711:13:711:26 | new[] | new[] | test.cpp:712:19:712:22 | size | size |
| test.cpp:733:5:733:12 | ... = ... | test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:730:12:730:28 | new[] | new[] | test.cpp:732:21:732:25 | ... + ... | ... + ... |
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:767:22:767:28 | ... + ... | ... + ... |
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:772:22:772:28 | ... + ... | ... + ... |
| test.cpp:772:16:772:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:767:22:767:28 | ... + ... | ... + ... |
| test.cpp:772:16:772:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:772:22:772:28 | ... + ... | ... + ... |
| test.cpp:786:18:786:27 | access to array | test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:781:14:781:27 | new[] | new[] | test.cpp:786:20:786:26 | ... + ... | ... + ... |

View File

@@ -305,7 +305,7 @@ void test21() {
for (int i = 0; i < n; i += 2) {
xs[i] = test21_get(i); // GOOD
xs[i+1] = test21_get(i+1); // $ alloc=L304 alloc=L304-1 deref=L308 // GOOD [FALSE POSITIVE]
xs[i+1] = test21_get(i+1); // GOOD
}
}
@@ -659,7 +659,7 @@ void test32(unsigned size) {
xs++;
if (xs >= end)
return;
xs[0] = 0; // $ deref=L656->L662+1 deref=L657->L662+1 GOOD [FALSE POSITIVE]
xs[0] = 0; // GOOD
}
void test33(unsigned size, unsigned src_pos)
@@ -672,7 +672,7 @@ void test33(unsigned size, unsigned src_pos)
while (dst_pos < size - 1) {
dst_pos++;
if (true)
xs[dst_pos++] = 0; // $ alloc=L667+1 deref=L675 // GOOD [FALSE POSITIVE]
xs[dst_pos++] = 0; // GOOD
}
}
@@ -689,4 +689,102 @@ void test_missing_call_context_2(unsigned size) {
int* p = new int[size];
int* end_minus_one = pointer_arithmetic(p, size - 1);
*end_minus_one = '0'; // $ deref=L680->L690->L691 // GOOD
}
void test34(unsigned size) {
char *p = new char[size];
char *end = p + size + 1; // $ alloc=L695
if (p + 1 < end) {
p += 1;
}
if (p + 1 < end) {
int val = *p; // $ deref=L698->L700->L701 // GOOD [FALSE POSITIVE]
}
}
void deref(char* q) {
char x = *q; // $ deref=L714->L705->L706 // BAD
}
void test35(unsigned long size, char* q)
{
char* p = new char[size];
char* end = p + size; // $ alloc=L711
if(q <= end) {
deref(q);
}
}
void test21_simple(bool b) {
int n = 0;
if (b) n = 2;
int* xs = new int[n];
for (int i = 0; i < n; i += 2) {
xs[i+1] = 0; // GOOD
}
}
void test36(unsigned size, unsigned n) {
int* p = new int[size + 2];
if(n < size + 1) {
int* end = p + (n + 2); // $ alloc=L730+2
*end = 0; // $ deref=L733 // BAD
}
}
void test37(unsigned long n)
{
int *p = new int[n];
for (unsigned long i = n; i != 0u; i--)
{
p[n - i] = 0; // GOOD
}
}
unsigned get(char);
void exit(int);
void error(const char * msg) {
exit(1);
}
void test38(unsigned size) {
char * alloc = new char[size];
unsigned pos = 0;
while (pos < size) {
char kind = alloc[pos];
unsigned n = get(alloc[pos]);
if (pos + n >= size) {
error("");
}
switch (kind) {
case '0':
if (n != 1)
error("");
char x = alloc[pos + 1]; // $ alloc=L754 deref=L767 // GOOD [FALSE POSITIVE]
break;
case '1':
if (n != 2)
error("");
char a = alloc[pos + 1]; // $ alloc=L754 deref=L772 // GOOD [FALSE POSITIVE]
char b = alloc[pos + 2];
break;
}
pos += 1 + n;
}
}
void test38_simple(unsigned size, unsigned pos, unsigned numParams) {
char * p = new char[size];
if (pos < size) {
if (pos + numParams < size) {
if (numParams == 1) {
char x = p[pos + 1]; // $ alloc=L781 deref=L786 // GOOD [FALSE POSITIVE]
}
}
}
}

View File

@@ -16,3 +16,5 @@ class AddressOfGetter {
&field;
}
};
__declspec("SAL_volatile") char* pBuf;

View File

@@ -4,6 +4,7 @@
| ms_var_attributes.cpp:8:15:8:20 | myInt4 | ms_var_attributes.cpp:8:1:8:9 | dllexport |
| ms_var_attributes.cpp:9:5:9:10 | myInt5 | ms_var_attributes.h:7:1:7:9 | dllexport |
| ms_var_attributes.cpp:12:42:12:46 | field | ms_var_attributes.cpp:12:14:12:21 | property |
| ms_var_attributes.cpp:20:34:20:37 | pBuf | ms_var_attributes.cpp:20:12:20:12 | SAL_volatile |
| ms_var_attributes.h:5:22:5:27 | myInt3 | ms_var_attributes.h:5:1:5:9 | dllexport |
| var_attributes.c:1:12:1:19 | weak_var | var_attributes.c:1:36:1:39 | weak |
| var_attributes.c:2:12:2:22 | weakref_var | var_attributes.c:2:39:2:45 | weakref |

View File

@@ -732,7 +732,7 @@ void test_does_not_write_source_to_dereference()
{
int x;
does_not_write_source_to_dereference(&x);
sink(x); // $ ast,ir=733:7 SPURIOUS: ast,ir=726:11
sink(x); // $ ast=733:7 ir SPURIOUS: ast=726:11
}
void sometimes_calls_sink_eq(int x, int n) {

View File

@@ -134,7 +134,7 @@ void pointer_test() {
sink(*p3); // $ ast,ir
*p3 = 0;
sink(*p3); // $ SPURIOUS: ast,ir
sink(*p3); // $ SPURIOUS: ast
}
// --- return values ---

View File

@@ -1,3 +0,0 @@
| file://:0:0:0:0 | There was an error during this compilation |
| float128.cpp:1:39:1:39 | 128-bit floating-point types are not supported in this configuration |
| float128.cpp:2:30:2:30 | 128-bit floating-point types are not supported in this configuration |

View File

@@ -1,4 +0,0 @@
import cpp
from Diagnostic d
select d

View File

@@ -1,5 +1,5 @@
typedef _Complex float __attribute__((mode(TC))) _Complex128; // [COMPILER ERROR AND ERROR-TYPE DUE TO __float128 BEING DISABLED]
typedef float __attribute__((mode(TF))) _Float128; // [COMPILER ERROR AND ERROR-TYPE DUE TO __float128 BEING DISABLED]
typedef _Complex float __attribute__((mode(TC))) _Complex128;
typedef float __attribute__((mode(TF))) _Float128;
int main() {
__float128 f = 1.0f;
@@ -25,4 +25,3 @@ __float128 id(__float128 q)
{
return q;
}
// semmle-extractor-options: --expect_errors

View File

@@ -1,5 +1,5 @@
| float128.cpp:1:50:1:60 | _Complex128 | file://:0:0:0:0 | <error-type> |
| float128.cpp:2:41:2:49 | _Float128 | file://:0:0:0:0 | <error-type> |
| float128.cpp:1:50:1:60 | _Complex128 | file://:0:0:0:0 | float __complex__ |
| float128.cpp:2:41:2:49 | _Float128 | file://:0:0:0:0 | __float128 |
| float128.cpp:13:29:13:54 | __is_floating_point_helper<T> | float128.cpp:10:8:10:17 | false_type |
| float128.cpp:14:19:14:51 | __is_floating_point_helper<float> | float128.cpp:11:8:11:16 | true_type |
| float128.cpp:15:19:15:52 | __is_floating_point_helper<double> | float128.cpp:11:8:11:16 | true_type |

View File

@@ -1728,6 +1728,76 @@ complex.c:
# 144| Type = [LongDoubleType] long double
# 144| ValueCategory = prvalue
# 145| getStmt(72): [ReturnStmt] return ...
ir.c:
# 5| [TopLevelFunction] int getX(MyCoords*)
# 5| <params>:
# 5| getParameter(0): [Parameter] coords
# 5| Type = [PointerType] MyCoords *
# 7| [TopLevelFunction] void MyCoordsTest(int)
# 7| <params>:
# 7| getParameter(0): [Parameter] pos
# 7| Type = [IntType] int
# 7| getEntryPoint(): [BlockStmt] { ... }
# 8| getStmt(0): [DeclStmt] declaration
# 8| getDeclarationEntry(0): [VariableDeclarationEntry] definition of coords
# 8| Type = [CTypedefType] MyCoords
# 8| getVariable().getInitializer(): [Initializer] initializer for coords
# 8| getExpr(): [ClassAggregateLiteral] {...}
# 8| Type = [Struct] (unnamed class/struct/union)
# 8| ValueCategory = prvalue
# 8| getAFieldExpr(x): [Literal] 0
# 8| Type = [IntType] int
# 8| Value = [Literal] 0
# 8| ValueCategory = prvalue
# 9| getStmt(1): [ExprStmt] ExprStmt
# 9| getExpr(): [AssignExpr] ... = ...
# 9| Type = [IntType] int
# 9| ValueCategory = prvalue
# 9| getLValue(): [ValueFieldAccess] x
# 9| Type = [IntType] int
# 9| ValueCategory = lvalue
# 9| getQualifier(): [VariableAccess] coords
# 9| Type = [CTypedefType] MyCoords
# 9| ValueCategory = lvalue
# 9| getRValue(): [AssignExpr] ... = ...
# 9| Type = [IntType] int
# 9| ValueCategory = prvalue
# 9| getLValue(): [ValueFieldAccess] y
# 9| Type = [IntType] int
# 9| ValueCategory = lvalue
# 9| getQualifier(): [VariableAccess] coords
# 9| Type = [CTypedefType] MyCoords
# 9| ValueCategory = lvalue
# 9| getRValue(): [AddExpr] ... + ...
# 9| Type = [IntType] int
# 9| ValueCategory = prvalue
# 9| getLeftOperand(): [VariableAccess] pos
# 9| Type = [IntType] int
# 9| ValueCategory = prvalue(load)
# 9| getRightOperand(): [Literal] 1
# 9| Type = [IntType] int
# 9| Value = [Literal] 1
# 9| ValueCategory = prvalue
# 10| getStmt(2): [ExprStmt] ExprStmt
# 10| getExpr(): [AssignExpr] ... = ...
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue
# 10| getLValue(): [ValueFieldAccess] x
# 10| Type = [IntType] int
# 10| ValueCategory = lvalue
# 10| getQualifier(): [VariableAccess] coords
# 10| Type = [CTypedefType] MyCoords
# 10| ValueCategory = lvalue
# 10| getRValue(): [FunctionCall] call to getX
# 10| Type = [IntType] int
# 10| ValueCategory = prvalue
# 10| getArgument(0): [AddressOfExpr] & ...
# 10| Type = [PointerType] MyCoords *
# 10| ValueCategory = prvalue
# 10| getOperand(): [VariableAccess] coords
# 10| Type = [CTypedefType] MyCoords
# 10| ValueCategory = lvalue
# 11| getStmt(3): [ReturnStmt] return ...
ir.cpp:
# 1| [TopLevelFunction] void Constants()
# 1| <params>:
@@ -8529,6 +8599,11 @@ ir.cpp:
# 1035| Type = [Struct] EmptyStruct
# 1035| ValueCategory = prvalue
# 1036| getStmt(1): [ReturnStmt] return ...
# 1038| [GlobalVariable] (lambda [] type at line 1038, col. 12) lam
# 1038| getInitializer(): [Initializer] initializer for lam
# 1038| getExpr(): [LambdaExpression] [...](...){...}
# 1038| Type = [Closure] decltype([...](...){...})
# 1038| ValueCategory = prvalue
# 1038| [CopyAssignmentOperator] (lambda [] type at line 1038, col. 12)& (lambda [] type at line 1038, col. 12)::operator=((lambda [] type at line 1038, col. 12) const&)
# 1038| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
@@ -13976,6 +14051,54 @@ ir.cpp:
# 1815| Type = [IntType] int
# 1815| ValueCategory = prvalue(load)
# 1817| getStmt(8): [ReturnStmt] return ...
# 1821| [GlobalVariable] int global_2
# 1821| getInitializer(): [Initializer] initializer for global_2
# 1821| getExpr(): [Literal] 1
# 1821| Type = [IntType] int
# 1821| Value = [Literal] 1
# 1821| ValueCategory = prvalue
# 1823| [GlobalVariable] int const global_3
# 1823| getInitializer(): [Initializer] initializer for global_3
# 1823| getExpr(): [Literal] 2
# 1823| Type = [IntType] int
# 1823| Value = [Literal] 2
# 1823| ValueCategory = prvalue
# 1825| [GlobalVariable] constructor_only global_4
# 1825| getInitializer(): [Initializer] initializer for global_4
# 1825| getExpr(): [ConstructorCall] call to constructor_only
# 1825| Type = [VoidType] void
# 1825| ValueCategory = prvalue
# 1825| getArgument(0): [Literal] 1
# 1825| Type = [IntType] int
# 1825| Value = [Literal] 1
# 1825| ValueCategory = prvalue
# 1827| [GlobalVariable] constructor_only global_5
# 1827| getInitializer(): [Initializer] initializer for global_5
# 1827| getExpr(): [ConstructorCall] call to constructor_only
# 1827| Type = [VoidType] void
# 1827| ValueCategory = prvalue
# 1827| getArgument(0): [Literal] 2
# 1827| Type = [IntType] int
# 1827| Value = [Literal] 2
# 1827| ValueCategory = prvalue
# 1829| [GlobalVariable] char* global_string
# 1829| getInitializer(): [Initializer] initializer for global_string
# 1829| getExpr(): global string
# 1829| Type = [ArrayType] const char[14]
# 1829| Value = [StringLiteral] "global string"
# 1829| ValueCategory = lvalue
# 1829| getExpr().getFullyConverted(): [CStyleCast] (char *)...
# 1829| Conversion = [PointerConversion] pointer conversion
# 1829| Type = [CharPointerType] char *
# 1829| ValueCategory = prvalue
# 1829| getExpr(): [ArrayToPointerConversion] array to pointer conversion
# 1829| Type = [PointerType] const char *
# 1829| ValueCategory = prvalue
# 1831| [GlobalVariable] int global_6
# 1831| getInitializer(): [Initializer] initializer for global_6
# 1831| getExpr(): [VariableAccess] global_2
# 1831| Type = [IntType] int
# 1831| ValueCategory = prvalue(load)
# 1834| [CopyAssignmentOperator] block_assignment::A& block_assignment::A::operator=(block_assignment::A const&)
# 1834| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
@@ -14377,6 +14500,23 @@ ir.cpp:
# 1885| Type = [ClassTemplateInstantiation,Struct] Bar2<int>
# 1885| ValueCategory = lvalue
# 1886| getStmt(2): [ReturnStmt] return ...
# 1889| [GlobalVariable] char global_template<char>
# 1889| getInitializer(): [Initializer] initializer for global_template
# 1889| getExpr(): [Literal] 42
# 1889| Type = [IntType] int
# 1889| Value = [Literal] 42
# 1889| ValueCategory = prvalue
# 1889| getExpr().getFullyConverted(): [CStyleCast] (char)...
# 1889| Conversion = [IntegralConversion] integral conversion
# 1889| Type = [PlainCharType] char
# 1889| Value = [CStyleCast] 42
# 1889| ValueCategory = prvalue
# 1889| [GlobalVariable] int global_template<int>
# 1889| getInitializer(): [Initializer] initializer for global_template
# 1889| getExpr(): [Literal] 42
# 1889| Type = [IntType] int
# 1889| Value = [Literal] 42
# 1889| ValueCategory = prvalue
# 1891| [TopLevelFunction] int test_global_template_int()
# 1891| <params>:
# 1891| getEntryPoint(): [BlockStmt] { ... }
@@ -14888,6 +15028,514 @@ ir.cpp:
# 1993| Type = [Class] C
# 1993| ValueCategory = lvalue
# 1994| getStmt(3): [ReturnStmt] return ...
# 1996| [TopLevelFunction] void TernaryTestInt(bool, int, int, int)
# 1996| <params>:
# 1996| getParameter(0): [Parameter] a
# 1996| Type = [BoolType] bool
# 1996| getParameter(1): [Parameter] x
# 1996| Type = [IntType] int
# 1996| getParameter(2): [Parameter] y
# 1996| Type = [IntType] int
# 1996| getParameter(3): [Parameter] z
# 1996| Type = [IntType] int
# 1996| getEntryPoint(): [BlockStmt] { ... }
# 1997| getStmt(0): [ExprStmt] ExprStmt
# 1997| getExpr(): [AssignExpr] ... = ...
# 1997| Type = [IntType] int
# 1997| ValueCategory = lvalue
# 1997| getLValue(): [VariableAccess] z
# 1997| Type = [IntType] int
# 1997| ValueCategory = lvalue
# 1997| getRValue(): [ConditionalExpr] ... ? ... : ...
# 1997| Type = [IntType] int
# 1997| ValueCategory = prvalue
# 1997| getCondition(): [VariableAccess] a
# 1997| Type = [BoolType] bool
# 1997| ValueCategory = prvalue(load)
# 1997| getThen(): [VariableAccess] x
# 1997| Type = [IntType] int
# 1997| ValueCategory = prvalue(load)
# 1997| getElse(): [VariableAccess] y
# 1997| Type = [IntType] int
# 1997| ValueCategory = prvalue(load)
# 1998| getStmt(1): [ExprStmt] ExprStmt
# 1998| getExpr(): [AssignExpr] ... = ...
# 1998| Type = [IntType] int
# 1998| ValueCategory = lvalue
# 1998| getLValue(): [VariableAccess] z
# 1998| Type = [IntType] int
# 1998| ValueCategory = lvalue
# 1998| getRValue(): [ConditionalExpr] ... ? ... : ...
# 1998| Type = [IntType] int
# 1998| ValueCategory = prvalue
# 1998| getCondition(): [VariableAccess] a
# 1998| Type = [BoolType] bool
# 1998| ValueCategory = prvalue(load)
# 1998| getThen(): [VariableAccess] x
# 1998| Type = [IntType] int
# 1998| ValueCategory = prvalue(load)
# 1998| getElse(): [Literal] 5
# 1998| Type = [IntType] int
# 1998| Value = [Literal] 5
# 1998| ValueCategory = prvalue
# 1999| getStmt(2): [ExprStmt] ExprStmt
# 1999| getExpr(): [AssignExpr] ... = ...
# 1999| Type = [IntType] int
# 1999| ValueCategory = lvalue
# 1999| getLValue(): [VariableAccess] z
# 1999| Type = [IntType] int
# 1999| ValueCategory = lvalue
# 1999| getRValue(): [ConditionalExpr] ... ? ... : ...
# 1999| Type = [IntType] int
# 1999| ValueCategory = prvalue
# 1999| getCondition(): [VariableAccess] a
# 1999| Type = [BoolType] bool
# 1999| ValueCategory = prvalue(load)
# 1999| getThen(): [Literal] 3
# 1999| Type = [IntType] int
# 1999| Value = [Literal] 3
# 1999| ValueCategory = prvalue
# 1999| getElse(): [Literal] 5
# 1999| Type = [IntType] int
# 1999| Value = [Literal] 5
# 1999| ValueCategory = prvalue
# 2000| getStmt(3): [ExprStmt] ExprStmt
# 2000| getExpr(): [AssignExpr] ... = ...
# 2000| Type = [IntType] int
# 2000| ValueCategory = lvalue
# 2000| getLValue(): [ConditionalExpr] ... ? ... : ...
# 2000| Type = [IntType] int
# 2000| ValueCategory = lvalue
# 2000| getCondition(): [VariableAccess] a
# 2000| Type = [BoolType] bool
# 2000| ValueCategory = prvalue(load)
# 2000| getThen(): [VariableAccess] x
# 2000| Type = [IntType] int
# 2000| ValueCategory = lvalue
# 2000| getElse(): [VariableAccess] y
# 2000| Type = [IntType] int
# 2000| ValueCategory = lvalue
# 2000| getRValue(): [Literal] 7
# 2000| Type = [IntType] int
# 2000| Value = [Literal] 7
# 2000| ValueCategory = prvalue
# 2000| getLValue().getFullyConverted(): [ParenthesisExpr] (...)
# 2000| Type = [IntType] int
# 2000| ValueCategory = lvalue
# 2001| getStmt(4): [ReturnStmt] return ...
# 2003| [CopyAssignmentOperator] TernaryPodObj& TernaryPodObj::operator=(TernaryPodObj const&)
# 2003| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const TernaryPodObj &
# 2003| [MoveAssignmentOperator] TernaryPodObj& TernaryPodObj::operator=(TernaryPodObj&&)
# 2003| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] TernaryPodObj &&
# 2006| [TopLevelFunction] void TernaryTestPodObj(bool, TernaryPodObj, TernaryPodObj, TernaryPodObj)
# 2006| <params>:
# 2006| getParameter(0): [Parameter] a
# 2006| Type = [BoolType] bool
# 2006| getParameter(1): [Parameter] x
# 2006| Type = [Struct] TernaryPodObj
# 2006| getParameter(2): [Parameter] y
# 2006| Type = [Struct] TernaryPodObj
# 2006| getParameter(3): [Parameter] z
# 2006| Type = [Struct] TernaryPodObj
# 2006| getEntryPoint(): [BlockStmt] { ... }
# 2007| getStmt(0): [ExprStmt] ExprStmt
# 2007| getExpr(): [AssignExpr] ... = ...
# 2007| Type = [Struct] TernaryPodObj
# 2007| ValueCategory = lvalue
# 2007| getLValue(): [VariableAccess] z
# 2007| Type = [Struct] TernaryPodObj
# 2007| ValueCategory = lvalue
# 2007| getRValue(): [ConditionalExpr] ... ? ... : ...
# 2007| Type = [Struct] TernaryPodObj
# 2007| ValueCategory = prvalue
# 2007| getCondition(): [VariableAccess] a
# 2007| Type = [BoolType] bool
# 2007| ValueCategory = prvalue(load)
# 2007| getThen(): [VariableAccess] x
# 2007| Type = [Struct] TernaryPodObj
# 2007| ValueCategory = prvalue(load)
# 2007| getElse(): [VariableAccess] y
# 2007| Type = [Struct] TernaryPodObj
# 2007| ValueCategory = prvalue(load)
# 2008| getStmt(1): [ExprStmt] ExprStmt
# 2008| getExpr(): [AssignExpr] ... = ...
# 2008| Type = [Struct] TernaryPodObj
# 2008| ValueCategory = lvalue
# 2008| getLValue(): [VariableAccess] z
# 2008| Type = [Struct] TernaryPodObj
# 2008| ValueCategory = lvalue
# 2008| getRValue(): [ConditionalExpr] ... ? ... : ...
# 2008| Type = [Struct] TernaryPodObj
# 2008| ValueCategory = prvalue
# 2008| getCondition(): [VariableAccess] a
# 2008| Type = [BoolType] bool
# 2008| ValueCategory = prvalue(load)
# 2008| getThen(): [VariableAccess] x
# 2008| Type = [Struct] TernaryPodObj
# 2008| ValueCategory = prvalue(load)
# 2008| getElse(): [Literal] 0
# 2008| Type = [Struct] TernaryPodObj
# 2008| Value = [Literal] 0
# 2008| ValueCategory = prvalue
# 2008| getThen().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2008| Type = [Struct] TernaryPodObj
# 2008| ValueCategory = prvalue(load)
# 2008| getElse().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2008| Type = [Struct] TernaryPodObj
# 2008| ValueCategory = prvalue(load)
# 2008| getRValue().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2008| Type = [Struct] TernaryPodObj
# 2008| ValueCategory = prvalue(load)
# 2009| getStmt(2): [ExprStmt] ExprStmt
# 2009| getExpr(): [AssignExpr] ... = ...
# 2009| Type = [Struct] TernaryPodObj
# 2009| ValueCategory = lvalue
# 2009| getLValue(): [VariableAccess] z
# 2009| Type = [Struct] TernaryPodObj
# 2009| ValueCategory = lvalue
# 2009| getRValue(): [ConditionalExpr] ... ? ... : ...
# 2009| Type = [Struct] TernaryPodObj
# 2009| ValueCategory = prvalue
# 2009| getCondition(): [VariableAccess] a
# 2009| Type = [BoolType] bool
# 2009| ValueCategory = prvalue(load)
# 2009| getThen(): [Literal] 0
# 2009| Type = [Struct] TernaryPodObj
# 2009| Value = [Literal] 0
# 2009| ValueCategory = prvalue
# 2009| getElse(): [Literal] 0
# 2009| Type = [Struct] TernaryPodObj
# 2009| Value = [Literal] 0
# 2009| ValueCategory = prvalue
# 2009| getThen().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2009| Type = [Struct] TernaryPodObj
# 2009| ValueCategory = prvalue(load)
# 2009| getElse().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2009| Type = [Struct] TernaryPodObj
# 2009| ValueCategory = prvalue(load)
# 2009| getRValue().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2009| Type = [Struct] TernaryPodObj
# 2009| ValueCategory = prvalue(load)
# 2010| getStmt(3): [ExprStmt] ExprStmt
# 2010| getExpr(): [AssignExpr] ... = ...
# 2010| Type = [Struct] TernaryPodObj
# 2010| ValueCategory = lvalue
# 2010| getLValue(): [AssignExpr] ... = ...
# 2010| Type = [Struct] TernaryPodObj
# 2010| ValueCategory = lvalue
# 2010| getLValue(): [VariableAccess] z
# 2010| Type = [Struct] TernaryPodObj
# 2010| ValueCategory = lvalue
# 2010| getRValue(): [ConditionalExpr] ... ? ... : ...
# 2010| Type = [Struct] TernaryPodObj
# 2010| ValueCategory = prvalue
# 2010| getCondition(): [VariableAccess] a
# 2010| Type = [BoolType] bool
# 2010| ValueCategory = prvalue(load)
# 2010| getThen(): [VariableAccess] x
# 2010| Type = [Struct] TernaryPodObj
# 2010| ValueCategory = prvalue(load)
# 2010| getElse(): [VariableAccess] y
# 2010| Type = [Struct] TernaryPodObj
# 2010| ValueCategory = prvalue(load)
# 2010| getRValue(): [Literal] 0
# 2010| Type = [Struct] TernaryPodObj
# 2010| Value = [Literal] 0
# 2010| ValueCategory = prvalue
# 2010| getLValue().getFullyConverted(): [ParenthesisExpr] (...)
# 2010| Type = [Struct] TernaryPodObj
# 2010| ValueCategory = lvalue
# 2010| getRValue().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2010| Type = [Struct] TernaryPodObj
# 2010| ValueCategory = prvalue(load)
# 2011| getStmt(4): [ReturnStmt] return ...
# 2013| [CopyAssignmentOperator] TernaryNonPodObj& TernaryNonPodObj::operator=(TernaryNonPodObj const&)
# 2013| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const TernaryNonPodObj &
#-----| getEntryPoint(): [BlockStmt] { ... }
#-----| getStmt(0): [ReturnStmt] return ...
#-----| getExpr(): [PointerDereferenceExpr] * ...
#-----| Type = [Struct] TernaryNonPodObj
#-----| ValueCategory = lvalue
#-----| getOperand(): [ThisExpr] this
#-----| Type = [PointerType] TernaryNonPodObj *
#-----| ValueCategory = prvalue(load)
#-----| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
#-----| Type = [LValueReferenceType] TernaryNonPodObj &
#-----| ValueCategory = prvalue
# 2013| [Constructor] void TernaryNonPodObj::TernaryNonPodObj()
# 2013| <params>:
# 2013| <initializations>:
# 2013| getEntryPoint(): [BlockStmt] { ... }
# 2013| getStmt(0): [ReturnStmt] return ...
# 2013| [CopyConstructor] void TernaryNonPodObj::TernaryNonPodObj(TernaryNonPodObj const&)
# 2013| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const TernaryNonPodObj &
# 2013| <initializations>:
# 2013| getEntryPoint(): [BlockStmt] { ... }
# 2013| getStmt(0): [ReturnStmt] return ...
# 2014| [Destructor,VirtualFunction] void TernaryNonPodObj::~TernaryNonPodObj()
# 2014| <params>:
# 2014| getEntryPoint(): [BlockStmt] { ... }
# 2014| getStmt(0): [ReturnStmt] return ...
# 2014| <destructions>:
# 2017| [TopLevelFunction] void TernaryTestNonPodObj(bool, TernaryNonPodObj, TernaryNonPodObj, TernaryNonPodObj)
# 2017| <params>:
# 2017| getParameter(0): [Parameter] a
# 2017| Type = [BoolType] bool
# 2017| getParameter(1): [Parameter] x
# 2017| Type = [Struct] TernaryNonPodObj
# 2017| getParameter(2): [Parameter] y
# 2017| Type = [Struct] TernaryNonPodObj
# 2017| getParameter(3): [Parameter] z
# 2017| Type = [Struct] TernaryNonPodObj
# 2017| getEntryPoint(): [BlockStmt] { ... }
# 2018| getStmt(0): [ExprStmt] ExprStmt
# 2018| getExpr(): [FunctionCall] call to operator=
# 2018| Type = [LValueReferenceType] TernaryNonPodObj &
# 2018| ValueCategory = prvalue
# 2018| getQualifier(): [VariableAccess] z
# 2018| Type = [Struct] TernaryNonPodObj
# 2018| ValueCategory = lvalue
# 2018| getArgument(0): [ConditionalExpr] ... ? ... : ...
# 2018| Type = [Struct] TernaryNonPodObj
# 2018| ValueCategory = lvalue
# 2018| getCondition(): [VariableAccess] a
# 2018| Type = [BoolType] bool
# 2018| ValueCategory = prvalue(load)
# 2018| getThen(): [VariableAccess] x
# 2018| Type = [Struct] TernaryNonPodObj
# 2018| ValueCategory = lvalue
# 2018| getElse(): [VariableAccess] y
# 2018| Type = [Struct] TernaryNonPodObj
# 2018| ValueCategory = lvalue
# 2018| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
# 2018| Type = [LValueReferenceType] const TernaryNonPodObj &
# 2018| ValueCategory = prvalue
# 2018| getExpr(): [CStyleCast] (const TernaryNonPodObj)...
# 2018| Conversion = [GlvalueConversion] glvalue conversion
# 2018| Type = [SpecifiedType] const TernaryNonPodObj
# 2018| ValueCategory = lvalue
# 2018| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2018| Type = [Struct] TernaryNonPodObj
# 2018| ValueCategory = lvalue
# 2019| getStmt(1): [ExprStmt] ExprStmt
# 2019| getExpr(): [FunctionCall] call to operator=
# 2019| Type = [LValueReferenceType] TernaryNonPodObj &
# 2019| ValueCategory = prvalue
# 2019| getQualifier(): [VariableAccess] z
# 2019| Type = [Struct] TernaryNonPodObj
# 2019| ValueCategory = lvalue
# 2019| getArgument(0): [ConditionalExpr] ... ? ... : ...
# 2019| Type = [Struct] TernaryNonPodObj
# 2019| ValueCategory = prvalue
# 2019| getCondition(): [VariableAccess] a
# 2019| Type = [BoolType] bool
# 2019| ValueCategory = prvalue(load)
# 2019| getThen(): [ConstructorCall] call to TernaryNonPodObj
# 2019| Type = [VoidType] void
# 2019| ValueCategory = prvalue
# 2019| getArgument(0): [VariableAccess] x
# 2019| Type = [Struct] TernaryNonPodObj
# 2019| ValueCategory = lvalue
# 2019| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
# 2019| Type = [LValueReferenceType] const TernaryNonPodObj &
# 2019| ValueCategory = prvalue
# 2019| getExpr(): [CStyleCast] (const TernaryNonPodObj)...
# 2019| Conversion = [GlvalueConversion] glvalue conversion
# 2019| Type = [SpecifiedType] const TernaryNonPodObj
# 2019| ValueCategory = lvalue
# 2019| getElse(): [ConstructorCall] call to TernaryNonPodObj
# 2019| Type = [VoidType] void
# 2019| ValueCategory = prvalue
# 2019| getThen().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2019| Type = [Struct] TernaryNonPodObj
# 2019| ValueCategory = prvalue(load)
# 2019| getElse().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2019| Type = [Struct] TernaryNonPodObj
# 2019| ValueCategory = prvalue(load)
# 2019| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
# 2019| Type = [LValueReferenceType] const TernaryNonPodObj &
# 2019| ValueCategory = prvalue
# 2019| getExpr(): [CStyleCast] (const TernaryNonPodObj)...
# 2019| Conversion = [GlvalueConversion] glvalue conversion
# 2019| Type = [SpecifiedType] const TernaryNonPodObj
# 2019| ValueCategory = lvalue
# 2019| getExpr(): [TemporaryObjectExpr] temporary object
# 2019| Type = [Struct] TernaryNonPodObj
# 2019| ValueCategory = lvalue
# 2019| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2019| Type = [Struct] TernaryNonPodObj
# 2019| ValueCategory = lvalue
# 2020| getStmt(2): [ExprStmt] ExprStmt
# 2020| getExpr(): [FunctionCall] call to operator=
# 2020| Type = [LValueReferenceType] TernaryNonPodObj &
# 2020| ValueCategory = prvalue
# 2020| getQualifier(): [VariableAccess] z
# 2020| Type = [Struct] TernaryNonPodObj
# 2020| ValueCategory = lvalue
# 2020| getArgument(0): [ConditionalExpr] ... ? ... : ...
# 2020| Type = [Struct] TernaryNonPodObj
# 2020| ValueCategory = prvalue
# 2020| getCondition(): [VariableAccess] a
# 2020| Type = [BoolType] bool
# 2020| ValueCategory = prvalue(load)
# 2020| getThen(): [ConstructorCall] call to TernaryNonPodObj
# 2020| Type = [VoidType] void
# 2020| ValueCategory = prvalue
# 2020| getElse(): [ConstructorCall] call to TernaryNonPodObj
# 2020| Type = [VoidType] void
# 2020| ValueCategory = prvalue
# 2020| getThen().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2020| Type = [Struct] TernaryNonPodObj
# 2020| ValueCategory = prvalue(load)
# 2020| getElse().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 2020| Type = [Struct] TernaryNonPodObj
# 2020| ValueCategory = prvalue(load)
# 2020| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
# 2020| Type = [LValueReferenceType] const TernaryNonPodObj &
# 2020| ValueCategory = prvalue
# 2020| getExpr(): [CStyleCast] (const TernaryNonPodObj)...
# 2020| Conversion = [GlvalueConversion] glvalue conversion
# 2020| Type = [SpecifiedType] const TernaryNonPodObj
# 2020| ValueCategory = lvalue
# 2020| getExpr(): [TemporaryObjectExpr] temporary object
# 2020| Type = [Struct] TernaryNonPodObj
# 2020| ValueCategory = lvalue
# 2020| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2020| Type = [Struct] TernaryNonPodObj
# 2020| ValueCategory = lvalue
# 2021| getStmt(3): [ExprStmt] ExprStmt
# 2021| getExpr(): [FunctionCall] call to operator=
# 2021| Type = [LValueReferenceType] TernaryNonPodObj &
# 2021| ValueCategory = prvalue
# 2021| getQualifier(): [FunctionCall] call to operator=
# 2021| Type = [LValueReferenceType] TernaryNonPodObj &
# 2021| ValueCategory = prvalue
# 2021| getQualifier(): [VariableAccess] z
# 2021| Type = [Struct] TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getArgument(0): [ConditionalExpr] ... ? ... : ...
# 2021| Type = [Struct] TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getCondition(): [VariableAccess] a
# 2021| Type = [BoolType] bool
# 2021| ValueCategory = prvalue(load)
# 2021| getThen(): [VariableAccess] x
# 2021| Type = [Struct] TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getElse(): [VariableAccess] y
# 2021| Type = [Struct] TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
# 2021| Type = [LValueReferenceType] const TernaryNonPodObj &
# 2021| ValueCategory = prvalue
# 2021| getExpr(): [CStyleCast] (const TernaryNonPodObj)...
# 2021| Conversion = [GlvalueConversion] glvalue conversion
# 2021| Type = [SpecifiedType] const TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getArgument(0): [ConstructorCall] call to TernaryNonPodObj
# 2021| Type = [VoidType] void
# 2021| ValueCategory = prvalue
# 2021| getQualifier().getFullyConverted(): [ParenthesisExpr] (...)
# 2021| Type = [Struct] TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
# 2021| Type = [Struct] TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
# 2021| Type = [LValueReferenceType] const TernaryNonPodObj &
# 2021| ValueCategory = prvalue
# 2021| getExpr(): [CStyleCast] (const TernaryNonPodObj)...
# 2021| Conversion = [GlvalueConversion] glvalue conversion
# 2021| Type = [SpecifiedType] const TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getExpr(): [TemporaryObjectExpr] temporary object
# 2021| Type = [Struct] TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2021| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2021| Type = [Struct] TernaryNonPodObj
# 2021| ValueCategory = lvalue
# 2022| getStmt(4): [ReturnStmt] return ...
# 2024| [TopLevelFunction] void CommaTestHelper(unsigned int)
# 2024| <params>:
# 2024| getParameter(0): [Parameter] (unnamed parameter 0)
# 2024| Type = [IntType] unsigned int
# 2026| [TopLevelFunction] unsigned int CommaTest(unsigned int)
# 2026| <params>:
# 2026| getParameter(0): [Parameter] x
# 2026| Type = [IntType] unsigned int
# 2026| getEntryPoint(): [BlockStmt] { ... }
# 2027| getStmt(0): [DeclStmt] declaration
# 2027| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
# 2027| Type = [IntType] unsigned int
# 2028| getStmt(1): [ExprStmt] ExprStmt
# 2028| getExpr(): [AssignExpr] ... = ...
# 2028| Type = [IntType] unsigned int
# 2028| ValueCategory = lvalue
# 2028| getLValue(): [VariableAccess] y
# 2028| Type = [IntType] unsigned int
# 2028| ValueCategory = lvalue
# 2028| getRValue(): [ConditionalExpr] ... ? ... : ...
# 2028| Type = [IntType] unsigned int
# 2028| ValueCategory = prvalue
# 2028| getCondition(): [LTExpr] ... < ...
# 2028| Type = [BoolType] bool
# 2028| ValueCategory = prvalue
# 2028| getLesserOperand(): [VariableAccess] x
# 2028| Type = [IntType] unsigned int
# 2028| ValueCategory = prvalue(load)
# 2028| getGreaterOperand(): [Literal] 100
# 2028| Type = [IntType] int
# 2028| Value = [Literal] 100
# 2028| ValueCategory = prvalue
# 2028| getGreaterOperand().getFullyConverted(): [CStyleCast] (unsigned int)...
# 2028| Conversion = [IntegralConversion] integral conversion
# 2028| Type = [IntType] unsigned int
# 2028| Value = [CStyleCast] 100
# 2028| ValueCategory = prvalue
# 2029| getThen(): [CommaExpr] ... , ...
# 2029| Type = [IntType] unsigned int
# 2029| ValueCategory = prvalue
# 2029| getLeftOperand(): [FunctionCall] call to CommaTestHelper
# 2029| Type = [VoidType] void
# 2029| ValueCategory = prvalue
# 2029| getArgument(0): [VariableAccess] x
# 2029| Type = [IntType] unsigned int
# 2029| ValueCategory = prvalue(load)
# 2029| getRightOperand(): [VariableAccess] x
# 2029| Type = [IntType] unsigned int
# 2029| ValueCategory = prvalue(load)
# 2030| getElse(): [CommaExpr] ... , ...
# 2030| Type = [IntType] int
# 2030| ValueCategory = prvalue
# 2030| getLeftOperand(): [FunctionCall] call to CommaTestHelper
# 2030| Type = [VoidType] void
# 2030| ValueCategory = prvalue
# 2030| getArgument(0): [VariableAccess] x
# 2030| Type = [IntType] unsigned int
# 2030| ValueCategory = prvalue(load)
# 2030| getRightOperand(): [Literal] 10
# 2030| Type = [IntType] int
# 2030| Value = [Literal] 10
# 2030| ValueCategory = prvalue
# 2029| getThen().getFullyConverted(): [ParenthesisExpr] (...)
# 2029| Type = [IntType] unsigned int
# 2029| ValueCategory = prvalue
# 2030| getElse().getFullyConverted(): [CStyleCast] (unsigned int)...
# 2030| Conversion = [IntegralConversion] integral conversion
# 2030| Type = [IntType] unsigned int
# 2030| ValueCategory = prvalue
# 2030| getExpr(): [ParenthesisExpr] (...)
# 2030| Type = [IntType] int
# 2030| ValueCategory = prvalue
# 2031| getStmt(2): [ReturnStmt] return ...
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| <params>:
@@ -15170,6 +15818,40 @@ struct_init.cpp:
# 4| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] Info &&
# 9| [GlobalVariable] Info infos_in_file[]
# 9| getInitializer(): [Initializer] initializer for infos_in_file
# 9| getExpr(): [ArrayAggregateLiteral] {...}
# 9| Type = [ArrayType] Info[2]
# 9| ValueCategory = prvalue
# 10| getAnElementExpr(0): [ClassAggregateLiteral] {...}
# 10| Type = [Struct] Info
# 10| ValueCategory = prvalue
# 10| getAFieldExpr(name): 1
# 10| Type = [ArrayType] const char[2]
# 10| Value = [StringLiteral] "1"
# 10| ValueCategory = lvalue
# 10| getAFieldExpr(handler): [FunctionAccess] handler1
# 10| Type = [FunctionPointerType] ..(*)(..)
# 10| ValueCategory = prvalue(load)
# 10| getAFieldExpr(name).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 10| Type = [PointerType] const char *
# 10| ValueCategory = prvalue
# 11| getAnElementExpr(1): [ClassAggregateLiteral] {...}
# 11| Type = [Struct] Info
# 11| ValueCategory = prvalue
# 11| getAFieldExpr(name): 3
# 11| Type = [ArrayType] const char[2]
# 11| Value = [StringLiteral] "3"
# 11| ValueCategory = lvalue
# 11| getAFieldExpr(handler): [AddressOfExpr] & ...
# 11| Type = [FunctionPointerType] ..(*)(..)
# 11| ValueCategory = prvalue
# 11| getOperand(): [FunctionAccess] handler2
# 11| Type = [RoutineType] ..()(..)
# 11| ValueCategory = lvalue
# 11| getAFieldExpr(name).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
# 11| Type = [PointerType] const char *
# 11| ValueCategory = prvalue
# 16| [TopLevelFunction] void let_info_escape(Info*)
# 16| <params>:
# 16| getParameter(0): [Parameter] info

View File

@@ -7,5 +7,5 @@ private import semmle.code.cpp.PrintAST
private import PrintConfig
private class PrintConfig extends PrintAstConfiguration {
override predicate shouldPrintFunction(Function func) { shouldDumpFunction(func) }
override predicate shouldPrintDeclaration(Declaration decl) { shouldDumpDeclaration(decl) }
}

View File

@@ -8,11 +8,11 @@ predicate locationIsInStandardHeaders(Location loc) {
}
/**
* Holds if the AST or IR for the specified function should be printed in the test output.
* Holds if the AST or IR for the specified declaration should be printed in the test output.
*
* This predicate excludes functions defined in standard headers.
* This predicate excludes declarations defined in standard headers.
*/
predicate shouldDumpFunction(Declaration decl) {
predicate shouldDumpDeclaration(Declaration decl) {
not locationIsInStandardHeaders(decl.getLocation()) and
(
decl instanceof Function

View File

@@ -0,0 +1,11 @@
typedef struct {
int x, y;
} MyCoords;
int getX(MyCoords *coords);
void MyCoordsTest(int pos) {
MyCoords coords = {0};
coords.x = coords.y = pos + 1;
coords.x = getX(&coords);
}

View File

@@ -1993,4 +1993,41 @@ void SetStaticFuncPtr() {
pfn = c.StaticMemberFunction;
}
void TernaryTestInt(bool a, int x, int y, int z) {
z = a ? x : y;
z = a ? x : 5;
z = a ? 3 : 5;
(a ? x : y) = 7;
}
struct TernaryPodObj {
};
void TernaryTestPodObj(bool a, TernaryPodObj x, TernaryPodObj y, TernaryPodObj z) {
z = a ? x : y;
z = a ? x : TernaryPodObj();
z = a ? TernaryPodObj() : TernaryPodObj();
(z = a ? x : y) = TernaryPodObj();
}
struct TernaryNonPodObj {
virtual ~TernaryNonPodObj() {}
};
void TernaryTestNonPodObj(bool a, TernaryNonPodObj x, TernaryNonPodObj y, TernaryNonPodObj z) {
z = a ? x : y;
z = a ? x : TernaryNonPodObj();
z = a ? TernaryNonPodObj() : TernaryNonPodObj();
(z = a ? x : y) = TernaryNonPodObj();
}
void CommaTestHelper(unsigned int);
unsigned int CommaTest(unsigned int x) {
unsigned int y;
y = x < 100 ?
(CommaTestHelper(x), x) :
(CommaTestHelper(x), 10);
}
// semmle-extractor-options: -std=c++17 --clang

View File

@@ -680,6 +680,10 @@
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_2 |
| file://:0:0:0:0 | Address | &:r0_3 |
| file://:0:0:0:0 | Address | &:r0_3 |
@@ -704,6 +708,10 @@
| file://:0:0:0:0 | Address | &:r0_3 |
| file://:0:0:0:0 | Address | &:r0_3 |
| file://:0:0:0:0 | Address | &:r0_3 |
| file://:0:0:0:0 | Address | &:r0_3 |
| file://:0:0:0:0 | Address | &:r0_3 |
| file://:0:0:0:0 | Address | &:r0_3 |
| file://:0:0:0:0 | Address | &:r0_3 |
| file://:0:0:0:0 | Address | &:r0_4 |
| file://:0:0:0:0 | Address | &:r0_4 |
| file://:0:0:0:0 | Address | &:r0_5 |
@@ -715,6 +723,8 @@
| file://:0:0:0:0 | Address | &:r0_5 |
| file://:0:0:0:0 | Address | &:r0_5 |
| file://:0:0:0:0 | Address | &:r0_5 |
| file://:0:0:0:0 | Address | &:r0_5 |
| file://:0:0:0:0 | Address | &:r0_6 |
| file://:0:0:0:0 | Address | &:r0_6 |
| file://:0:0:0:0 | Address | &:r0_7 |
| file://:0:0:0:0 | Address | &:r0_7 |
@@ -799,6 +809,8 @@
| file://:0:0:0:0 | Load | m0_2 |
| file://:0:0:0:0 | Load | m0_2 |
| file://:0:0:0:0 | Load | m0_2 |
| file://:0:0:0:0 | Load | m0_2 |
| file://:0:0:0:0 | Load | m0_2 |
| file://:0:0:0:0 | Load | m0_5 |
| file://:0:0:0:0 | Load | m0_8 |
| file://:0:0:0:0 | Load | m0_11 |
@@ -814,6 +826,7 @@
| file://:0:0:0:0 | Load | m1834_6 |
| file://:0:0:0:0 | Load | m1834_6 |
| file://:0:0:0:0 | Load | m1839_6 |
| file://:0:0:0:0 | Load | m2013_6 |
| file://:0:0:0:0 | Load | ~m0_4 |
| file://:0:0:0:0 | Load | ~m1444_6 |
| file://:0:0:0:0 | Load | ~m1712_10 |
@@ -832,6 +845,8 @@
| file://:0:0:0:0 | SideEffect | m0_4 |
| file://:0:0:0:0 | SideEffect | m0_4 |
| file://:0:0:0:0 | SideEffect | m0_4 |
| file://:0:0:0:0 | SideEffect | m0_4 |
| file://:0:0:0:0 | SideEffect | m0_4 |
| file://:0:0:0:0 | SideEffect | m0_14 |
| file://:0:0:0:0 | SideEffect | m1078_23 |
| file://:0:0:0:0 | SideEffect | m1078_23 |
@@ -869,6 +884,7 @@
| file://:0:0:0:0 | StoreValue | r0_7 |
| file://:0:0:0:0 | StoreValue | r0_9 |
| file://:0:0:0:0 | StoreValue | r0_9 |
| file://:0:0:0:0 | StoreValue | r0_9 |
| file://:0:0:0:0 | StoreValue | r0_12 |
| file://:0:0:0:0 | StoreValue | r0_12 |
| file://:0:0:0:0 | StoreValue | r0_13 |
@@ -895,6 +911,8 @@
| file://:0:0:0:0 | Unary | r0_7 |
| file://:0:0:0:0 | Unary | r0_7 |
| file://:0:0:0:0 | Unary | r0_7 |
| file://:0:0:0:0 | Unary | r0_7 |
| file://:0:0:0:0 | Unary | r0_8 |
| file://:0:0:0:0 | Unary | r0_8 |
| file://:0:0:0:0 | Unary | r0_9 |
| file://:0:0:0:0 | Unary | r0_9 |
@@ -914,6 +932,52 @@
| file://:0:0:0:0 | Unary | r0_20 |
| file://:0:0:0:0 | Unary | r0_21 |
| file://:0:0:0:0 | Unary | r0_21 |
| ir.c:7:6:7:17 | ChiPartial | partial:m7_3 |
| ir.c:7:6:7:17 | ChiTotal | total:m7_2 |
| ir.c:7:6:7:17 | SideEffect | ~m10_6 |
| ir.c:7:23:7:25 | Address | &:r7_5 |
| ir.c:8:12:8:17 | Address | &:r8_1 |
| ir.c:8:12:8:17 | Unary | r8_1 |
| ir.c:8:12:8:17 | Unary | r8_1 |
| ir.c:8:20:8:23 | Address | &:r8_3 |
| ir.c:8:20:8:23 | Address | &:r8_7 |
| ir.c:8:20:8:23 | ChiPartial | partial:m8_9 |
| ir.c:8:20:8:23 | ChiTotal | total:m8_6 |
| ir.c:8:20:8:23 | StoreValue | r8_8 |
| ir.c:8:22:8:22 | ChiPartial | partial:m8_5 |
| ir.c:8:22:8:22 | ChiTotal | total:m8_2 |
| ir.c:8:22:8:22 | StoreValue | r8_4 |
| ir.c:9:3:9:8 | Unary | r9_10 |
| ir.c:9:3:9:31 | ChiPartial | partial:m9_12 |
| ir.c:9:3:9:31 | ChiTotal | total:m9_8 |
| ir.c:9:10:9:10 | Address | &:r9_11 |
| ir.c:9:14:9:19 | Unary | r9_5 |
| ir.c:9:14:9:31 | ChiPartial | partial:m9_7 |
| ir.c:9:14:9:31 | ChiTotal | total:m8_10 |
| ir.c:9:14:9:31 | StoreValue | r9_9 |
| ir.c:9:21:9:21 | Address | &:r9_6 |
| ir.c:9:25:9:27 | Address | &:r9_1 |
| ir.c:9:25:9:27 | Left | r9_2 |
| ir.c:9:25:9:27 | Load | m7_6 |
| ir.c:9:25:9:31 | StoreValue | r9_4 |
| ir.c:9:25:9:31 | Unary | r9_4 |
| ir.c:9:31:9:31 | Right | r9_3 |
| ir.c:10:3:10:8 | Unary | r10_10 |
| ir.c:10:3:10:26 | ChiPartial | partial:m10_12 |
| ir.c:10:3:10:26 | ChiTotal | total:m10_9 |
| ir.c:10:10:10:10 | Address | &:r10_11 |
| ir.c:10:14:10:17 | CallTarget | func:r10_1 |
| ir.c:10:14:10:17 | ChiPartial | partial:m10_5 |
| ir.c:10:14:10:17 | ChiTotal | total:m7_4 |
| ir.c:10:14:10:17 | SideEffect | ~m7_4 |
| ir.c:10:14:10:17 | StoreValue | r10_4 |
| ir.c:10:19:10:25 | Address | &:r10_3 |
| ir.c:10:19:10:25 | Address | &:r10_3 |
| ir.c:10:19:10:25 | Arg(0) | 0:r10_3 |
| ir.c:10:19:10:25 | ChiPartial | partial:m10_8 |
| ir.c:10:19:10:25 | ChiTotal | total:m9_13 |
| ir.c:10:19:10:25 | SideEffect | ~m9_13 |
| ir.c:10:20:10:25 | Unary | r10_2 |
| ir.cpp:1:6:1:14 | ChiPartial | partial:m1_3 |
| ir.cpp:1:6:1:14 | ChiTotal | total:m1_2 |
| ir.cpp:1:6:1:14 | SideEffect | m1_3 |
@@ -9058,6 +9122,446 @@
| ir.cpp:1992:23:1992:45 | StoreValue | r1992_2 |
| ir.cpp:1993:5:1993:7 | Address | &:r1993_3 |
| ir.cpp:1993:13:1993:32 | StoreValue | r1993_2 |
| ir.cpp:1996:6:1996:19 | ChiPartial | partial:m1996_3 |
| ir.cpp:1996:6:1996:19 | ChiTotal | total:m1996_2 |
| ir.cpp:1996:6:1996:19 | SideEffect | ~m2000_9 |
| ir.cpp:1996:26:1996:26 | Address | &:r1996_5 |
| ir.cpp:1996:33:1996:33 | Address | &:r1996_7 |
| ir.cpp:1996:40:1996:40 | Address | &:r1996_9 |
| ir.cpp:1996:47:1996:47 | Address | &:r1996_11 |
| ir.cpp:1997:5:1997:5 | Address | &:r1997_7 |
| ir.cpp:1997:9:1997:9 | Address | &:r1997_1 |
| ir.cpp:1997:9:1997:9 | Condition | r1997_2 |
| ir.cpp:1997:9:1997:9 | Load | m1996_6 |
| ir.cpp:1997:9:1997:17 | Address | &:r1997_5 |
| ir.cpp:1997:9:1997:17 | Address | &:r1997_11 |
| ir.cpp:1997:9:1997:17 | Address | &:r1997_15 |
| ir.cpp:1997:9:1997:17 | Load | m1997_4 |
| ir.cpp:1997:9:1997:17 | Phi | from 2:m1997_12 |
| ir.cpp:1997:9:1997:17 | Phi | from 3:m1997_16 |
| ir.cpp:1997:9:1997:17 | StoreValue | r1997_6 |
| ir.cpp:1997:13:1997:13 | Address | &:r1997_9 |
| ir.cpp:1997:13:1997:13 | Load | m1996_8 |
| ir.cpp:1997:13:1997:13 | StoreValue | r1997_10 |
| ir.cpp:1997:17:1997:17 | Address | &:r1997_13 |
| ir.cpp:1997:17:1997:17 | Load | m1996_10 |
| ir.cpp:1997:17:1997:17 | StoreValue | r1997_14 |
| ir.cpp:1998:5:1998:5 | Address | &:r1998_7 |
| ir.cpp:1998:9:1998:9 | Address | &:r1998_1 |
| ir.cpp:1998:9:1998:9 | Condition | r1998_2 |
| ir.cpp:1998:9:1998:9 | Load | m1996_6 |
| ir.cpp:1998:9:1998:17 | Address | &:r1998_5 |
| ir.cpp:1998:9:1998:17 | Address | &:r1998_11 |
| ir.cpp:1998:9:1998:17 | Address | &:r1998_14 |
| ir.cpp:1998:9:1998:17 | Load | m1998_4 |
| ir.cpp:1998:9:1998:17 | Phi | from 5:m1998_12 |
| ir.cpp:1998:9:1998:17 | Phi | from 6:m1998_15 |
| ir.cpp:1998:9:1998:17 | StoreValue | r1998_6 |
| ir.cpp:1998:13:1998:13 | Address | &:r1998_9 |
| ir.cpp:1998:13:1998:13 | Load | m1996_8 |
| ir.cpp:1998:13:1998:13 | StoreValue | r1998_10 |
| ir.cpp:1998:17:1998:17 | StoreValue | r1998_13 |
| ir.cpp:1999:5:1999:5 | Address | &:r1999_7 |
| ir.cpp:1999:9:1999:9 | Address | &:r1999_1 |
| ir.cpp:1999:9:1999:9 | Condition | r1999_2 |
| ir.cpp:1999:9:1999:9 | Load | m1996_6 |
| ir.cpp:1999:9:1999:17 | Address | &:r1999_5 |
| ir.cpp:1999:9:1999:17 | Address | &:r1999_10 |
| ir.cpp:1999:9:1999:17 | Address | &:r1999_13 |
| ir.cpp:1999:9:1999:17 | Load | m1999_4 |
| ir.cpp:1999:9:1999:17 | Phi | from 8:m1999_11 |
| ir.cpp:1999:9:1999:17 | Phi | from 9:m1999_14 |
| ir.cpp:1999:9:1999:17 | StoreValue | r1999_6 |
| ir.cpp:1999:13:1999:13 | StoreValue | r1999_9 |
| ir.cpp:1999:17:1999:17 | StoreValue | r1999_12 |
| ir.cpp:2000:5:2000:19 | ChiPartial | partial:m2000_8 |
| ir.cpp:2000:5:2000:19 | ChiTotal | total:m1996_4 |
| ir.cpp:2000:6:2000:6 | Address | &:r2000_2 |
| ir.cpp:2000:6:2000:6 | Condition | r2000_3 |
| ir.cpp:2000:6:2000:6 | Load | m1996_6 |
| ir.cpp:2000:6:2000:14 | Address | &:r2000_6 |
| ir.cpp:2000:6:2000:14 | Address | &:r2000_7 |
| ir.cpp:2000:6:2000:14 | Address | &:r2000_11 |
| ir.cpp:2000:6:2000:14 | Address | &:r2000_14 |
| ir.cpp:2000:6:2000:14 | Load | m2000_5 |
| ir.cpp:2000:6:2000:14 | Phi | from 11:m2000_12 |
| ir.cpp:2000:6:2000:14 | Phi | from 12:m2000_15 |
| ir.cpp:2000:10:2000:10 | StoreValue | r2000_10 |
| ir.cpp:2000:14:2000:14 | StoreValue | r2000_13 |
| ir.cpp:2000:19:2000:19 | StoreValue | r2000_1 |
| ir.cpp:2006:6:2006:22 | ChiPartial | partial:m2006_3 |
| ir.cpp:2006:6:2006:22 | ChiTotal | total:m2006_2 |
| ir.cpp:2006:6:2006:22 | SideEffect | m2006_3 |
| ir.cpp:2006:29:2006:29 | Address | &:r2006_5 |
| ir.cpp:2006:46:2006:46 | Address | &:r2006_7 |
| ir.cpp:2006:63:2006:63 | Address | &:r2006_9 |
| ir.cpp:2006:80:2006:80 | Address | &:r2006_11 |
| ir.cpp:2007:5:2007:5 | Address | &:r2007_7 |
| ir.cpp:2007:9:2007:9 | Address | &:r2007_1 |
| ir.cpp:2007:9:2007:9 | Condition | r2007_2 |
| ir.cpp:2007:9:2007:9 | Load | m2006_6 |
| ir.cpp:2007:9:2007:17 | Address | &:r2007_5 |
| ir.cpp:2007:9:2007:17 | Address | &:r2007_11 |
| ir.cpp:2007:9:2007:17 | Address | &:r2007_15 |
| ir.cpp:2007:9:2007:17 | Load | m2007_4 |
| ir.cpp:2007:9:2007:17 | Phi | from 2:m2007_12 |
| ir.cpp:2007:9:2007:17 | Phi | from 3:m2007_16 |
| ir.cpp:2007:9:2007:17 | StoreValue | r2007_6 |
| ir.cpp:2007:13:2007:13 | Address | &:r2007_9 |
| ir.cpp:2007:13:2007:13 | Load | m2006_8 |
| ir.cpp:2007:13:2007:13 | StoreValue | r2007_10 |
| ir.cpp:2007:17:2007:17 | Address | &:r2007_13 |
| ir.cpp:2007:17:2007:17 | Load | m2006_10 |
| ir.cpp:2007:17:2007:17 | StoreValue | r2007_14 |
| ir.cpp:2008:5:2008:5 | Address | &:r2008_10 |
| ir.cpp:2008:9:2008:9 | Address | &:r2008_2 |
| ir.cpp:2008:9:2008:9 | Address | &:r2008_6 |
| ir.cpp:2008:9:2008:9 | Address | &:r2008_17 |
| ir.cpp:2008:9:2008:9 | Address | &:r2008_23 |
| ir.cpp:2008:9:2008:9 | Condition | r2008_3 |
| ir.cpp:2008:9:2008:9 | Load | m2006_6 |
| ir.cpp:2008:9:2008:9 | Load | m2008_5 |
| ir.cpp:2008:9:2008:9 | Phi | from 5:m2008_18 |
| ir.cpp:2008:9:2008:9 | Phi | from 6:m2008_24 |
| ir.cpp:2008:9:2008:9 | StoreValue | r2008_7 |
| ir.cpp:2008:9:2008:31 | Address | &:r2008_1 |
| ir.cpp:2008:9:2008:31 | Address | &:r2008_1 |
| ir.cpp:2008:9:2008:31 | Load | m2008_8 |
| ir.cpp:2008:9:2008:31 | StoreValue | r2008_9 |
| ir.cpp:2008:13:2008:13 | Address | &:r2008_12 |
| ir.cpp:2008:13:2008:13 | Address | &:r2008_12 |
| ir.cpp:2008:13:2008:13 | Address | &:r2008_13 |
| ir.cpp:2008:13:2008:13 | Load | m2006_8 |
| ir.cpp:2008:13:2008:13 | Load | m2008_15 |
| ir.cpp:2008:13:2008:13 | StoreValue | r2008_14 |
| ir.cpp:2008:13:2008:13 | StoreValue | r2008_16 |
| ir.cpp:2008:17:2008:31 | Address | &:r2008_19 |
| ir.cpp:2008:17:2008:31 | Address | &:r2008_19 |
| ir.cpp:2008:17:2008:31 | Load | m2008_21 |
| ir.cpp:2008:17:2008:31 | StoreValue | r2008_20 |
| ir.cpp:2008:17:2008:31 | StoreValue | r2008_22 |
| ir.cpp:2009:5:2009:5 | Address | &:r2009_10 |
| ir.cpp:2009:9:2009:9 | Address | &:r2009_2 |
| ir.cpp:2009:9:2009:9 | Address | &:r2009_6 |
| ir.cpp:2009:9:2009:9 | Address | &:r2009_16 |
| ir.cpp:2009:9:2009:9 | Address | &:r2009_22 |
| ir.cpp:2009:9:2009:9 | Condition | r2009_3 |
| ir.cpp:2009:9:2009:9 | Load | m2006_6 |
| ir.cpp:2009:9:2009:9 | Load | m2009_5 |
| ir.cpp:2009:9:2009:9 | Phi | from 8:m2009_17 |
| ir.cpp:2009:9:2009:9 | Phi | from 9:m2009_23 |
| ir.cpp:2009:9:2009:9 | StoreValue | r2009_7 |
| ir.cpp:2009:9:2009:45 | Address | &:r2009_1 |
| ir.cpp:2009:9:2009:45 | Address | &:r2009_1 |
| ir.cpp:2009:9:2009:45 | Load | m2009_8 |
| ir.cpp:2009:9:2009:45 | StoreValue | r2009_9 |
| ir.cpp:2009:13:2009:27 | Address | &:r2009_12 |
| ir.cpp:2009:13:2009:27 | Address | &:r2009_12 |
| ir.cpp:2009:13:2009:27 | Load | m2009_14 |
| ir.cpp:2009:13:2009:27 | StoreValue | r2009_13 |
| ir.cpp:2009:13:2009:27 | StoreValue | r2009_15 |
| ir.cpp:2009:31:2009:45 | Address | &:r2009_18 |
| ir.cpp:2009:31:2009:45 | Address | &:r2009_18 |
| ir.cpp:2009:31:2009:45 | Load | m2009_20 |
| ir.cpp:2009:31:2009:45 | StoreValue | r2009_19 |
| ir.cpp:2009:31:2009:45 | StoreValue | r2009_21 |
| ir.cpp:2010:6:2010:6 | Address | &:r2010_11 |
| ir.cpp:2010:6:2010:6 | Unary | r2010_11 |
| ir.cpp:2010:6:2010:18 | Address | &:r2010_13 |
| ir.cpp:2010:10:2010:10 | Address | &:r2010_5 |
| ir.cpp:2010:10:2010:10 | Condition | r2010_6 |
| ir.cpp:2010:10:2010:10 | Load | m2006_6 |
| ir.cpp:2010:10:2010:18 | Address | &:r2010_9 |
| ir.cpp:2010:10:2010:18 | Address | &:r2010_17 |
| ir.cpp:2010:10:2010:18 | Address | &:r2010_21 |
| ir.cpp:2010:10:2010:18 | Load | m2010_8 |
| ir.cpp:2010:10:2010:18 | Phi | from 11:m2010_18 |
| ir.cpp:2010:10:2010:18 | Phi | from 12:m2010_22 |
| ir.cpp:2010:10:2010:18 | StoreValue | r2010_10 |
| ir.cpp:2010:14:2010:14 | Address | &:r2010_15 |
| ir.cpp:2010:14:2010:14 | Load | m2006_8 |
| ir.cpp:2010:14:2010:14 | StoreValue | r2010_16 |
| ir.cpp:2010:18:2010:18 | Address | &:r2010_19 |
| ir.cpp:2010:18:2010:18 | Load | m2006_10 |
| ir.cpp:2010:18:2010:18 | StoreValue | r2010_20 |
| ir.cpp:2010:23:2010:37 | Address | &:r2010_1 |
| ir.cpp:2010:23:2010:37 | Address | &:r2010_1 |
| ir.cpp:2010:23:2010:37 | Load | m2010_3 |
| ir.cpp:2010:23:2010:37 | StoreValue | r2010_2 |
| ir.cpp:2010:23:2010:37 | StoreValue | r2010_4 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_5 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_5 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_5 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_5 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_5 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_5 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_7 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_7 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_7 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_7 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_7 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_7 |
| ir.cpp:2013:8:2013:8 | Address | &:r2013_10 |
| ir.cpp:2013:8:2013:8 | ChiPartial | partial:m2013_3 |
| ir.cpp:2013:8:2013:8 | ChiPartial | partial:m2013_3 |
| ir.cpp:2013:8:2013:8 | ChiPartial | partial:m2013_3 |
| ir.cpp:2013:8:2013:8 | ChiTotal | total:m2013_2 |
| ir.cpp:2013:8:2013:8 | ChiTotal | total:m2013_2 |
| ir.cpp:2013:8:2013:8 | ChiTotal | total:m2013_2 |
| ir.cpp:2013:8:2013:8 | Load | m0_10 |
| ir.cpp:2013:8:2013:8 | Load | m2013_6 |
| ir.cpp:2013:8:2013:8 | Load | m2013_6 |
| ir.cpp:2013:8:2013:8 | Load | m2013_6 |
| ir.cpp:2013:8:2013:8 | SideEffect | m2013_3 |
| ir.cpp:2013:8:2013:8 | SideEffect | m2013_3 |
| ir.cpp:2013:8:2013:8 | SideEffect | m2013_3 |
| ir.cpp:2013:8:2013:8 | SideEffect | m2013_8 |
| ir.cpp:2013:8:2013:8 | SideEffect | m2013_8 |
| ir.cpp:2013:8:2013:8 | SideEffect | m2013_8 |
| ir.cpp:2014:13:2014:29 | Address | &:r2014_5 |
| ir.cpp:2014:13:2014:29 | Address | &:r2014_5 |
| ir.cpp:2014:13:2014:29 | Address | &:r2014_7 |
| ir.cpp:2014:13:2014:29 | Address | &:r2014_7 |
| ir.cpp:2014:13:2014:29 | ChiPartial | partial:m2014_3 |
| ir.cpp:2014:13:2014:29 | ChiTotal | total:m2014_2 |
| ir.cpp:2014:13:2014:29 | Load | m2014_6 |
| ir.cpp:2014:13:2014:29 | SideEffect | m2014_3 |
| ir.cpp:2014:13:2014:29 | SideEffect | m2014_8 |
| ir.cpp:2017:6:2017:25 | ChiPartial | partial:m2017_3 |
| ir.cpp:2017:6:2017:25 | ChiTotal | total:m2017_2 |
| ir.cpp:2017:6:2017:25 | SideEffect | ~m2021_32 |
| ir.cpp:2017:32:2017:32 | Address | &:r2017_5 |
| ir.cpp:2017:52:2017:52 | Address | &:r2017_7 |
| ir.cpp:2017:72:2017:72 | Address | &:r2017_9 |
| ir.cpp:2017:92:2017:92 | Address | &:r2017_11 |
| ir.cpp:2018:5:2018:5 | Address | &:r2018_1 |
| ir.cpp:2018:5:2018:5 | Address | &:r2018_1 |
| ir.cpp:2018:5:2018:5 | Arg(this) | this:r2018_1 |
| ir.cpp:2018:5:2018:5 | ChiPartial | partial:m2018_16 |
| ir.cpp:2018:5:2018:5 | ChiTotal | total:m2017_12 |
| ir.cpp:2018:5:2018:5 | SideEffect | m2017_12 |
| ir.cpp:2018:7:2018:7 | CallTarget | func:r2018_2 |
| ir.cpp:2018:7:2018:7 | ChiPartial | partial:m2018_12 |
| ir.cpp:2018:7:2018:7 | ChiTotal | total:m2017_4 |
| ir.cpp:2018:7:2018:7 | SideEffect | ~m2017_4 |
| ir.cpp:2018:7:2018:7 | Unary | r2018_11 |
| ir.cpp:2018:9:2018:9 | Address | &:r2018_3 |
| ir.cpp:2018:9:2018:9 | Condition | r2018_4 |
| ir.cpp:2018:9:2018:9 | Load | m2017_6 |
| ir.cpp:2018:9:2018:17 | Address | &:r2018_7 |
| ir.cpp:2018:9:2018:17 | Address | &:r2018_10 |
| ir.cpp:2018:9:2018:17 | Address | &:r2018_20 |
| ir.cpp:2018:9:2018:17 | Address | &:r2018_23 |
| ir.cpp:2018:9:2018:17 | Arg(0) | 0:r2018_10 |
| ir.cpp:2018:9:2018:17 | Load | m2018_6 |
| ir.cpp:2018:9:2018:17 | Phi | from 2:m2018_21 |
| ir.cpp:2018:9:2018:17 | Phi | from 3:m2018_24 |
| ir.cpp:2018:9:2018:17 | SideEffect | ~m2018_13 |
| ir.cpp:2018:9:2018:17 | Unary | r2018_8 |
| ir.cpp:2018:9:2018:17 | Unary | r2018_9 |
| ir.cpp:2018:13:2018:13 | StoreValue | r2018_19 |
| ir.cpp:2018:17:2018:17 | StoreValue | r2018_22 |
| ir.cpp:2019:5:2019:5 | Address | &:r2019_1 |
| ir.cpp:2019:5:2019:5 | Address | &:r2019_1 |
| ir.cpp:2019:5:2019:5 | Arg(this) | this:r2019_1 |
| ir.cpp:2019:5:2019:5 | ChiPartial | partial:m2019_19 |
| ir.cpp:2019:5:2019:5 | ChiTotal | total:m2018_17 |
| ir.cpp:2019:5:2019:5 | SideEffect | m2018_17 |
| ir.cpp:2019:7:2019:7 | CallTarget | func:r2019_2 |
| ir.cpp:2019:7:2019:7 | ChiPartial | partial:m2019_15 |
| ir.cpp:2019:7:2019:7 | ChiTotal | total:m2019_7 |
| ir.cpp:2019:7:2019:7 | SideEffect | ~m2019_7 |
| ir.cpp:2019:7:2019:7 | Unary | r2019_14 |
| ir.cpp:2019:9:2019:9 | Address | &:r2019_4 |
| ir.cpp:2019:9:2019:9 | Address | &:r2019_9 |
| ir.cpp:2019:9:2019:9 | Address | &:r2019_35 |
| ir.cpp:2019:9:2019:9 | Address | &:r2019_46 |
| ir.cpp:2019:9:2019:9 | Condition | r2019_5 |
| ir.cpp:2019:9:2019:9 | Load | m2017_6 |
| ir.cpp:2019:9:2019:9 | Load | m2019_8 |
| ir.cpp:2019:9:2019:9 | Phi | from 5:m2019_36 |
| ir.cpp:2019:9:2019:9 | Phi | from 5:~m2019_30 |
| ir.cpp:2019:9:2019:9 | Phi | from 6:m2019_47 |
| ir.cpp:2019:9:2019:9 | Phi | from 6:~m2019_42 |
| ir.cpp:2019:9:2019:9 | StoreValue | r2019_10 |
| ir.cpp:2019:9:2019:34 | Address | &:r2019_3 |
| ir.cpp:2019:9:2019:34 | Address | &:r2019_13 |
| ir.cpp:2019:9:2019:34 | Arg(0) | 0:r2019_13 |
| ir.cpp:2019:9:2019:34 | SideEffect | ~m2019_11 |
| ir.cpp:2019:9:2019:34 | Unary | r2019_3 |
| ir.cpp:2019:9:2019:34 | Unary | r2019_12 |
| ir.cpp:2019:13:2019:13 | Address | &:r2019_22 |
| ir.cpp:2019:13:2019:13 | Address | &:r2019_22 |
| ir.cpp:2019:13:2019:13 | Address | &:r2019_22 |
| ir.cpp:2019:13:2019:13 | Address | &:r2019_27 |
| ir.cpp:2019:13:2019:13 | Arg(0) | 0:r2019_27 |
| ir.cpp:2019:13:2019:13 | Arg(this) | this:r2019_22 |
| ir.cpp:2019:13:2019:13 | CallTarget | func:r2019_24 |
| ir.cpp:2019:13:2019:13 | ChiPartial | partial:m2019_29 |
| ir.cpp:2019:13:2019:13 | ChiPartial | partial:m2019_32 |
| ir.cpp:2019:13:2019:13 | ChiTotal | total:m2018_13 |
| ir.cpp:2019:13:2019:13 | ChiTotal | total:m2019_23 |
| ir.cpp:2019:13:2019:13 | Load | m2019_33 |
| ir.cpp:2019:13:2019:13 | SideEffect | ~m2017_8 |
| ir.cpp:2019:13:2019:13 | SideEffect | ~m2018_13 |
| ir.cpp:2019:13:2019:13 | StoreValue | r2019_34 |
| ir.cpp:2019:13:2019:13 | Unary | r2019_25 |
| ir.cpp:2019:13:2019:13 | Unary | r2019_26 |
| ir.cpp:2019:17:2019:34 | Address | &:r2019_37 |
| ir.cpp:2019:17:2019:34 | Address | &:r2019_37 |
| ir.cpp:2019:17:2019:34 | Address | &:r2019_37 |
| ir.cpp:2019:17:2019:34 | Arg(this) | this:r2019_37 |
| ir.cpp:2019:17:2019:34 | CallTarget | func:r2019_39 |
| ir.cpp:2019:17:2019:34 | ChiPartial | partial:m2019_41 |
| ir.cpp:2019:17:2019:34 | ChiPartial | partial:m2019_43 |
| ir.cpp:2019:17:2019:34 | ChiTotal | total:m2018_13 |
| ir.cpp:2019:17:2019:34 | ChiTotal | total:m2019_38 |
| ir.cpp:2019:17:2019:34 | Load | m2019_44 |
| ir.cpp:2019:17:2019:34 | SideEffect | ~m2018_13 |
| ir.cpp:2019:17:2019:34 | StoreValue | r2019_45 |
| ir.cpp:2020:5:2020:5 | Address | &:r2020_1 |
| ir.cpp:2020:5:2020:5 | Address | &:r2020_1 |
| ir.cpp:2020:5:2020:5 | Arg(this) | this:r2020_1 |
| ir.cpp:2020:5:2020:5 | ChiPartial | partial:m2020_19 |
| ir.cpp:2020:5:2020:5 | ChiTotal | total:m2019_20 |
| ir.cpp:2020:5:2020:5 | SideEffect | m2019_20 |
| ir.cpp:2020:7:2020:7 | CallTarget | func:r2020_2 |
| ir.cpp:2020:7:2020:7 | ChiPartial | partial:m2020_15 |
| ir.cpp:2020:7:2020:7 | ChiTotal | total:m2020_7 |
| ir.cpp:2020:7:2020:7 | SideEffect | ~m2020_7 |
| ir.cpp:2020:7:2020:7 | Unary | r2020_14 |
| ir.cpp:2020:9:2020:9 | Address | &:r2020_4 |
| ir.cpp:2020:9:2020:9 | Address | &:r2020_9 |
| ir.cpp:2020:9:2020:9 | Address | &:r2020_31 |
| ir.cpp:2020:9:2020:9 | Address | &:r2020_42 |
| ir.cpp:2020:9:2020:9 | Condition | r2020_5 |
| ir.cpp:2020:9:2020:9 | Load | m2017_6 |
| ir.cpp:2020:9:2020:9 | Load | m2020_8 |
| ir.cpp:2020:9:2020:9 | Phi | from 8:m2020_32 |
| ir.cpp:2020:9:2020:9 | Phi | from 8:~m2020_27 |
| ir.cpp:2020:9:2020:9 | Phi | from 9:m2020_43 |
| ir.cpp:2020:9:2020:9 | Phi | from 9:~m2020_38 |
| ir.cpp:2020:9:2020:9 | StoreValue | r2020_10 |
| ir.cpp:2020:9:2020:51 | Address | &:r2020_3 |
| ir.cpp:2020:9:2020:51 | Address | &:r2020_13 |
| ir.cpp:2020:9:2020:51 | Arg(0) | 0:r2020_13 |
| ir.cpp:2020:9:2020:51 | SideEffect | ~m2020_11 |
| ir.cpp:2020:9:2020:51 | Unary | r2020_3 |
| ir.cpp:2020:9:2020:51 | Unary | r2020_12 |
| ir.cpp:2020:13:2020:30 | Address | &:r2020_22 |
| ir.cpp:2020:13:2020:30 | Address | &:r2020_22 |
| ir.cpp:2020:13:2020:30 | Address | &:r2020_22 |
| ir.cpp:2020:13:2020:30 | Arg(this) | this:r2020_22 |
| ir.cpp:2020:13:2020:30 | CallTarget | func:r2020_24 |
| ir.cpp:2020:13:2020:30 | ChiPartial | partial:m2020_26 |
| ir.cpp:2020:13:2020:30 | ChiPartial | partial:m2020_28 |
| ir.cpp:2020:13:2020:30 | ChiTotal | total:m2019_16 |
| ir.cpp:2020:13:2020:30 | ChiTotal | total:m2020_23 |
| ir.cpp:2020:13:2020:30 | Load | m2020_29 |
| ir.cpp:2020:13:2020:30 | SideEffect | ~m2019_16 |
| ir.cpp:2020:13:2020:30 | StoreValue | r2020_30 |
| ir.cpp:2020:34:2020:51 | Address | &:r2020_33 |
| ir.cpp:2020:34:2020:51 | Address | &:r2020_33 |
| ir.cpp:2020:34:2020:51 | Address | &:r2020_33 |
| ir.cpp:2020:34:2020:51 | Arg(this) | this:r2020_33 |
| ir.cpp:2020:34:2020:51 | CallTarget | func:r2020_35 |
| ir.cpp:2020:34:2020:51 | ChiPartial | partial:m2020_37 |
| ir.cpp:2020:34:2020:51 | ChiPartial | partial:m2020_39 |
| ir.cpp:2020:34:2020:51 | ChiTotal | total:m2019_16 |
| ir.cpp:2020:34:2020:51 | ChiTotal | total:m2020_34 |
| ir.cpp:2020:34:2020:51 | Load | m2020_40 |
| ir.cpp:2020:34:2020:51 | SideEffect | ~m2019_16 |
| ir.cpp:2020:34:2020:51 | StoreValue | r2020_41 |
| ir.cpp:2021:5:2021:19 | ChiPartial | partial:m2021_35 |
| ir.cpp:2021:5:2021:19 | ChiTotal | total:m2021_17 |
| ir.cpp:2021:5:2021:19 | SideEffect | m2021_17 |
| ir.cpp:2021:6:2021:6 | Address | &:r2021_1 |
| ir.cpp:2021:6:2021:6 | Address | &:r2021_1 |
| ir.cpp:2021:6:2021:6 | Arg(this) | this:r2021_1 |
| ir.cpp:2021:6:2021:6 | ChiPartial | partial:m2021_16 |
| ir.cpp:2021:6:2021:6 | ChiTotal | total:m2020_20 |
| ir.cpp:2021:6:2021:6 | SideEffect | m2020_20 |
| ir.cpp:2021:8:2021:8 | CallTarget | func:r2021_2 |
| ir.cpp:2021:8:2021:8 | ChiPartial | partial:m2021_12 |
| ir.cpp:2021:8:2021:8 | ChiTotal | total:m2020_16 |
| ir.cpp:2021:8:2021:8 | SideEffect | ~m2020_16 |
| ir.cpp:2021:8:2021:8 | Unary | r2021_11 |
| ir.cpp:2021:8:2021:19 | Address | &:r2021_18 |
| ir.cpp:2021:8:2021:19 | Address | &:r2021_18 |
| ir.cpp:2021:8:2021:19 | Arg(this) | this:r2021_18 |
| ir.cpp:2021:10:2021:10 | Address | &:r2021_3 |
| ir.cpp:2021:10:2021:10 | Condition | r2021_4 |
| ir.cpp:2021:10:2021:10 | Load | m2017_6 |
| ir.cpp:2021:10:2021:18 | Address | &:r2021_7 |
| ir.cpp:2021:10:2021:18 | Address | &:r2021_10 |
| ir.cpp:2021:10:2021:18 | Address | &:r2021_39 |
| ir.cpp:2021:10:2021:18 | Address | &:r2021_42 |
| ir.cpp:2021:10:2021:18 | Arg(0) | 0:r2021_10 |
| ir.cpp:2021:10:2021:18 | Load | m2021_6 |
| ir.cpp:2021:10:2021:18 | Phi | from 11:m2021_40 |
| ir.cpp:2021:10:2021:18 | Phi | from 12:m2021_43 |
| ir.cpp:2021:10:2021:18 | SideEffect | ~m2021_13 |
| ir.cpp:2021:10:2021:18 | Unary | r2021_8 |
| ir.cpp:2021:10:2021:18 | Unary | r2021_9 |
| ir.cpp:2021:14:2021:14 | StoreValue | r2021_38 |
| ir.cpp:2021:18:2021:18 | StoreValue | r2021_41 |
| ir.cpp:2021:21:2021:21 | CallTarget | func:r2021_19 |
| ir.cpp:2021:21:2021:21 | ChiPartial | partial:m2021_31 |
| ir.cpp:2021:21:2021:21 | ChiTotal | total:m2021_25 |
| ir.cpp:2021:21:2021:21 | SideEffect | ~m2021_25 |
| ir.cpp:2021:21:2021:21 | Unary | r2021_30 |
| ir.cpp:2021:23:2021:40 | Address | &:r2021_20 |
| ir.cpp:2021:23:2021:40 | Address | &:r2021_20 |
| ir.cpp:2021:23:2021:40 | Address | &:r2021_29 |
| ir.cpp:2021:23:2021:40 | Arg(0) | 0:r2021_29 |
| ir.cpp:2021:23:2021:40 | Arg(this) | this:r2021_20 |
| ir.cpp:2021:23:2021:40 | CallTarget | func:r2021_22 |
| ir.cpp:2021:23:2021:40 | ChiPartial | partial:m2021_24 |
| ir.cpp:2021:23:2021:40 | ChiPartial | partial:m2021_26 |
| ir.cpp:2021:23:2021:40 | ChiTotal | total:m2021_13 |
| ir.cpp:2021:23:2021:40 | ChiTotal | total:m2021_21 |
| ir.cpp:2021:23:2021:40 | SideEffect | ~m2021_13 |
| ir.cpp:2021:23:2021:40 | SideEffect | ~m2021_27 |
| ir.cpp:2021:23:2021:40 | Unary | r2021_20 |
| ir.cpp:2021:23:2021:40 | Unary | r2021_28 |
| ir.cpp:2026:14:2026:22 | ChiPartial | partial:m2026_3 |
| ir.cpp:2026:14:2026:22 | ChiTotal | total:m2026_2 |
| ir.cpp:2026:37:2026:37 | Address | &:r2026_5 |
| ir.cpp:2027:16:2027:16 | Address | &:r2027_1 |
| ir.cpp:2028:3:2028:3 | Address | &:r2028_9 |
| ir.cpp:2028:7:2028:7 | Address | &:r2028_1 |
| ir.cpp:2028:7:2028:7 | Left | r2028_2 |
| ir.cpp:2028:7:2028:7 | Load | m2026_6 |
| ir.cpp:2028:7:2028:13 | Condition | r2028_4 |
| ir.cpp:2028:7:2030:28 | Address | &:r2028_7 |
| ir.cpp:2028:7:2030:28 | Address | &:r2028_11 |
| ir.cpp:2028:7:2030:28 | Address | &:r2028_13 |
| ir.cpp:2028:7:2030:28 | Load | m2028_6 |
| ir.cpp:2028:7:2030:28 | Phi | from 2:m2028_12 |
| ir.cpp:2028:7:2030:28 | Phi | from 3:m2028_14 |
| ir.cpp:2028:7:2030:28 | StoreValue | r2028_8 |
| ir.cpp:2028:11:2028:13 | Right | r2028_3 |
| ir.cpp:2029:6:2029:20 | CallTarget | func:r2029_1 |
| ir.cpp:2029:6:2029:20 | ChiPartial | partial:m2029_5 |
| ir.cpp:2029:6:2029:20 | ChiTotal | total:m2026_4 |
| ir.cpp:2029:6:2029:20 | SideEffect | ~m2026_4 |
| ir.cpp:2029:6:2029:26 | StoreValue | r2029_9 |
| ir.cpp:2029:22:2029:22 | Address | &:r2029_2 |
| ir.cpp:2029:22:2029:22 | Arg(0) | 0:r2029_3 |
| ir.cpp:2029:22:2029:22 | Load | m2026_6 |
| ir.cpp:2029:26:2029:26 | Address | &:r2029_7 |
| ir.cpp:2029:26:2029:26 | Load | m2026_6 |
| ir.cpp:2029:26:2029:26 | Unary | r2029_8 |
| ir.cpp:2030:5:2030:28 | StoreValue | r2030_9 |
| ir.cpp:2030:6:2030:20 | CallTarget | func:r2030_1 |
| ir.cpp:2030:6:2030:20 | ChiPartial | partial:m2030_5 |
| ir.cpp:2030:6:2030:20 | ChiTotal | total:m2026_4 |
| ir.cpp:2030:6:2030:20 | SideEffect | ~m2026_4 |
| ir.cpp:2030:6:2030:27 | Unary | r2030_8 |
| ir.cpp:2030:22:2030:22 | Address | &:r2030_2 |
| ir.cpp:2030:22:2030:22 | Arg(0) | 0:r2030_3 |
| ir.cpp:2030:22:2030:22 | Load | m2026_6 |
| ir.cpp:2030:26:2030:27 | Unary | r2030_7 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |

View File

@@ -724,6 +724,48 @@ complex.c:
# 58| v58_5(void) = AliasedUse : ~m?
# 58| v58_6(void) = ExitFunction :
ir.c:
# 7| void MyCoordsTest(int)
# 7| Block 0
# 7| v7_1(void) = EnterFunction :
# 7| mu7_2(unknown) = AliasedDefinition :
# 7| mu7_3(unknown) = InitializeNonLocal :
# 7| r7_4(glval<int>) = VariableAddress[pos] :
# 7| mu7_5(int) = InitializeParameter[pos] : &:r7_4
# 8| r8_1(glval<(unnamed class/struct/union)>) = VariableAddress[coords] :
# 8| mu8_2((unnamed class/struct/union)) = Uninitialized[coords] : &:r8_1
# 8| r8_3(glval<int>) = FieldAddress[x] : r8_1
# 8| r8_4(int) = Constant[0] :
# 8| mu8_5(int) = Store[?] : &:r8_3, r8_4
# 8| r8_6(glval<int>) = FieldAddress[y] : r8_1
# 8| r8_7(int) = Constant[0] :
# 8| mu8_8(int) = Store[?] : &:r8_6, r8_7
# 9| r9_1(glval<int>) = VariableAddress[pos] :
# 9| r9_2(int) = Load[pos] : &:r9_1, ~m?
# 9| r9_3(int) = Constant[1] :
# 9| r9_4(int) = Add : r9_2, r9_3
# 9| r9_5(glval<(unnamed class/struct/union)>) = VariableAddress[coords] :
# 9| r9_6(glval<int>) = FieldAddress[y] : r9_5
# 9| mu9_7(int) = Store[?] : &:r9_6, r9_4
# 9| r9_8(int) = CopyValue : r9_4
# 9| r9_9(glval<(unnamed class/struct/union)>) = VariableAddress[coords] :
# 9| r9_10(glval<int>) = FieldAddress[x] : r9_9
# 9| mu9_11(int) = Store[?] : &:r9_10, r9_8
# 10| r10_1(glval<unknown>) = FunctionAddress[getX] :
# 10| r10_2(glval<(unnamed class/struct/union)>) = VariableAddress[coords] :
# 10| r10_3(struct <unnamed> *) = CopyValue : r10_2
# 10| r10_4(int) = Call[getX] : func:r10_1, 0:r10_3
# 10| mu10_5(unknown) = ^CallSideEffect : ~m?
# 10| v10_6(void) = ^BufferReadSideEffect[0] : &:r10_3, ~m?
# 10| mu10_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_3
# 10| r10_8(glval<(unnamed class/struct/union)>) = VariableAddress[coords] :
# 10| r10_9(glval<int>) = FieldAddress[x] : r10_8
# 10| mu10_10(int) = Store[?] : &:r10_9, r10_4
# 11| v11_1(void) = NoOp :
# 7| v7_6(void) = ReturnVoid :
# 7| v7_7(void) = AliasedUse : ~m?
# 7| v7_8(void) = ExitFunction :
ir.cpp:
# 1| void Constants()
# 1| Block 0
@@ -10456,6 +10498,579 @@ ir.cpp:
# 1990| v1990_5(void) = AliasedUse : ~m?
# 1990| v1990_6(void) = ExitFunction :
# 1996| void TernaryTestInt(bool, int, int, int)
# 1996| Block 0
# 1996| v1996_1(void) = EnterFunction :
# 1996| mu1996_2(unknown) = AliasedDefinition :
# 1996| mu1996_3(unknown) = InitializeNonLocal :
# 1996| r1996_4(glval<bool>) = VariableAddress[a] :
# 1996| mu1996_5(bool) = InitializeParameter[a] : &:r1996_4
# 1996| r1996_6(glval<int>) = VariableAddress[x] :
# 1996| mu1996_7(int) = InitializeParameter[x] : &:r1996_6
# 1996| r1996_8(glval<int>) = VariableAddress[y] :
# 1996| mu1996_9(int) = InitializeParameter[y] : &:r1996_8
# 1996| r1996_10(glval<int>) = VariableAddress[z] :
# 1996| mu1996_11(int) = InitializeParameter[z] : &:r1996_10
# 1997| r1997_1(glval<bool>) = VariableAddress[a] :
# 1997| r1997_2(bool) = Load[a] : &:r1997_1, ~m?
# 1997| v1997_3(void) = ConditionalBranch : r1997_2
#-----| False -> Block 3
#-----| True -> Block 2
# 1997| Block 1
# 1997| r1997_4(glval<int>) = VariableAddress[#temp1997:9] :
# 1997| r1997_5(int) = Load[#temp1997:9] : &:r1997_4, ~m?
# 1997| r1997_6(glval<int>) = VariableAddress[z] :
# 1997| mu1997_7(int) = Store[z] : &:r1997_6, r1997_5
# 1998| r1998_1(glval<bool>) = VariableAddress[a] :
# 1998| r1998_2(bool) = Load[a] : &:r1998_1, ~m?
# 1998| v1998_3(void) = ConditionalBranch : r1998_2
#-----| False -> Block 6
#-----| True -> Block 5
# 1997| Block 2
# 1997| r1997_8(glval<int>) = VariableAddress[x] :
# 1997| r1997_9(int) = Load[x] : &:r1997_8, ~m?
# 1997| r1997_10(glval<int>) = VariableAddress[#temp1997:9] :
# 1997| mu1997_11(int) = Store[#temp1997:9] : &:r1997_10, r1997_9
#-----| Goto -> Block 1
# 1997| Block 3
# 1997| r1997_12(glval<int>) = VariableAddress[y] :
# 1997| r1997_13(int) = Load[y] : &:r1997_12, ~m?
# 1997| r1997_14(glval<int>) = VariableAddress[#temp1997:9] :
# 1997| mu1997_15(int) = Store[#temp1997:9] : &:r1997_14, r1997_13
#-----| Goto -> Block 1
# 1998| Block 4
# 1998| r1998_4(glval<int>) = VariableAddress[#temp1998:9] :
# 1998| r1998_5(int) = Load[#temp1998:9] : &:r1998_4, ~m?
# 1998| r1998_6(glval<int>) = VariableAddress[z] :
# 1998| mu1998_7(int) = Store[z] : &:r1998_6, r1998_5
# 1999| r1999_1(glval<bool>) = VariableAddress[a] :
# 1999| r1999_2(bool) = Load[a] : &:r1999_1, ~m?
# 1999| v1999_3(void) = ConditionalBranch : r1999_2
#-----| False -> Block 9
#-----| True -> Block 8
# 1998| Block 5
# 1998| r1998_8(glval<int>) = VariableAddress[x] :
# 1998| r1998_9(int) = Load[x] : &:r1998_8, ~m?
# 1998| r1998_10(glval<int>) = VariableAddress[#temp1998:9] :
# 1998| mu1998_11(int) = Store[#temp1998:9] : &:r1998_10, r1998_9
#-----| Goto -> Block 4
# 1998| Block 6
# 1998| r1998_12(int) = Constant[5] :
# 1998| r1998_13(glval<int>) = VariableAddress[#temp1998:9] :
# 1998| mu1998_14(int) = Store[#temp1998:9] : &:r1998_13, r1998_12
#-----| Goto -> Block 4
# 1999| Block 7
# 1999| r1999_4(glval<int>) = VariableAddress[#temp1999:9] :
# 1999| r1999_5(int) = Load[#temp1999:9] : &:r1999_4, ~m?
# 1999| r1999_6(glval<int>) = VariableAddress[z] :
# 1999| mu1999_7(int) = Store[z] : &:r1999_6, r1999_5
# 2000| r2000_1(int) = Constant[7] :
# 2000| r2000_2(glval<bool>) = VariableAddress[a] :
# 2000| r2000_3(bool) = Load[a] : &:r2000_2, ~m?
# 2000| v2000_4(void) = ConditionalBranch : r2000_3
#-----| False -> Block 12
#-----| True -> Block 11
# 1999| Block 8
# 1999| r1999_8(int) = Constant[3] :
# 1999| r1999_9(glval<int>) = VariableAddress[#temp1999:9] :
# 1999| mu1999_10(int) = Store[#temp1999:9] : &:r1999_9, r1999_8
#-----| Goto -> Block 7
# 1999| Block 9
# 1999| r1999_11(int) = Constant[5] :
# 1999| r1999_12(glval<int>) = VariableAddress[#temp1999:9] :
# 1999| mu1999_13(int) = Store[#temp1999:9] : &:r1999_12, r1999_11
#-----| Goto -> Block 7
# 2000| Block 10
# 2000| r2000_5(glval<unknown>) = VariableAddress[#temp2000:6] :
# 2000| r2000_6(glval<int>) = Load[#temp2000:6] : &:r2000_5, ~m?
# 2000| mu2000_7(int) = Store[?] : &:r2000_6, r2000_1
# 2001| v2001_1(void) = NoOp :
# 1996| v1996_12(void) = ReturnVoid :
# 1996| v1996_13(void) = AliasedUse : ~m?
# 1996| v1996_14(void) = ExitFunction :
# 2000| Block 11
# 2000| r2000_8(glval<int>) = VariableAddress[x] :
# 2000| r2000_9(glval<unknown>) = VariableAddress[#temp2000:6] :
# 2000| mu2000_10(glval<int>) = Store[#temp2000:6] : &:r2000_9, r2000_8
#-----| Goto -> Block 10
# 2000| Block 12
# 2000| r2000_11(glval<int>) = VariableAddress[y] :
# 2000| r2000_12(glval<unknown>) = VariableAddress[#temp2000:6] :
# 2000| mu2000_13(glval<int>) = Store[#temp2000:6] : &:r2000_12, r2000_11
#-----| Goto -> Block 10
# 2006| void TernaryTestPodObj(bool, TernaryPodObj, TernaryPodObj, TernaryPodObj)
# 2006| Block 0
# 2006| v2006_1(void) = EnterFunction :
# 2006| mu2006_2(unknown) = AliasedDefinition :
# 2006| mu2006_3(unknown) = InitializeNonLocal :
# 2006| r2006_4(glval<bool>) = VariableAddress[a] :
# 2006| mu2006_5(bool) = InitializeParameter[a] : &:r2006_4
# 2006| r2006_6(glval<TernaryPodObj>) = VariableAddress[x] :
# 2006| mu2006_7(TernaryPodObj) = InitializeParameter[x] : &:r2006_6
# 2006| r2006_8(glval<TernaryPodObj>) = VariableAddress[y] :
# 2006| mu2006_9(TernaryPodObj) = InitializeParameter[y] : &:r2006_8
# 2006| r2006_10(glval<TernaryPodObj>) = VariableAddress[z] :
# 2006| mu2006_11(TernaryPodObj) = InitializeParameter[z] : &:r2006_10
# 2007| r2007_1(glval<bool>) = VariableAddress[a] :
# 2007| r2007_2(bool) = Load[a] : &:r2007_1, ~m?
# 2007| v2007_3(void) = ConditionalBranch : r2007_2
#-----| False -> Block 3
#-----| True -> Block 2
# 2007| Block 1
# 2007| r2007_4(glval<TernaryPodObj>) = VariableAddress[#temp2007:9] :
# 2007| r2007_5(TernaryPodObj) = Load[#temp2007:9] : &:r2007_4, ~m?
# 2007| r2007_6(glval<TernaryPodObj>) = VariableAddress[z] :
# 2007| mu2007_7(TernaryPodObj) = Store[z] : &:r2007_6, r2007_5
# 2008| r2008_1(glval<TernaryPodObj>) = VariableAddress[#temp2008:9] :
# 2008| r2008_2(glval<bool>) = VariableAddress[a] :
# 2008| r2008_3(bool) = Load[a] : &:r2008_2, ~m?
# 2008| v2008_4(void) = ConditionalBranch : r2008_3
#-----| False -> Block 6
#-----| True -> Block 5
# 2007| Block 2
# 2007| r2007_8(glval<TernaryPodObj>) = VariableAddress[x] :
# 2007| r2007_9(TernaryPodObj) = Load[x] : &:r2007_8, ~m?
# 2007| r2007_10(glval<TernaryPodObj>) = VariableAddress[#temp2007:9] :
# 2007| mu2007_11(TernaryPodObj) = Store[#temp2007:9] : &:r2007_10, r2007_9
#-----| Goto -> Block 1
# 2007| Block 3
# 2007| r2007_12(glval<TernaryPodObj>) = VariableAddress[y] :
# 2007| r2007_13(TernaryPodObj) = Load[y] : &:r2007_12, ~m?
# 2007| r2007_14(glval<TernaryPodObj>) = VariableAddress[#temp2007:9] :
# 2007| mu2007_15(TernaryPodObj) = Store[#temp2007:9] : &:r2007_14, r2007_13
#-----| Goto -> Block 1
# 2008| Block 4
# 2008| r2008_5(glval<TernaryPodObj>) = VariableAddress[#temp2008:9] :
# 2008| r2008_6(TernaryPodObj) = Load[#temp2008:9] : &:r2008_5, ~m?
# 2008| mu2008_7(TernaryPodObj) = Store[#temp2008:9] : &:r2008_1, r2008_6
# 2008| r2008_8(TernaryPodObj) = Load[#temp2008:9] : &:r2008_1, ~m?
# 2008| r2008_9(glval<TernaryPodObj>) = VariableAddress[z] :
# 2008| mu2008_10(TernaryPodObj) = Store[z] : &:r2008_9, r2008_8
# 2009| r2009_1(glval<TernaryPodObj>) = VariableAddress[#temp2009:9] :
# 2009| r2009_2(glval<bool>) = VariableAddress[a] :
# 2009| r2009_3(bool) = Load[a] : &:r2009_2, ~m?
# 2009| v2009_4(void) = ConditionalBranch : r2009_3
#-----| False -> Block 9
#-----| True -> Block 8
# 2008| Block 5
# 2008| r2008_11(glval<TernaryPodObj>) = VariableAddress[#temp2008:13] :
# 2008| r2008_12(glval<TernaryPodObj>) = VariableAddress[x] :
# 2008| r2008_13(TernaryPodObj) = Load[x] : &:r2008_12, ~m?
# 2008| mu2008_14(TernaryPodObj) = Store[#temp2008:13] : &:r2008_11, r2008_13
# 2008| r2008_15(TernaryPodObj) = Load[#temp2008:13] : &:r2008_11, ~m?
# 2008| r2008_16(glval<TernaryPodObj>) = VariableAddress[#temp2008:9] :
# 2008| mu2008_17(TernaryPodObj) = Store[#temp2008:9] : &:r2008_16, r2008_15
#-----| Goto -> Block 4
# 2008| Block 6
# 2008| r2008_18(glval<TernaryPodObj>) = VariableAddress[#temp2008:17] :
# 2008| r2008_19(TernaryPodObj) = Constant[0] :
# 2008| mu2008_20(TernaryPodObj) = Store[#temp2008:17] : &:r2008_18, r2008_19
# 2008| r2008_21(TernaryPodObj) = Load[#temp2008:17] : &:r2008_18, ~m?
# 2008| r2008_22(glval<TernaryPodObj>) = VariableAddress[#temp2008:9] :
# 2008| mu2008_23(TernaryPodObj) = Store[#temp2008:9] : &:r2008_22, r2008_21
#-----| Goto -> Block 4
# 2009| Block 7
# 2009| r2009_5(glval<TernaryPodObj>) = VariableAddress[#temp2009:9] :
# 2009| r2009_6(TernaryPodObj) = Load[#temp2009:9] : &:r2009_5, ~m?
# 2009| mu2009_7(TernaryPodObj) = Store[#temp2009:9] : &:r2009_1, r2009_6
# 2009| r2009_8(TernaryPodObj) = Load[#temp2009:9] : &:r2009_1, ~m?
# 2009| r2009_9(glval<TernaryPodObj>) = VariableAddress[z] :
# 2009| mu2009_10(TernaryPodObj) = Store[z] : &:r2009_9, r2009_8
# 2010| r2010_1(glval<TernaryPodObj>) = VariableAddress[#temp2010:23] :
# 2010| r2010_2(TernaryPodObj) = Constant[0] :
# 2010| mu2010_3(TernaryPodObj) = Store[#temp2010:23] : &:r2010_1, r2010_2
# 2010| r2010_4(TernaryPodObj) = Load[#temp2010:23] : &:r2010_1, ~m?
# 2010| r2010_5(glval<bool>) = VariableAddress[a] :
# 2010| r2010_6(bool) = Load[a] : &:r2010_5, ~m?
# 2010| v2010_7(void) = ConditionalBranch : r2010_6
#-----| False -> Block 12
#-----| True -> Block 11
# 2009| Block 8
# 2009| r2009_11(glval<TernaryPodObj>) = VariableAddress[#temp2009:13] :
# 2009| r2009_12(TernaryPodObj) = Constant[0] :
# 2009| mu2009_13(TernaryPodObj) = Store[#temp2009:13] : &:r2009_11, r2009_12
# 2009| r2009_14(TernaryPodObj) = Load[#temp2009:13] : &:r2009_11, ~m?
# 2009| r2009_15(glval<TernaryPodObj>) = VariableAddress[#temp2009:9] :
# 2009| mu2009_16(TernaryPodObj) = Store[#temp2009:9] : &:r2009_15, r2009_14
#-----| Goto -> Block 7
# 2009| Block 9
# 2009| r2009_17(glval<TernaryPodObj>) = VariableAddress[#temp2009:31] :
# 2009| r2009_18(TernaryPodObj) = Constant[0] :
# 2009| mu2009_19(TernaryPodObj) = Store[#temp2009:31] : &:r2009_17, r2009_18
# 2009| r2009_20(TernaryPodObj) = Load[#temp2009:31] : &:r2009_17, ~m?
# 2009| r2009_21(glval<TernaryPodObj>) = VariableAddress[#temp2009:9] :
# 2009| mu2009_22(TernaryPodObj) = Store[#temp2009:9] : &:r2009_21, r2009_20
#-----| Goto -> Block 7
# 2010| Block 10
# 2010| r2010_8(glval<TernaryPodObj>) = VariableAddress[#temp2010:10] :
# 2010| r2010_9(TernaryPodObj) = Load[#temp2010:10] : &:r2010_8, ~m?
# 2010| r2010_10(glval<TernaryPodObj>) = VariableAddress[z] :
# 2010| mu2010_11(TernaryPodObj) = Store[z] : &:r2010_10, r2010_9
# 2010| r2010_12(glval<TernaryPodObj>) = CopyValue : r2010_10
# 2010| mu2010_13(TernaryPodObj) = Store[?] : &:r2010_12, r2010_4
# 2011| v2011_1(void) = NoOp :
# 2006| v2006_12(void) = ReturnVoid :
# 2006| v2006_13(void) = AliasedUse : ~m?
# 2006| v2006_14(void) = ExitFunction :
# 2010| Block 11
# 2010| r2010_14(glval<TernaryPodObj>) = VariableAddress[x] :
# 2010| r2010_15(TernaryPodObj) = Load[x] : &:r2010_14, ~m?
# 2010| r2010_16(glval<TernaryPodObj>) = VariableAddress[#temp2010:10] :
# 2010| mu2010_17(TernaryPodObj) = Store[#temp2010:10] : &:r2010_16, r2010_15
#-----| Goto -> Block 10
# 2010| Block 12
# 2010| r2010_18(glval<TernaryPodObj>) = VariableAddress[y] :
# 2010| r2010_19(TernaryPodObj) = Load[y] : &:r2010_18, ~m?
# 2010| r2010_20(glval<TernaryPodObj>) = VariableAddress[#temp2010:10] :
# 2010| mu2010_21(TernaryPodObj) = Store[#temp2010:10] : &:r2010_20, r2010_19
#-----| Goto -> Block 10
# 2013| TernaryNonPodObj& TernaryNonPodObj::operator=(TernaryNonPodObj const&)
# 2013| Block 0
# 2013| v2013_1(void) = EnterFunction :
# 2013| mu2013_2(unknown) = AliasedDefinition :
# 2013| mu2013_3(unknown) = InitializeNonLocal :
# 2013| r2013_4(glval<unknown>) = VariableAddress[#this] :
# 2013| mu2013_5(glval<TernaryNonPodObj>) = InitializeParameter[#this] : &:r2013_4
# 2013| r2013_6(glval<TernaryNonPodObj>) = Load[#this] : &:r2013_4, ~m?
# 2013| mu2013_7(TernaryNonPodObj) = InitializeIndirection[#this] : &:r2013_6
#-----| r0_1(glval<TernaryNonPodObj &>) = VariableAddress[(unnamed parameter 0)] :
#-----| mu0_2(TernaryNonPodObj &) = InitializeParameter[(unnamed parameter 0)] : &:r0_1
#-----| r0_3(TernaryNonPodObj &) = Load[(unnamed parameter 0)] : &:r0_1, ~m?
#-----| mu0_4(unknown) = InitializeIndirection[(unnamed parameter 0)] : &:r0_3
#-----| r0_5(glval<TernaryNonPodObj &>) = VariableAddress[#return] :
#-----| r0_6(glval<unknown>) = VariableAddress[#this] :
#-----| r0_7(TernaryNonPodObj *) = Load[#this] : &:r0_6, ~m?
#-----| r0_8(glval<TernaryNonPodObj>) = CopyValue : r0_7
#-----| r0_9(TernaryNonPodObj &) = CopyValue : r0_8
#-----| mu0_10(TernaryNonPodObj &) = Store[#return] : &:r0_5, r0_9
# 2013| v2013_8(void) = ReturnIndirection[#this] : &:r2013_6, ~m?
#-----| v0_11(void) = ReturnIndirection[(unnamed parameter 0)] : &:r0_3, ~m?
# 2013| r2013_9(glval<TernaryNonPodObj &>) = VariableAddress[#return] :
# 2013| v2013_10(void) = ReturnValue : &:r2013_9, ~m?
# 2013| v2013_11(void) = AliasedUse : ~m?
# 2013| v2013_12(void) = ExitFunction :
# 2013| void TernaryNonPodObj::TernaryNonPodObj()
# 2013| Block 0
# 2013| v2013_1(void) = EnterFunction :
# 2013| mu2013_2(unknown) = AliasedDefinition :
# 2013| mu2013_3(unknown) = InitializeNonLocal :
# 2013| r2013_4(glval<unknown>) = VariableAddress[#this] :
# 2013| mu2013_5(glval<TernaryNonPodObj>) = InitializeParameter[#this] : &:r2013_4
# 2013| r2013_6(glval<TernaryNonPodObj>) = Load[#this] : &:r2013_4, ~m?
# 2013| mu2013_7(TernaryNonPodObj) = InitializeIndirection[#this] : &:r2013_6
# 2013| v2013_8(void) = NoOp :
# 2013| v2013_9(void) = ReturnIndirection[#this] : &:r2013_6, ~m?
# 2013| v2013_10(void) = ReturnVoid :
# 2013| v2013_11(void) = AliasedUse : ~m?
# 2013| v2013_12(void) = ExitFunction :
# 2013| void TernaryNonPodObj::TernaryNonPodObj(TernaryNonPodObj const&)
# 2013| Block 0
# 2013| v2013_1(void) = EnterFunction :
# 2013| mu2013_2(unknown) = AliasedDefinition :
# 2013| mu2013_3(unknown) = InitializeNonLocal :
# 2013| r2013_4(glval<unknown>) = VariableAddress[#this] :
# 2013| mu2013_5(glval<TernaryNonPodObj>) = InitializeParameter[#this] : &:r2013_4
# 2013| r2013_6(glval<TernaryNonPodObj>) = Load[#this] : &:r2013_4, ~m?
# 2013| mu2013_7(TernaryNonPodObj) = InitializeIndirection[#this] : &:r2013_6
#-----| r0_1(glval<TernaryNonPodObj &>) = VariableAddress[(unnamed parameter 0)] :
#-----| mu0_2(TernaryNonPodObj &) = InitializeParameter[(unnamed parameter 0)] : &:r0_1
#-----| r0_3(TernaryNonPodObj &) = Load[(unnamed parameter 0)] : &:r0_1, ~m?
#-----| mu0_4(unknown) = InitializeIndirection[(unnamed parameter 0)] : &:r0_3
# 2013| v2013_8(void) = NoOp :
# 2013| v2013_9(void) = ReturnIndirection[#this] : &:r2013_6, ~m?
#-----| v0_5(void) = ReturnIndirection[(unnamed parameter 0)] : &:r0_3, ~m?
# 2013| v2013_10(void) = ReturnVoid :
# 2013| v2013_11(void) = AliasedUse : ~m?
# 2013| v2013_12(void) = ExitFunction :
# 2014| void TernaryNonPodObj::~TernaryNonPodObj()
# 2014| Block 0
# 2014| v2014_1(void) = EnterFunction :
# 2014| mu2014_2(unknown) = AliasedDefinition :
# 2014| mu2014_3(unknown) = InitializeNonLocal :
# 2014| r2014_4(glval<unknown>) = VariableAddress[#this] :
# 2014| mu2014_5(glval<TernaryNonPodObj>) = InitializeParameter[#this] : &:r2014_4
# 2014| r2014_6(glval<TernaryNonPodObj>) = Load[#this] : &:r2014_4, ~m?
# 2014| mu2014_7(TernaryNonPodObj) = InitializeIndirection[#this] : &:r2014_6
# 2014| v2014_8(void) = NoOp :
# 2014| v2014_9(void) = ReturnIndirection[#this] : &:r2014_6, ~m?
# 2014| v2014_10(void) = ReturnVoid :
# 2014| v2014_11(void) = AliasedUse : ~m?
# 2014| v2014_12(void) = ExitFunction :
# 2017| void TernaryTestNonPodObj(bool, TernaryNonPodObj, TernaryNonPodObj, TernaryNonPodObj)
# 2017| Block 0
# 2017| v2017_1(void) = EnterFunction :
# 2017| mu2017_2(unknown) = AliasedDefinition :
# 2017| mu2017_3(unknown) = InitializeNonLocal :
# 2017| r2017_4(glval<bool>) = VariableAddress[a] :
# 2017| mu2017_5(bool) = InitializeParameter[a] : &:r2017_4
# 2017| r2017_6(glval<TernaryNonPodObj>) = VariableAddress[x] :
# 2017| mu2017_7(TernaryNonPodObj) = InitializeParameter[x] : &:r2017_6
# 2017| r2017_8(glval<TernaryNonPodObj>) = VariableAddress[y] :
# 2017| mu2017_9(TernaryNonPodObj) = InitializeParameter[y] : &:r2017_8
# 2017| r2017_10(glval<TernaryNonPodObj>) = VariableAddress[z] :
# 2017| mu2017_11(TernaryNonPodObj) = InitializeParameter[z] : &:r2017_10
# 2018| r2018_1(glval<TernaryNonPodObj>) = VariableAddress[z] :
# 2018| r2018_2(glval<unknown>) = FunctionAddress[operator=] :
# 2018| r2018_3(glval<bool>) = VariableAddress[a] :
# 2018| r2018_4(bool) = Load[a] : &:r2018_3, ~m?
# 2018| v2018_5(void) = ConditionalBranch : r2018_4
#-----| False -> Block 3
#-----| True -> Block 2
# 2018| Block 1
# 2018| r2018_6(glval<unknown>) = VariableAddress[#temp2018:9] :
# 2018| r2018_7(glval<TernaryNonPodObj>) = Load[#temp2018:9] : &:r2018_6, ~m?
# 2018| r2018_8(glval<TernaryNonPodObj>) = Convert : r2018_7
# 2018| r2018_9(TernaryNonPodObj &) = CopyValue : r2018_8
# 2018| r2018_10(TernaryNonPodObj &) = Call[operator=] : func:r2018_2, this:r2018_1, 0:r2018_9
# 2018| mu2018_11(unknown) = ^CallSideEffect : ~m?
# 2018| v2018_12(void) = ^IndirectReadSideEffect[-1] : &:r2018_1, ~m?
# 2018| v2018_13(void) = ^BufferReadSideEffect[0] : &:r2018_9, ~m?
# 2018| mu2018_14(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2018_1
# 2018| r2018_15(glval<TernaryNonPodObj>) = CopyValue : r2018_10
# 2019| r2019_1(glval<TernaryNonPodObj>) = VariableAddress[z] :
# 2019| r2019_2(glval<unknown>) = FunctionAddress[operator=] :
# 2019| r2019_3(glval<TernaryNonPodObj>) = VariableAddress[#temp2019:9] :
# 2019| r2019_4(glval<bool>) = VariableAddress[a] :
# 2019| r2019_5(bool) = Load[a] : &:r2019_4, ~m?
# 2019| v2019_6(void) = ConditionalBranch : r2019_5
#-----| False -> Block 6
#-----| True -> Block 5
# 2018| Block 2
# 2018| r2018_16(glval<TernaryNonPodObj>) = VariableAddress[x] :
# 2018| r2018_17(glval<unknown>) = VariableAddress[#temp2018:9] :
# 2018| mu2018_18(glval<TernaryNonPodObj>) = Store[#temp2018:9] : &:r2018_17, r2018_16
#-----| Goto -> Block 1
# 2018| Block 3
# 2018| r2018_19(glval<TernaryNonPodObj>) = VariableAddress[y] :
# 2018| r2018_20(glval<unknown>) = VariableAddress[#temp2018:9] :
# 2018| mu2018_21(glval<TernaryNonPodObj>) = Store[#temp2018:9] : &:r2018_20, r2018_19
#-----| Goto -> Block 1
# 2019| Block 4
# 2019| r2019_7(glval<TernaryNonPodObj>) = VariableAddress[#temp2019:9] :
# 2019| r2019_8(TernaryNonPodObj) = Load[#temp2019:9] : &:r2019_7, ~m?
# 2019| mu2019_9(TernaryNonPodObj) = Store[#temp2019:9] : &:r2019_3, r2019_8
# 2019| r2019_10(glval<TernaryNonPodObj>) = Convert : r2019_3
# 2019| r2019_11(TernaryNonPodObj &) = CopyValue : r2019_10
# 2019| r2019_12(TernaryNonPodObj &) = Call[operator=] : func:r2019_2, this:r2019_1, 0:r2019_11
# 2019| mu2019_13(unknown) = ^CallSideEffect : ~m?
# 2019| v2019_14(void) = ^IndirectReadSideEffect[-1] : &:r2019_1, ~m?
# 2019| v2019_15(void) = ^BufferReadSideEffect[0] : &:r2019_11, ~m?
# 2019| mu2019_16(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2019_1
# 2019| r2019_17(glval<TernaryNonPodObj>) = CopyValue : r2019_12
# 2020| r2020_1(glval<TernaryNonPodObj>) = VariableAddress[z] :
# 2020| r2020_2(glval<unknown>) = FunctionAddress[operator=] :
# 2020| r2020_3(glval<TernaryNonPodObj>) = VariableAddress[#temp2020:9] :
# 2020| r2020_4(glval<bool>) = VariableAddress[a] :
# 2020| r2020_5(bool) = Load[a] : &:r2020_4, ~m?
# 2020| v2020_6(void) = ConditionalBranch : r2020_5
#-----| False -> Block 9
#-----| True -> Block 8
# 2019| Block 5
# 2019| r2019_18(glval<TernaryNonPodObj>) = VariableAddress[#temp2019:13] :
# 2019| mu2019_19(TernaryNonPodObj) = Uninitialized[#temp2019:13] : &:r2019_18
# 2019| r2019_20(glval<unknown>) = FunctionAddress[TernaryNonPodObj] :
# 2019| r2019_21(glval<TernaryNonPodObj>) = VariableAddress[x] :
# 2019| r2019_22(glval<TernaryNonPodObj>) = Convert : r2019_21
# 2019| r2019_23(TernaryNonPodObj &) = CopyValue : r2019_22
# 2019| v2019_24(void) = Call[TernaryNonPodObj] : func:r2019_20, this:r2019_18, 0:r2019_23
# 2019| mu2019_25(unknown) = ^CallSideEffect : ~m?
# 2019| v2019_26(void) = ^BufferReadSideEffect[0] : &:r2019_23, ~m?
# 2019| mu2019_27(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2019_18
# 2019| r2019_28(TernaryNonPodObj) = Load[#temp2019:13] : &:r2019_18, ~m?
# 2019| r2019_29(glval<TernaryNonPodObj>) = VariableAddress[#temp2019:9] :
# 2019| mu2019_30(TernaryNonPodObj) = Store[#temp2019:9] : &:r2019_29, r2019_28
#-----| Goto -> Block 4
# 2019| Block 6
# 2019| r2019_31(glval<TernaryNonPodObj>) = VariableAddress[#temp2019:17] :
# 2019| mu2019_32(TernaryNonPodObj) = Uninitialized[#temp2019:17] : &:r2019_31
# 2019| r2019_33(glval<unknown>) = FunctionAddress[TernaryNonPodObj] :
# 2019| v2019_34(void) = Call[TernaryNonPodObj] : func:r2019_33, this:r2019_31
# 2019| mu2019_35(unknown) = ^CallSideEffect : ~m?
# 2019| mu2019_36(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2019_31
# 2019| r2019_37(TernaryNonPodObj) = Load[#temp2019:17] : &:r2019_31, ~m?
# 2019| r2019_38(glval<TernaryNonPodObj>) = VariableAddress[#temp2019:9] :
# 2019| mu2019_39(TernaryNonPodObj) = Store[#temp2019:9] : &:r2019_38, r2019_37
#-----| Goto -> Block 4
# 2020| Block 7
# 2020| r2020_7(glval<TernaryNonPodObj>) = VariableAddress[#temp2020:9] :
# 2020| r2020_8(TernaryNonPodObj) = Load[#temp2020:9] : &:r2020_7, ~m?
# 2020| mu2020_9(TernaryNonPodObj) = Store[#temp2020:9] : &:r2020_3, r2020_8
# 2020| r2020_10(glval<TernaryNonPodObj>) = Convert : r2020_3
# 2020| r2020_11(TernaryNonPodObj &) = CopyValue : r2020_10
# 2020| r2020_12(TernaryNonPodObj &) = Call[operator=] : func:r2020_2, this:r2020_1, 0:r2020_11
# 2020| mu2020_13(unknown) = ^CallSideEffect : ~m?
# 2020| v2020_14(void) = ^IndirectReadSideEffect[-1] : &:r2020_1, ~m?
# 2020| v2020_15(void) = ^BufferReadSideEffect[0] : &:r2020_11, ~m?
# 2020| mu2020_16(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2020_1
# 2020| r2020_17(glval<TernaryNonPodObj>) = CopyValue : r2020_12
# 2021| r2021_1(glval<TernaryNonPodObj>) = VariableAddress[z] :
# 2021| r2021_2(glval<unknown>) = FunctionAddress[operator=] :
# 2021| r2021_3(glval<bool>) = VariableAddress[a] :
# 2021| r2021_4(bool) = Load[a] : &:r2021_3, ~m?
# 2021| v2021_5(void) = ConditionalBranch : r2021_4
#-----| False -> Block 12
#-----| True -> Block 11
# 2020| Block 8
# 2020| r2020_18(glval<TernaryNonPodObj>) = VariableAddress[#temp2020:13] :
# 2020| mu2020_19(TernaryNonPodObj) = Uninitialized[#temp2020:13] : &:r2020_18
# 2020| r2020_20(glval<unknown>) = FunctionAddress[TernaryNonPodObj] :
# 2020| v2020_21(void) = Call[TernaryNonPodObj] : func:r2020_20, this:r2020_18
# 2020| mu2020_22(unknown) = ^CallSideEffect : ~m?
# 2020| mu2020_23(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2020_18
# 2020| r2020_24(TernaryNonPodObj) = Load[#temp2020:13] : &:r2020_18, ~m?
# 2020| r2020_25(glval<TernaryNonPodObj>) = VariableAddress[#temp2020:9] :
# 2020| mu2020_26(TernaryNonPodObj) = Store[#temp2020:9] : &:r2020_25, r2020_24
#-----| Goto -> Block 7
# 2020| Block 9
# 2020| r2020_27(glval<TernaryNonPodObj>) = VariableAddress[#temp2020:34] :
# 2020| mu2020_28(TernaryNonPodObj) = Uninitialized[#temp2020:34] : &:r2020_27
# 2020| r2020_29(glval<unknown>) = FunctionAddress[TernaryNonPodObj] :
# 2020| v2020_30(void) = Call[TernaryNonPodObj] : func:r2020_29, this:r2020_27
# 2020| mu2020_31(unknown) = ^CallSideEffect : ~m?
# 2020| mu2020_32(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2020_27
# 2020| r2020_33(TernaryNonPodObj) = Load[#temp2020:34] : &:r2020_27, ~m?
# 2020| r2020_34(glval<TernaryNonPodObj>) = VariableAddress[#temp2020:9] :
# 2020| mu2020_35(TernaryNonPodObj) = Store[#temp2020:9] : &:r2020_34, r2020_33
#-----| Goto -> Block 7
# 2021| Block 10
# 2021| r2021_6(glval<unknown>) = VariableAddress[#temp2021:10] :
# 2021| r2021_7(glval<TernaryNonPodObj>) = Load[#temp2021:10] : &:r2021_6, ~m?
# 2021| r2021_8(glval<TernaryNonPodObj>) = Convert : r2021_7
# 2021| r2021_9(TernaryNonPodObj &) = CopyValue : r2021_8
# 2021| r2021_10(TernaryNonPodObj &) = Call[operator=] : func:r2021_2, this:r2021_1, 0:r2021_9
# 2021| mu2021_11(unknown) = ^CallSideEffect : ~m?
# 2021| v2021_12(void) = ^IndirectReadSideEffect[-1] : &:r2021_1, ~m?
# 2021| v2021_13(void) = ^BufferReadSideEffect[0] : &:r2021_9, ~m?
# 2021| mu2021_14(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2021_1
# 2021| r2021_15(glval<TernaryNonPodObj>) = CopyValue : r2021_10
# 2021| r2021_16(glval<unknown>) = FunctionAddress[operator=] :
# 2021| r2021_17(glval<TernaryNonPodObj>) = VariableAddress[#temp2021:23] :
# 2021| mu2021_18(TernaryNonPodObj) = Uninitialized[#temp2021:23] : &:r2021_17
# 2021| r2021_19(glval<unknown>) = FunctionAddress[TernaryNonPodObj] :
# 2021| v2021_20(void) = Call[TernaryNonPodObj] : func:r2021_19, this:r2021_17
# 2021| mu2021_21(unknown) = ^CallSideEffect : ~m?
# 2021| mu2021_22(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2021_17
# 2021| r2021_23(glval<TernaryNonPodObj>) = Convert : r2021_17
# 2021| r2021_24(TernaryNonPodObj &) = CopyValue : r2021_23
# 2021| r2021_25(TernaryNonPodObj &) = Call[operator=] : func:r2021_16, this:r2021_15, 0:r2021_24
# 2021| mu2021_26(unknown) = ^CallSideEffect : ~m?
# 2021| v2021_27(void) = ^IndirectReadSideEffect[-1] : &:r2021_15, ~m?
# 2021| v2021_28(void) = ^BufferReadSideEffect[0] : &:r2021_24, ~m?
# 2021| mu2021_29(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2021_15
# 2021| r2021_30(glval<TernaryNonPodObj>) = CopyValue : r2021_25
# 2022| v2022_1(void) = NoOp :
# 2017| v2017_12(void) = ReturnVoid :
# 2017| v2017_13(void) = AliasedUse : ~m?
# 2017| v2017_14(void) = ExitFunction :
# 2021| Block 11
# 2021| r2021_31(glval<TernaryNonPodObj>) = VariableAddress[x] :
# 2021| r2021_32(glval<unknown>) = VariableAddress[#temp2021:10] :
# 2021| mu2021_33(glval<TernaryNonPodObj>) = Store[#temp2021:10] : &:r2021_32, r2021_31
#-----| Goto -> Block 10
# 2021| Block 12
# 2021| r2021_34(glval<TernaryNonPodObj>) = VariableAddress[y] :
# 2021| r2021_35(glval<unknown>) = VariableAddress[#temp2021:10] :
# 2021| mu2021_36(glval<TernaryNonPodObj>) = Store[#temp2021:10] : &:r2021_35, r2021_34
#-----| Goto -> Block 10
# 2026| unsigned int CommaTest(unsigned int)
# 2026| Block 0
# 2026| v2026_1(void) = EnterFunction :
# 2026| mu2026_2(unknown) = AliasedDefinition :
# 2026| mu2026_3(unknown) = InitializeNonLocal :
# 2026| r2026_4(glval<unsigned int>) = VariableAddress[x] :
# 2026| mu2026_5(unsigned int) = InitializeParameter[x] : &:r2026_4
# 2027| r2027_1(glval<unsigned int>) = VariableAddress[y] :
# 2027| mu2027_2(unsigned int) = Uninitialized[y] : &:r2027_1
# 2028| r2028_1(glval<unsigned int>) = VariableAddress[x] :
# 2028| r2028_2(unsigned int) = Load[x] : &:r2028_1, ~m?
# 2028| r2028_3(unsigned int) = Constant[100] :
# 2028| r2028_4(bool) = CompareLT : r2028_2, r2028_3
# 2028| v2028_5(void) = ConditionalBranch : r2028_4
#-----| False -> Block 4
#-----| True -> Block 3
# 2026| Block 1
# 2026| r2026_6(glval<unsigned int>) = VariableAddress[#return] :
# 2026| v2026_7(void) = ReturnValue : &:r2026_6, ~m?
# 2026| v2026_8(void) = AliasedUse : ~m?
# 2026| v2026_9(void) = ExitFunction :
# 2028| Block 2
# 2028| r2028_6(glval<unsigned int>) = VariableAddress[#temp2028:7] :
# 2028| r2028_7(unsigned int) = Load[#temp2028:7] : &:r2028_6, ~m?
# 2028| r2028_8(glval<unsigned int>) = VariableAddress[y] :
# 2028| mu2028_9(unsigned int) = Store[y] : &:r2028_8, r2028_7
# 2031| v2031_1(void) = Unreached :
# 2029| Block 3
# 2029| r2029_1(glval<unknown>) = FunctionAddress[CommaTestHelper] :
# 2029| r2029_2(glval<unsigned int>) = VariableAddress[x] :
# 2029| r2029_3(unsigned int) = Load[x] : &:r2029_2, ~m?
# 2029| v2029_4(void) = Call[CommaTestHelper] : func:r2029_1, 0:r2029_3
# 2029| mu2029_5(unknown) = ^CallSideEffect : ~m?
# 2029| r2029_6(glval<unsigned int>) = VariableAddress[x] :
# 2029| r2029_7(unsigned int) = Load[x] : &:r2029_6, ~m?
# 2029| r2029_8(unsigned int) = CopyValue : r2029_7
# 2028| r2028_10(glval<unsigned int>) = VariableAddress[#temp2028:7] :
# 2028| mu2028_11(unsigned int) = Store[#temp2028:7] : &:r2028_10, r2029_8
#-----| Goto -> Block 2
# 2030| Block 4
# 2030| r2030_1(glval<unknown>) = FunctionAddress[CommaTestHelper] :
# 2030| r2030_2(glval<unsigned int>) = VariableAddress[x] :
# 2030| r2030_3(unsigned int) = Load[x] : &:r2030_2, ~m?
# 2030| v2030_4(void) = Call[CommaTestHelper] : func:r2030_1, 0:r2030_3
# 2030| mu2030_5(unknown) = ^CallSideEffect : ~m?
# 2030| r2030_6(int) = Constant[10] :
# 2030| r2030_7(int) = CopyValue : r2030_6
# 2030| r2030_8(unsigned int) = Convert : r2030_7
# 2028| r2028_12(glval<unsigned int>) = VariableAddress[#temp2028:7] :
# 2028| mu2028_13(unsigned int) = Store[#temp2028:7] : &:r2028_12, r2030_8
#-----| Goto -> Block 2
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -7,5 +7,5 @@ private import semmle.code.cpp.ir.implementation.raw.PrintIR
private import PrintConfig
private class PrintConfig extends PrintIRConfiguration {
override predicate shouldPrintFunction(Declaration decl) { shouldDumpFunction(decl) }
override predicate shouldPrintDeclaration(Declaration decl) { shouldDumpDeclaration(decl) }
}

View File

@@ -95,3 +95,25 @@ void gotoLoop(bool b1, bool b2)
}
}
}
void test_sub(int x, int y, int n) {
if(x > 0 && x < 500) {
if(y > 0 && y < 10) {
range(x - y); // $ range=<=498 range=>=-8
}
if(n > 0 && n < 100) {
for (int i = 0; i < n; i++)
{
range(n - i); // $ range=">=Phi: i-97" range=<=99 range=>=-97
range(i - n); // $ range="<=Phi: i-1" range=">=Phi: i-99" range=<=97 range=>=-99
}
for (int i = n; i != 0; i--)
{
range(n - i); // $ SPURIOUS: overflow=+
range(i - n); // $ range=">=Phi: i-99"
}
}
}
}

View File

@@ -2157,3 +2157,46 @@ ssa.cpp:
# 431| v431_9(void) = ReturnValue : &:r431_8, m435_4
# 431| v431_10(void) = AliasedUse : m431_3
# 431| v431_11(void) = ExitFunction :
# 438| void Conditional(bool, int, int)
# 438| Block 0
# 438| v438_1(void) = EnterFunction :
# 438| m438_2(unknown) = AliasedDefinition :
# 438| m438_3(unknown) = InitializeNonLocal :
# 438| m438_4(unknown) = Chi : total:m438_2, partial:m438_3
# 438| r438_5(glval<bool>) = VariableAddress[a] :
# 438| m438_6(bool) = InitializeParameter[a] : &:r438_5
# 438| r438_7(glval<int>) = VariableAddress[x] :
# 438| m438_8(int) = InitializeParameter[x] : &:r438_7
# 438| r438_9(glval<int>) = VariableAddress[y] :
# 438| m438_10(int) = InitializeParameter[y] : &:r438_9
# 439| r439_1(glval<int>) = VariableAddress[z] :
# 439| r439_2(glval<bool>) = VariableAddress[a] :
# 439| r439_3(bool) = Load[a] : &:r439_2, m438_6
# 439| v439_4(void) = ConditionalBranch : r439_3
#-----| False -> Block 3
#-----| True -> Block 2
# 439| Block 1
# 439| m439_5(int) = Phi : from 2:m439_12, from 3:m439_16
# 439| r439_6(glval<int>) = VariableAddress[#temp439:13] :
# 439| r439_7(int) = Load[#temp439:13] : &:r439_6, m439_5
# 439| m439_8(int) = Store[z] : &:r439_1, r439_7
# 440| v440_1(void) = NoOp :
# 438| v438_11(void) = ReturnVoid :
# 438| v438_12(void) = AliasedUse : m438_3
# 438| v438_13(void) = ExitFunction :
# 439| Block 2
# 439| r439_9(glval<int>) = VariableAddress[x] :
# 439| r439_10(int) = Load[x] : &:r439_9, m438_8
# 439| r439_11(glval<int>) = VariableAddress[#temp439:13] :
# 439| m439_12(int) = Store[#temp439:13] : &:r439_11, r439_10
#-----| Goto -> Block 1
# 439| Block 3
# 439| r439_13(glval<int>) = VariableAddress[y] :
# 439| r439_14(int) = Load[y] : &:r439_13, m438_10
# 439| r439_15(glval<int>) = VariableAddress[#temp439:13] :
# 439| m439_16(int) = Store[#temp439:13] : &:r439_15, r439_14
#-----| Goto -> Block 1

View File

@@ -2146,3 +2146,46 @@ ssa.cpp:
# 431| v431_9(void) = ReturnValue : &:r431_8, m435_4
# 431| v431_10(void) = AliasedUse : m431_3
# 431| v431_11(void) = ExitFunction :
# 438| void Conditional(bool, int, int)
# 438| Block 0
# 438| v438_1(void) = EnterFunction :
# 438| m438_2(unknown) = AliasedDefinition :
# 438| m438_3(unknown) = InitializeNonLocal :
# 438| m438_4(unknown) = Chi : total:m438_2, partial:m438_3
# 438| r438_5(glval<bool>) = VariableAddress[a] :
# 438| m438_6(bool) = InitializeParameter[a] : &:r438_5
# 438| r438_7(glval<int>) = VariableAddress[x] :
# 438| m438_8(int) = InitializeParameter[x] : &:r438_7
# 438| r438_9(glval<int>) = VariableAddress[y] :
# 438| m438_10(int) = InitializeParameter[y] : &:r438_9
# 439| r439_1(glval<int>) = VariableAddress[z] :
# 439| r439_2(glval<bool>) = VariableAddress[a] :
# 439| r439_3(bool) = Load[a] : &:r439_2, m438_6
# 439| v439_4(void) = ConditionalBranch : r439_3
#-----| False -> Block 3
#-----| True -> Block 2
# 439| Block 1
# 439| m439_5(int) = Phi : from 2:m439_12, from 3:m439_16
# 439| r439_6(glval<int>) = VariableAddress[#temp439:13] :
# 439| r439_7(int) = Load[#temp439:13] : &:r439_6, m439_5
# 439| m439_8(int) = Store[z] : &:r439_1, r439_7
# 440| v440_1(void) = NoOp :
# 438| v438_11(void) = ReturnVoid :
# 438| v438_12(void) = AliasedUse : m438_3
# 438| v438_13(void) = ExitFunction :
# 439| Block 2
# 439| r439_9(glval<int>) = VariableAddress[x] :
# 439| r439_10(int) = Load[x] : &:r439_9, m438_8
# 439| r439_11(glval<int>) = VariableAddress[#temp439:13] :
# 439| m439_12(int) = Store[#temp439:13] : &:r439_11, r439_10
#-----| Goto -> Block 1
# 439| Block 3
# 439| r439_13(glval<int>) = VariableAddress[y] :
# 439| r439_14(int) = Load[y] : &:r439_13, m438_10
# 439| r439_15(glval<int>) = VariableAddress[#temp439:13] :
# 439| m439_16(int) = Store[#temp439:13] : &:r439_15, r439_14
#-----| Goto -> Block 1

View File

@@ -434,3 +434,7 @@ int noreturnTest2(int x) {
}
return x;
}
void Conditional(bool a, int x, int y) {
int z = a ? x : y;
}

View File

@@ -2002,3 +2002,45 @@ ssa.cpp:
# 431| v431_8(void) = ReturnValue : &:r431_7, m435_4
# 431| v431_9(void) = AliasedUse : ~m?
# 431| v431_10(void) = ExitFunction :
# 438| void Conditional(bool, int, int)
# 438| Block 0
# 438| v438_1(void) = EnterFunction :
# 438| mu438_2(unknown) = AliasedDefinition :
# 438| mu438_3(unknown) = InitializeNonLocal :
# 438| r438_4(glval<bool>) = VariableAddress[a] :
# 438| m438_5(bool) = InitializeParameter[a] : &:r438_4
# 438| r438_6(glval<int>) = VariableAddress[x] :
# 438| m438_7(int) = InitializeParameter[x] : &:r438_6
# 438| r438_8(glval<int>) = VariableAddress[y] :
# 438| m438_9(int) = InitializeParameter[y] : &:r438_8
# 439| r439_1(glval<int>) = VariableAddress[z] :
# 439| r439_2(glval<bool>) = VariableAddress[a] :
# 439| r439_3(bool) = Load[a] : &:r439_2, m438_5
# 439| v439_4(void) = ConditionalBranch : r439_3
#-----| False -> Block 3
#-----| True -> Block 2
# 439| Block 1
# 439| m439_5(int) = Phi : from 2:m439_12, from 3:m439_16
# 439| r439_6(glval<int>) = VariableAddress[#temp439:13] :
# 439| r439_7(int) = Load[#temp439:13] : &:r439_6, m439_5
# 439| m439_8(int) = Store[z] : &:r439_1, r439_7
# 440| v440_1(void) = NoOp :
# 438| v438_10(void) = ReturnVoid :
# 438| v438_11(void) = AliasedUse : ~m?
# 438| v438_12(void) = ExitFunction :
# 439| Block 2
# 439| r439_9(glval<int>) = VariableAddress[x] :
# 439| r439_10(int) = Load[x] : &:r439_9, m438_7
# 439| r439_11(glval<int>) = VariableAddress[#temp439:13] :
# 439| m439_12(int) = Store[#temp439:13] : &:r439_11, r439_10
#-----| Goto -> Block 1
# 439| Block 3
# 439| r439_13(glval<int>) = VariableAddress[y] :
# 439| r439_14(int) = Load[y] : &:r439_13, m438_9
# 439| r439_15(glval<int>) = VariableAddress[#temp439:13] :
# 439| m439_16(int) = Store[#temp439:13] : &:r439_15, r439_14
#-----| Goto -> Block 1

View File

@@ -2002,3 +2002,45 @@ ssa.cpp:
# 431| v431_8(void) = ReturnValue : &:r431_7, m435_4
# 431| v431_9(void) = AliasedUse : ~m?
# 431| v431_10(void) = ExitFunction :
# 438| void Conditional(bool, int, int)
# 438| Block 0
# 438| v438_1(void) = EnterFunction :
# 438| mu438_2(unknown) = AliasedDefinition :
# 438| mu438_3(unknown) = InitializeNonLocal :
# 438| r438_4(glval<bool>) = VariableAddress[a] :
# 438| m438_5(bool) = InitializeParameter[a] : &:r438_4
# 438| r438_6(glval<int>) = VariableAddress[x] :
# 438| m438_7(int) = InitializeParameter[x] : &:r438_6
# 438| r438_8(glval<int>) = VariableAddress[y] :
# 438| m438_9(int) = InitializeParameter[y] : &:r438_8
# 439| r439_1(glval<int>) = VariableAddress[z] :
# 439| r439_2(glval<bool>) = VariableAddress[a] :
# 439| r439_3(bool) = Load[a] : &:r439_2, m438_5
# 439| v439_4(void) = ConditionalBranch : r439_3
#-----| False -> Block 3
#-----| True -> Block 2
# 439| Block 1
# 439| m439_5(int) = Phi : from 2:m439_12, from 3:m439_16
# 439| r439_6(glval<int>) = VariableAddress[#temp439:13] :
# 439| r439_7(int) = Load[#temp439:13] : &:r439_6, m439_5
# 439| m439_8(int) = Store[z] : &:r439_1, r439_7
# 440| v440_1(void) = NoOp :
# 438| v438_10(void) = ReturnVoid :
# 438| v438_11(void) = AliasedUse : ~m?
# 438| v438_12(void) = ExitFunction :
# 439| Block 2
# 439| r439_9(glval<int>) = VariableAddress[x] :
# 439| r439_10(int) = Load[x] : &:r439_9, m438_7
# 439| r439_11(glval<int>) = VariableAddress[#temp439:13] :
# 439| m439_12(int) = Store[#temp439:13] : &:r439_11, r439_10
#-----| Goto -> Block 1
# 439| Block 3
# 439| r439_13(glval<int>) = VariableAddress[y] :
# 439| r439_14(int) = Load[y] : &:r439_13, m438_9
# 439| r439_15(glval<int>) = VariableAddress[#temp439:13] :
# 439| m439_16(int) = Store[#temp439:13] : &:r439_15, r439_14
#-----| Goto -> Block 1

View File

@@ -13,7 +13,6 @@
| file://:0:0:0:0 | _Float64 |
| file://:0:0:0:0 | _Float64x |
| file://:0:0:0:0 | _Float128 |
| file://:0:0:0:0 | _Float128x |
| file://:0:0:0:0 | _Imaginary double |
| file://:0:0:0:0 | _Imaginary float |
| file://:0:0:0:0 | _Imaginary long double |

View File

@@ -33,7 +33,6 @@
| file://:0:0:0:0 | _Float64 | 8 |
| file://:0:0:0:0 | _Float64x | 16 |
| file://:0:0:0:0 | _Float128 | 16 |
| file://:0:0:0:0 | _Float128x | 32 |
| file://:0:0:0:0 | _Imaginary double | 8 |
| file://:0:0:0:0 | _Imaginary float | 4 |
| file://:0:0:0:0 | _Imaginary long double | 16 |

View File

@@ -15,7 +15,6 @@
| file://:0:0:0:0 | _Float64 | _Float64 |
| file://:0:0:0:0 | _Float64x | _Float64x |
| file://:0:0:0:0 | _Float128 | _Float128 |
| file://:0:0:0:0 | _Float128x | _Float128x |
| file://:0:0:0:0 | _Imaginary double | _Imaginary double |
| file://:0:0:0:0 | _Imaginary float | _Imaginary float |
| file://:0:0:0:0 | _Imaginary long double | _Imaginary long double |

View File

@@ -14,7 +14,6 @@
| _Float64 | BinaryFloatingPointType, RealNumberType | | | | |
| _Float64x | BinaryFloatingPointType, RealNumberType | | | | |
| _Float128 | BinaryFloatingPointType, RealNumberType | | | | |
| _Float128x | BinaryFloatingPointType, RealNumberType | | | | |
| _Imaginary double | BinaryFloatingPointType, ImaginaryNumberType | | | | |
| _Imaginary float | BinaryFloatingPointType, ImaginaryNumberType | | | | |
| _Imaginary long double | BinaryFloatingPointType, ImaginaryNumberType | | | | |

View File

@@ -1,2 +1,6 @@
| tests2.cpp:59:3:59:10 | call to snprintf | This 'call to snprintf' operation is limited to 13 bytes but the destination is only 0 bytes. |
| tests2.cpp:59:3:59:10 | call to snprintf | This 'call to snprintf' operation is limited to 13 bytes but the destination is only 2 bytes. |
| tests2.cpp:63:3:63:10 | call to snprintf | This 'call to snprintf' operation is limited to 13 bytes but the destination is only 0 bytes. |
| tests2.cpp:63:3:63:10 | call to snprintf | This 'call to snprintf' operation is limited to 13 bytes but the destination is only 3 bytes. |
| tests.c:43:3:43:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. |
| tests.c:46:3:46:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. |

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