Merge remote-tracking branch 'upstream/main' into cert-checks

This commit is contained in:
Geoffrey White
2025-11-21 18:40:40 +00:00
892 changed files with 69976 additions and 39807 deletions

3
.gitattributes vendored
View File

@@ -82,9 +82,6 @@
/csharp/paket.main.bzl linguist-generated=true /csharp/paket.main.bzl linguist-generated=true
/csharp/paket.main_extension.bzl linguist-generated=true /csharp/paket.main_extension.bzl linguist-generated=true
# ripunzip tool
/misc/ripunzip/ripunzip-* filter=lfs diff=lfs merge=lfs -text
# swift prebuilt resources # swift prebuilt resources
/swift/third_party/resources/*.zip filter=lfs diff=lfs merge=lfs -text /swift/third_party/resources/*.zip filter=lfs diff=lfs merge=lfs -text
/swift/third_party/resources/*.tar.zst filter=lfs diff=lfs merge=lfs -text /swift/third_party/resources/*.tar.zst filter=lfs diff=lfs merge=lfs -text

View File

@@ -1,74 +0,0 @@
name: Build runzip
on:
workflow_dispatch:
inputs:
ripunzip-version:
description: "what reference to checktout from google/runzip"
required: false
default: v2.0.2
openssl-version:
description: "what reference to checkout from openssl/openssl for Linux"
required: false
default: openssl-3.5.0
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-13, windows-2022]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v5
with:
repository: google/ripunzip
ref: ${{ inputs.ripunzip-version }}
# we need to avoid ripunzip dynamically linking into libssl
# see https://github.com/sfackler/rust-openssl/issues/183
- if: runner.os == 'Linux'
name: checkout openssl
uses: actions/checkout@v5
with:
repository: openssl/openssl
path: openssl
ref: ${{ inputs.openssl-version }}
- if: runner.os == 'Linux'
name: build and install openssl with fPIC
shell: bash
working-directory: openssl
run: |
./config -fPIC --prefix=$HOME/.local --openssldir=$HOME/.local/ssl
make -j $(nproc)
make install_sw -j $(nproc)
- if: runner.os == 'Linux'
name: build (linux)
shell: bash
run: |
env OPENSSL_LIB_DIR=$HOME/.local/lib64 OPENSSL_INCLUDE_DIR=$HOME/.local/include OPENSSL_STATIC=yes cargo build --release
mv target/release/ripunzip ripunzip-linux
- if: runner.os == 'Windows'
name: build (windows)
shell: bash
run: |
cargo build --release
mv target/release/ripunzip ripunzip-windows
- name: build (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
rustup target install x86_64-apple-darwin
rustup target install aarch64-apple-darwin
cargo build --target x86_64-apple-darwin --release
cargo build --target aarch64-apple-darwin --release
lipo -create -output ripunzip-macos \
-arch x86_64 target/x86_64-apple-darwin/release/ripunzip \
-arch arm64 target/aarch64-apple-darwin/release/ripunzip
- uses: actions/upload-artifact@v4
with:
name: ripunzip-${{ runner.os }}
path: ripunzip-*
- name: Check built binary
shell: bash
run: |
./ripunzip-* --version

View File

@@ -5,19 +5,29 @@
/actions/ @github/codeql-dynamic /actions/ @github/codeql-dynamic
/cpp/ @github/codeql-c-analysis /cpp/ @github/codeql-c-analysis
/csharp/ @github/codeql-csharp /csharp/ @github/codeql-csharp
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor /csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor @github/code-scanning-language-coverage
/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests @github/codeql-c-extractor /csharp/autobuilder/Semmle.Autobuild.Cpp.Tests @github/codeql-c-extractor @github/code-scanning-language-coverage
/go/ @github/codeql-go /go/ @github/codeql-go
/go/codeql-tools/ @github/codeql-go @github/code-scanning-language-coverage
/go/downgrades/ @github/codeql-go @github/code-scanning-language-coverage
/go/extractor/ @github/codeql-go @github/code-scanning-language-coverage
/go/extractor-smoke-test/ @github/codeql-go @github/code-scanning-language-coverage
/go/ql/test/extractor-tests/ @github/codeql-go @github/code-scanning-language-coverage
/java/ @github/codeql-java /java/ @github/codeql-java
/javascript/ @github/codeql-javascript /javascript/ @github/codeql-javascript
/javascript/extractor/ @github/codeql-javascript @github/code-scanning-language-coverage
/python/ @github/codeql-python /python/ @github/codeql-python
/python/extractor/ @github/codeql-python @github/code-scanning-language-coverage
/ql/ @github/codeql-ql-for-ql-reviewers /ql/ @github/codeql-ql-for-ql-reviewers
/ruby/ @github/codeql-ruby /ruby/ @github/codeql-ruby
/ruby/extractor/ @github/codeql-ruby @github/code-scanning-language-coverage
/rust/ @github/codeql-rust /rust/ @github/codeql-rust
/rust/extractor/ @github/codeql-rust @github/code-scanning-language-coverage
/shared/ @github/codeql-shared-libraries-reviewers /shared/ @github/codeql-shared-libraries-reviewers
/swift/ @github/codeql-swift /swift/ @github/codeql-swift
/swift/extractor/ @github/codeql-swift @github/code-scanning-language-coverage
/misc/codegen/ @github/codeql-swift /misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin /java/kotlin-extractor/ @github/codeql-kotlin @github/code-scanning-language-coverage
/java/ql/test-kotlin1/ @github/codeql-kotlin /java/ql/test-kotlin1/ @github/codeql-kotlin
/java/ql/test-kotlin2/ @github/codeql-kotlin /java/ql/test-kotlin2/ @github/codeql-kotlin

View File

@@ -269,24 +269,16 @@ go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//go/extractor:go.mod") go_deps.from_file(go_mod = "//go/extractor:go.mod")
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools") use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
lfs_archive = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_archive") ripunzip_archive = use_repo_rule("//misc/ripunzip:ripunzip.bzl", "ripunzip_archive")
lfs_archive( # go to https://github.com/GoogleChrome/ripunzip/releases to find latest version and corresponding sha256s
name = "ripunzip-linux", ripunzip_archive(
src = "//misc/ripunzip:ripunzip-Linux.zip", name = "ripunzip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel", sha256_linux = "ee0e8a957687a5dc3a66b2a4b25883bf762df4c9c07f0651af527a32a405054b",
) sha256_macos_arm = "8a88eea54eac232d162a72a42065e0429b82dbf4f05e9642915dff9d7a81f846",
sha256_macos_intel = "4457a18bfcc5feabe09f5ea3d1157128e07b4873392cb404a870e611924abf64",
lfs_archive( sha256_windows = "66d0c1375301bf5ab815348048f43b110631d3fa7200acd50d50a8ed8655ca62",
name = "ripunzip-windows", version = "2.0.3",
src = "//misc/ripunzip:ripunzip-Windows.zip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
)
lfs_archive(
name = "ripunzip-macos",
src = "//misc/ripunzip:ripunzip-macOS.zip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
) )
register_toolchains( register_toolchains(

View File

@@ -1,3 +1,7 @@
## 0.4.21
No user-facing changes.
## 0.4.20 ## 0.4.20
No user-facing changes. No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.20 lastReleaseVersion: 0.4.21

View File

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

View File

@@ -1,3 +1,7 @@
## 0.6.13
No user-facing changes.
## 0.6.12 ## 0.6.12
No user-facing changes. No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.6.12 lastReleaseVersion: 0.6.13

View File

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

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,3 @@
description: Support expanded compilation argument lists
compatibility: full
compilation_expanded_args.rel: delete

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: Fix decltype qualifier issue
compatibility: full

View File

@@ -1,9 +1,17 @@
## 6.0.1 ## 6.1.0
### New Features
* New predicates `getAnExpandedArgument` and `getExpandedArgument` were added to the `Compilation` class, yielding compilation arguments after expansion of response files.
### Bug Fixes ### Bug Fixes
* Improve performance of the range analysis in cases where it would otherwise take an exorbitant amount of time. * Improve performance of the range analysis in cases where it would otherwise take an exorbitant amount of time.
## 6.0.1
No user-facing changes.
## 6.0.0 ## 6.0.0
### Breaking Changes ### Breaking Changes

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The class `DataFlow::FieldContent` now covers both `union` and `struct`/`class` types. A new predicate `FieldContent.getAField` has been added to access the union members associated with the `FieldContent`. The old `FieldContent` has been renamed to `NonUnionFieldContent`.

View File

@@ -1,5 +1,3 @@
## 6.0.1 ## 6.0.1
### Bug Fixes No user-facing changes.
* Improve performance of the range analysis in cases where it would otherwise take an exorbitant amount of time.

View File

@@ -0,0 +1,9 @@
## 6.1.0
### New Features
* New predicates `getAnExpandedArgument` and `getExpandedArgument` were added to the `Compilation` class, yielding compilation arguments after expansion of response files.
### Bug Fixes
* Improve performance of the range analysis in cases where it would otherwise take an exorbitant amount of time.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 6.0.1 lastReleaseVersion: 6.1.0

View File

@@ -0,0 +1,9 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["", "", False, "tolower", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["std", "", False, "tolower", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["", "", False, "toupper", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["std", "", False, "toupper", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]

View File

@@ -0,0 +1,7 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["", "", False, "iconv", "", "", "Argument[**1]", "Argument[**3]", "value", "manual"]

View File

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

View File

@@ -94,6 +94,25 @@ class Compilation extends @compilation {
*/ */
string getArgument(int i) { compilation_args(this, i, result) } string getArgument(int i) { compilation_args(this, i, result) }
/**
* Gets an expanded argument passed to the extractor on this invocation.
*/
string getAnExpandedArgument() { result = this.getExpandedArgument(_) }
/**
* Gets the `i`th expanded argument passed to the extractor on this
* invocation.
*
* This is similar to `getArgument`, but for a `@someFile` argument, it
* includes the arguments from that file, rather than just taking the
* argument literally.
*/
string getExpandedArgument(int i) {
if exists(string arg | compilation_expanded_args(this, _, arg))
then compilation_expanded_args(this, i, result)
else result = this.getArgument(i)
}
/** /**
* Gets the total amount of CPU time spent processing all the files in the * Gets the total amount of CPU time spent processing all the files in the
* front-end and extractor. * front-end and extractor.

View File

@@ -171,12 +171,14 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* Gets the nth parameter of this function. There is no result for the * Gets the nth parameter of this function. There is no result for the
* implicit `this` parameter, and there is no `...` varargs pseudo-parameter. * implicit `this` parameter, and there is no `...` varargs pseudo-parameter.
*/ */
pragma[nomagic]
Parameter getParameter(int n) { params(unresolveElement(result), underlyingElement(this), n, _) } Parameter getParameter(int n) { params(unresolveElement(result), underlyingElement(this), n, _) }
/** /**
* Gets a parameter of this function. There is no result for the implicit * Gets a parameter of this function. There is no result for the implicit
* `this` parameter, and there is no `...` varargs pseudo-parameter. * `this` parameter, and there is no `...` varargs pseudo-parameter.
*/ */
pragma[nomagic]
Parameter getAParameter() { params(unresolveElement(result), underlyingElement(this), _, _) } Parameter getAParameter() { params(unresolveElement(result), underlyingElement(this), _, _) }
/** /**

View File

@@ -144,14 +144,14 @@ class NameQualifiableElement extends Element, @namequalifiableelement {
class NameQualifyingElement extends Element, @namequalifyingelement { class NameQualifyingElement extends Element, @namequalifyingelement {
/** /**
* Gets a name qualifier for which this is the qualifying namespace or * Gets a name qualifier for which this is the qualifying namespace or
* user-defined type. For example: class `X` is the * user-defined type, or decltype. For example: class `X` is the
* `NameQualifyingElement` and `X::` is the `NameQualifier`. * `NameQualifyingElement` and `X::` is the `NameQualifier`.
*/ */
NameQualifier getANameQualifier() { NameQualifier getANameQualifier() {
namequalifiers(unresolveElement(result), _, underlyingElement(this), _) namequalifiers(unresolveElement(result), _, underlyingElement(this), _)
} }
/** Gets the name of this namespace or user-defined type. */ /** Gets the name of this namespace, user-defined type, or decltype. */
string getName() { none() } string getName() { none() }
} }

View File

@@ -1146,7 +1146,7 @@ class DerivedType extends Type, @derivedtype {
* decltype(a) b; * decltype(a) b;
* ``` * ```
*/ */
class Decltype extends Type { class Decltype extends Type, NameQualifyingElement {
Decltype() { decltypes(underlyingElement(this), _, 0, _, _) } Decltype() { decltypes(underlyingElement(this), _, 0, _, _) }
override string getAPrimaryQlClass() { result = "Decltype" } override string getAPrimaryQlClass() { result = "Decltype" }
@@ -1187,7 +1187,7 @@ class Decltype extends Type {
override string toString() { result = "decltype(...)" } override string toString() { result = "decltype(...)" }
override string getName() { none() } override string getName() { result = "decltype(...)" }
override int getSize() { result = this.getBaseType().getSize() } override int getSize() { result = this.getBaseType().getSize() }
@@ -1247,7 +1247,7 @@ class TypeofType extends Type {
override string toString() { result = "typeof(...)" } override string toString() { result = "typeof(...)" }
override string getName() { none() } override string getName() { result = "typeof(...)" }
override int getSize() { result = this.getBaseType().getSize() } override int getSize() { result = this.getBaseType().getSize() }
@@ -1311,8 +1311,6 @@ class TypeofTypeType extends TypeofType {
Type getType() { type_operators(underlyingElement(this), unresolveElement(result), _, _) } Type getType() { type_operators(underlyingElement(this), unresolveElement(result), _, _) }
override string getAPrimaryQlClass() { result = "TypeofTypeType" } override string getAPrimaryQlClass() { result = "TypeofTypeType" }
override string toString() { result = "typeof(...)" }
} }
/** /**
@@ -1394,7 +1392,7 @@ class IntrinsicTransformedType extends Type {
override Type resolveTypedefs() { result = this.getBaseType().resolveTypedefs() } override Type resolveTypedefs() { result = this.getBaseType().resolveTypedefs() }
override string getName() { none() } override string getName() { result = this.getIntrinsicName() + "(...)" }
override int getSize() { result = this.getBaseType().getSize() } override int getSize() { result = this.getBaseType().getSize() }

View File

@@ -703,6 +703,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
) )
} }
pragma[nomagic]
override predicate comparesLt( override predicate comparesLt(
Cpp::Expr left, Cpp::Expr right, int k, boolean isLessThan, boolean testIsTrue Cpp::Expr left, Cpp::Expr right, int k, boolean isLessThan, boolean testIsTrue
) { ) {
@@ -713,6 +714,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
) )
} }
pragma[nomagic]
override predicate comparesLt(Cpp::Expr e, int k, boolean isLessThan, GuardValue value) { override predicate comparesLt(Cpp::Expr e, int k, boolean isLessThan, GuardValue value) {
exists(GuardValue partValue, GuardCondition part | exists(GuardValue partValue, GuardCondition part |
this.(Cpp::BinaryLogicalOperation) this.(Cpp::BinaryLogicalOperation)
@@ -738,6 +740,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
) )
} }
pragma[nomagic]
override predicate comparesEq( override predicate comparesEq(
Cpp::Expr left, Cpp::Expr right, int k, boolean areEqual, boolean testIsTrue Cpp::Expr left, Cpp::Expr right, int k, boolean areEqual, boolean testIsTrue
) { ) {
@@ -757,6 +760,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
) )
} }
pragma[nomagic]
override predicate comparesEq(Cpp::Expr e, int k, boolean areEqual, GuardValue value) { override predicate comparesEq(Cpp::Expr e, int k, boolean areEqual, GuardValue value) {
exists(GuardValue partValue, GuardCondition part | exists(GuardValue partValue, GuardCondition part |
this.(Cpp::BinaryLogicalOperation) this.(Cpp::BinaryLogicalOperation)

View File

@@ -656,6 +656,7 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain
* Normalize the `n`'th parameter of `f` by replacing template names * Normalize the `n`'th parameter of `f` by replacing template names
* with `class:N` (where `N` is the index of the template). * with `class:N` (where `N` is the index of the template).
*/ */
pragma[nomagic]
private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) { private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) {
// If there is a declaring type then we start by expanding the function templates // If there is a declaring type then we start by expanding the function templates
exists(Class template | exists(Class template |
@@ -727,6 +728,7 @@ private string getSignatureWithoutClassTemplateNames(
* - The `remaining` number of template arguments in `partiallyNormalizedSignature` * - The `remaining` number of template arguments in `partiallyNormalizedSignature`
* with their index in `nameArgs`. * with their index in `nameArgs`.
*/ */
pragma[nomagic]
private string getSignatureWithoutFunctionTemplateNames( private string getSignatureWithoutFunctionTemplateNames(
string partiallyNormalizedSignature, string typeArgs, string nameArgs, int remaining string partiallyNormalizedSignature, string typeArgs, string nameArgs, int remaining
) { ) {
@@ -770,6 +772,7 @@ private string getSignatureWithoutFunctionTemplateNames(
* ``` * ```
* In this case, `normalizedSignature` will be `"(const func:0 &,int,class:1,class:0 *)"`. * In this case, `normalizedSignature` will be `"(const func:0 &,int,class:1,class:0 *)"`.
*/ */
pragma[nomagic]
private predicate elementSpecWithArguments( private predicate elementSpecWithArguments(
string signature, string type, string name, string normalizedSignature, string typeArgs, string signature, string type, string name, string normalizedSignature, string typeArgs,
string nameArgs string nameArgs
@@ -789,6 +792,35 @@ private string getSignatureParameterName(string signature, string type, string n
) )
} }
/**
* Gets a `Function` identified by the `(namespace, type, name)` components.
*
* If `subtypes` is `true` then the result may be an override of the function
* identified by the components.
*/
pragma[nomagic]
private Function getFunction(string namespace, string type, boolean subtypes, string name) {
elementSpec(namespace, type, subtypes, name, _, _) and
(
funcHasQualifiedName(result, namespace, name) and
subtypes = false and
type = ""
or
exists(Class namedClass, Class classWithMethod |
hasClassAndName(classWithMethod, result, name) and
classHasQualifiedName(namedClass, namespace, type)
|
// member declared in the named type or a subtype of it
subtypes = true and
classWithMethod = namedClass.getADerivedClass*()
or
// member declared directly in the named type
subtypes = false and
classWithMethod = namedClass
)
)
}
/** /**
* Holds if the suffix containing the entries in `signature` starting at entry * Holds if the suffix containing the entries in `signature` starting at entry
* `i` matches the suffix containing the parameters of `func` starting at entry `i`. * `i` matches the suffix containing the parameters of `func` starting at entry `i`.
@@ -812,13 +844,17 @@ private string getSignatureParameterName(string signature, string type, string n
* is `func:n` then the signature name is compared with the `n`'th name * is `func:n` then the signature name is compared with the `n`'th name
* in `name`. * in `name`.
*/ */
private predicate signatureMatches(Function func, string signature, string type, string name, int i) { pragma[nomagic]
private predicate signatureMatches(
Function func, string namespace, string signature, string type, string name, int i
) {
func = getFunction(namespace, type, _, name) and
exists(string s | exists(string s |
s = getSignatureParameterName(signature, type, name, i) and s = getSignatureParameterName(signature, type, name, i) and
s = getParameterTypeName(func, i) s = getParameterTypeName(func, i)
) and ) and
if exists(getParameterTypeName(func, i + 1)) if exists(getParameterTypeName(func, i + 1))
then signatureMatches(func, signature, type, name, i + 1) then signatureMatches(func, namespace, signature, type, name, i + 1)
else i = count(signature.indexOf(",")) else i = count(signature.indexOf(","))
} }
@@ -833,7 +869,7 @@ module ExternalFlowDebug {
* *
* Exposed for testing purposes. * Exposed for testing purposes.
*/ */
predicate signatureMatches_debug = signatureMatches/5; predicate signatureMatches_debug = signatureMatches/6;
/** /**
* INTERNAL: Do not use. * INTERNAL: Do not use.
@@ -883,6 +919,7 @@ private predicate parseParens(string s, string betweenParens) { s = "(" + betwee
* - `signatureWithoutParens` equals `signature`, but with the surrounding * - `signatureWithoutParens` equals `signature`, but with the surrounding
* parentheses removed. * parentheses removed.
*/ */
pragma[nomagic]
private predicate elementSpecWithArguments0( private predicate elementSpecWithArguments0(
string signature, string type, string name, string signatureWithoutParens, string typeArgs, string signature, string type, string name, string signatureWithoutParens, string typeArgs,
string nameArgs string nameArgs
@@ -909,7 +946,7 @@ private predicate elementSpecMatchesSignature(
) { ) {
elementSpec(namespace, pragma[only_bind_into](type), subtypes, pragma[only_bind_into](name), elementSpec(namespace, pragma[only_bind_into](type), subtypes, pragma[only_bind_into](name),
pragma[only_bind_into](signature), _) and pragma[only_bind_into](signature), _) and
signatureMatches(func, signature, type, name, 0) signatureMatches(func, namespace, signature, type, name, 0)
} }
/** /**
@@ -953,7 +990,7 @@ private predicate funcHasQualifiedName(Function func, string namespace, string n
* Holds if `namedClass` is in namespace `namespace` and has * Holds if `namedClass` is in namespace `namespace` and has
* name `type` (excluding any template parameters). * name `type` (excluding any template parameters).
*/ */
bindingset[type, namespace] bindingset[type]
pragma[inline_late] pragma[inline_late]
private predicate classHasQualifiedName(Class namedClass, string namespace, string type) { private predicate classHasQualifiedName(Class namedClass, string namespace, string type) {
exists(string typeWithoutArgs | exists(string typeWithoutArgs |
@@ -969,17 +1006,14 @@ private predicate classHasQualifiedName(Class namedClass, string namespace, stri
* are also returned. * are also returned.
* 3. The element has name `name` * 3. The element has name `name`
* 4. If `signature` is non-empty, then the element has a list of parameter types described by `signature`. * 4. If `signature` is non-empty, then the element has a list of parameter types described by `signature`.
*
* NOTE: `namespace` is currently not used (since we don't properly extract modules yet).
*/ */
pragma[nomagic] pragma[nomagic]
private Element interpretElement0( private Element interpretElement0(
string namespace, string type, boolean subtypes, string name, string signature string namespace, string type, boolean subtypes, string name, string signature
) { ) {
result = getFunction(namespace, type, subtypes, name) and
( (
// Non-member functions // Non-member functions
funcHasQualifiedName(result, namespace, name) and
subtypes = false and
type = "" and type = "" and
( (
elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature) elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature)
@@ -989,52 +1023,36 @@ private Element interpretElement0(
) )
or or
// Member functions // Member functions
exists(Class namedClass, Class classWithMethod | elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature)
hasClassAndName(classWithMethod, result, name) and
classHasQualifiedName(namedClass, namespace, type)
|
(
elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature)
or
signature = "" and
elementSpec(namespace, type, subtypes, name, "", _)
) and
(
// member declared in the named type or a subtype of it
subtypes = true and
classWithMethod = namedClass.getADerivedClass*()
or
// member declared directly in the named type
subtypes = false and
classWithMethod = namedClass
)
)
or or
elementSpec(namespace, type, subtypes, name, signature, _) and
// Member variables
signature = "" and signature = "" and
exists(Class namedClass, Class classWithMember, MemberVariable member | elementSpec(namespace, type, subtypes, name, signature, _)
member.getName() = name and
member = classWithMember.getAMember() and
namedClass.hasQualifiedName(namespace, type) and
result = member
|
// field declared in the named type or a subtype of it (or an extension of any)
subtypes = true and
classWithMember = namedClass.getADerivedClass*()
or
// field declared directly in the named type (or an extension of it)
subtypes = false and
classWithMember = namedClass
)
or
// Global or namespace variables
elementSpec(namespace, type, subtypes, name, signature, _) and
signature = "" and
type = "" and
subtypes = false and
result = any(GlobalOrNamespaceVariable v | v.hasQualifiedName(namespace, name))
) )
or
// Member variables
elementSpec(namespace, type, subtypes, name, signature, _) and
signature = "" and
exists(Class namedClass, Class classWithMember, MemberVariable member |
member.getName() = name and
member = classWithMember.getAMember() and
namedClass.hasQualifiedName(namespace, type) and
result = member
|
// field declared in the named type or a subtype of it (or an extension of any)
subtypes = true and
classWithMember = namedClass.getADerivedClass*()
or
// field declared directly in the named type (or an extension of it)
subtypes = false and
classWithMember = namedClass
)
or
// Global or namespace variables
elementSpec(namespace, type, subtypes, name, signature, _) and
signature = "" and
type = "" and
subtypes = false and
result = any(GlobalOrNamespaceVariable v | v.hasQualifiedName(namespace, name))
} }
cached cached

View File

@@ -750,6 +750,16 @@ class SizeofPackTypeOperator extends SizeofPackOperator {
*/ */
class SizeofOperator extends Expr, @runtime_sizeof { class SizeofOperator extends Expr, @runtime_sizeof {
override int getPrecedence() { result = 16 } override int getPrecedence() { result = 16 }
/**
* Gets the contained type of this `sizeof`. For example,
* the result is `int` in both cases below:
* ```
* sizeof(int);
* sizeof(42);
* ```
*/
Type getTypeOperand() { none() } // overridden in subclasses
} }
/** /**
@@ -766,6 +776,8 @@ class SizeofExprOperator extends SizeofOperator {
/** Gets the contained expression. */ /** Gets the contained expression. */
Expr getExprOperand() { result = this.getChild(0) } Expr getExprOperand() { result = this.getChild(0) }
override Type getTypeOperand() { result = this.getExprOperand().getType() }
override string toString() { result = "sizeof(<expr>)" } override string toString() { result = "sizeof(<expr>)" }
override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() } override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() }
@@ -784,8 +796,7 @@ class SizeofTypeOperator extends SizeofOperator {
override string getAPrimaryQlClass() { result = "SizeofTypeOperator" } override string getAPrimaryQlClass() { result = "SizeofTypeOperator" }
/** Gets the contained type. */ override Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
override string toString() { result = "sizeof(" + this.getTypeOperand().getName() + ")" } override string toString() { result = "sizeof(" + this.getTypeOperand().getName() + ")" }
@@ -842,6 +853,16 @@ class AlignofTypeOperator extends AlignofOperator {
*/ */
class DatasizeofOperator extends Expr, @datasizeof { class DatasizeofOperator extends Expr, @datasizeof {
override int getPrecedence() { result = 16 } override int getPrecedence() { result = 16 }
/**
* Gets the contained type of this `__datasizeof`. For example,
* the result is `int` in both cases below:
* ```
* __datasizeof(int);
* __datasizeof(42);
* ```
*/
Type getTypeOperand() { none() }
} }
/** /**
@@ -855,6 +876,8 @@ class DatasizeofExprOperator extends DatasizeofOperator {
/** Gets the contained expression. */ /** Gets the contained expression. */
Expr getExprOperand() { result = this.getChild(0) } Expr getExprOperand() { result = this.getChild(0) }
override Type getTypeOperand() { result = this.getExprOperand().getType() }
override string toString() { result = "__datasizeof(<expr>)" } override string toString() { result = "__datasizeof(<expr>)" }
override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() } override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() }
@@ -870,8 +893,7 @@ class DatasizeofTypeOperator extends DatasizeofOperator {
override string getAPrimaryQlClass() { result = "DatasizeofTypeOperator" } override string getAPrimaryQlClass() { result = "DatasizeofTypeOperator" }
/** Gets the contained type. */ override Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
override string toString() { result = "__datasizeof(" + this.getTypeOperand().getName() + ")" } override string toString() { result = "__datasizeof(" + this.getTypeOperand().getName() + ")" }

View File

@@ -861,6 +861,10 @@ predicate jumpStep(Node n1, Node n2) {
n2.(FlowSummaryNode).getSummaryNode()) n2.(FlowSummaryNode).getSummaryNode())
} }
bindingset[c]
pragma[inline_late]
private int getIndirectionIndexLate(Content c) { result = c.getIndirectionIndex() }
/** /**
* Holds if data can flow from `node1` to `node2` via an assignment to `f`. * Holds if data can flow from `node1` to `node2` via an assignment to `f`.
* Thus, `node2` references an object with a field `f` that contains the * Thus, `node2` references an object with a field `f` that contains the
@@ -873,23 +877,17 @@ predicate jumpStep(Node n1, Node n2) {
predicate storeStepImpl(Node node1, Content c, Node node2, boolean certain) { predicate storeStepImpl(Node node1, Content c, Node node2, boolean certain) {
exists( exists(
PostFieldUpdateNode postFieldUpdate, int indirectionIndex1, int numberOfLoads, PostFieldUpdateNode postFieldUpdate, int indirectionIndex1, int numberOfLoads,
StoreInstruction store StoreInstruction store, FieldContent fc
| |
postFieldUpdate = node2 and postFieldUpdate = node2 and
nodeHasInstruction(node1, store, pragma[only_bind_into](indirectionIndex1)) and fc = c and
nodeHasInstruction(node1, pragma[only_bind_into](store),
pragma[only_bind_into](indirectionIndex1)) and
postFieldUpdate.getIndirectionIndex() = 1 and postFieldUpdate.getIndirectionIndex() = 1 and
numberOfLoadsFromOperand(postFieldUpdate.getFieldAddress(), numberOfLoadsFromOperand(postFieldUpdate.getFieldAddress(),
store.getDestinationAddressOperand(), numberOfLoads, certain) store.getDestinationAddressOperand(), numberOfLoads, certain) and
| fc.getAField() = postFieldUpdate.getUpdatedField() and
exists(FieldContent fc | fc = c | getIndirectionIndexLate(fc) = 1 + indirectionIndex1 + numberOfLoads
fc.getField() = postFieldUpdate.getUpdatedField() and
fc.getIndirectionIndex() = 1 + indirectionIndex1 + numberOfLoads
)
or
exists(UnionContent uc | uc = c |
uc.getAField() = postFieldUpdate.getUpdatedField() and
uc.getIndirectionIndex() = 1 + indirectionIndex1 + numberOfLoads
)
) )
or or
// models-as-data summarized flow // models-as-data summarized flow
@@ -965,22 +963,17 @@ predicate nodeHasInstruction(Node node, Instruction instr, int indirectionIndex)
* `node2`. * `node2`.
*/ */
predicate readStep(Node node1, ContentSet c, Node node2) { predicate readStep(Node node1, ContentSet c, Node node2) {
exists(FieldAddress fa1, Operand operand, int numberOfLoads, int indirectionIndex2 | exists(
FieldAddress fa1, Operand operand, int numberOfLoads, int indirectionIndex2, FieldContent fc
|
fc = c and
nodeHasOperand(node2, operand, indirectionIndex2) and nodeHasOperand(node2, operand, indirectionIndex2) and
// The `1` here matches the `node2.getIndirectionIndex() = 1` conjunct // The `1` here matches the `node2.getIndirectionIndex() = 1` conjunct
// in `storeStep`. // in `storeStep`.
nodeHasOperand(node1, fa1.getObjectAddressOperand(), 1) and nodeHasOperand(node1, fa1.getObjectAddressOperand(), 1) and
numberOfLoadsFromOperand(fa1, operand, numberOfLoads, _) numberOfLoadsFromOperand(fa1, operand, numberOfLoads, _) and
| fc.getAField() = fa1.getField() and
exists(FieldContent fc | fc = c | getIndirectionIndexLate(fc) = indirectionIndex2 + numberOfLoads
fc.getField() = fa1.getField() and
fc.getIndirectionIndex() = indirectionIndex2 + numberOfLoads
)
or
exists(UnionContent uc | uc = c |
uc.getAField() = fa1.getField() and
uc.getIndirectionIndex() = indirectionIndex2 + numberOfLoads
)
) )
or or
// models-as-data summarized flow // models-as-data summarized flow
@@ -1574,7 +1567,7 @@ pragma[inline]
ContentApprox getContentApprox(Content c) { ContentApprox getContentApprox(Content c) {
exists(string prefix, Field f | exists(string prefix, Field f |
prefix = result.(FieldApproxContent).getPrefix() and prefix = result.(FieldApproxContent).getPrefix() and
f = c.(FieldContent).getField() and f = c.(NonUnionFieldContent).getField() and
fieldHasApproxName(f, prefix) fieldHasApproxName(f, prefix)
) )
or or

View File

@@ -2093,8 +2093,8 @@ private Field getAFieldWithSize(Union u, int bytes) {
cached cached
private newtype TContent = private newtype TContent =
TFieldContent(Field f, int indirectionIndex) { TNonUnionContent(Field f, int indirectionIndex) {
// the indirection index for field content starts at 1 (because `TFieldContent` is thought of as // the indirection index for field content starts at 1 (because `TNonUnionContent` is thought of as
// the address of the field, `FieldAddress` in the IR). // the address of the field, `FieldAddress` in the IR).
indirectionIndex = [1 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and indirectionIndex = [1 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and
// Reads and writes of union fields are tracked using `UnionContent`. // Reads and writes of union fields are tracked using `UnionContent`.
@@ -2124,14 +2124,14 @@ private newtype TContent =
*/ */
class Content extends TContent { class Content extends TContent {
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */
abstract string toString(); string toString() { none() } // overridden in subclasses
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0 path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
} }
/** Gets the indirection index of this `Content`. */ /** Gets the indirection index of this `Content`. */
abstract int getIndirectionIndex(); int getIndirectionIndex() { none() } // overridden in subclasses
/** /**
* INTERNAL: Do not use. * INTERNAL: Do not use.
@@ -2142,7 +2142,7 @@ class Content extends TContent {
* For example, a write to a field `f` implies that any content of * For example, a write to a field `f` implies that any content of
* the form `*f` is also cleared. * the form `*f` is also cleared.
*/ */
abstract predicate impliesClearOf(Content c); predicate impliesClearOf(Content c) { none() } // overridden in subclasses
} }
/** /**
@@ -2162,22 +2162,42 @@ private module ContentStars {
private import ContentStars private import ContentStars
/** A reference through a non-union instance field. */ private class TFieldContent = TNonUnionContent or TUnionContent;
/**
* A `Content` that references a `Field`. This may be a field of a `struct`,
* `class`, or `union`. In the case of a `union` there may be multiple fields
* associated with the same `Content`.
*/
class FieldContent extends Content, TFieldContent { class FieldContent extends Content, TFieldContent {
/** Gets a `Field` of this `Content`. */
Field getAField() { none() }
/**
* Gets the field associated with this `Content`, if a unique one exists.
*/
final Field getField() { result = unique( | | this.getAField()) }
override int getIndirectionIndex() { none() } // overridden in subclasses
override string toString() { none() } // overridden in subclasses
override predicate impliesClearOf(Content c) { none() } // overridden in subclasses
}
/** A reference through a non-union instance field. */
class NonUnionFieldContent extends FieldContent, TNonUnionContent {
private Field f; private Field f;
private int indirectionIndex; private int indirectionIndex;
FieldContent() { this = TFieldContent(f, indirectionIndex) } NonUnionFieldContent() { this = TNonUnionContent(f, indirectionIndex) }
override string toString() { result = contentStars(this) + f.toString() } override string toString() { result = contentStars(this) + f.toString() }
Field getField() { result = f } override Field getAField() { result = f }
/** Gets the indirection index of this `FieldContent`. */ /** Gets the indirection index of this `FieldContent`. */
pragma[inline] override int getIndirectionIndex() { result = indirectionIndex }
override int getIndirectionIndex() {
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
}
override predicate impliesClearOf(Content c) { override predicate impliesClearOf(Content c) {
exists(FieldContent fc | exists(FieldContent fc |
@@ -2191,7 +2211,7 @@ class FieldContent extends Content, TFieldContent {
} }
/** A reference through an instance field of a union. */ /** A reference through an instance field of a union. */
class UnionContent extends Content, TUnionContent { class UnionContent extends FieldContent, TUnionContent {
private Union u; private Union u;
private int indirectionIndex; private int indirectionIndex;
private int bytes; private int bytes;
@@ -2201,16 +2221,13 @@ class UnionContent extends Content, TUnionContent {
override string toString() { result = contentStars(this) + u.toString() } override string toString() { result = contentStars(this) + u.toString() }
/** Gets a field of the underlying union of this `UnionContent`, if any. */ /** Gets a field of the underlying union of this `UnionContent`, if any. */
Field getAField() { result = u.getAField() and getFieldSize(result) = bytes } override Field getAField() { result = u.getAField() and getFieldSize(result) = bytes }
/** Gets the underlying union of this `UnionContent`. */ /** Gets the underlying union of this `UnionContent`. */
Union getUnion() { result = u } Union getUnion() { result = u }
/** Gets the indirection index of this `UnionContent`. */ /** Gets the indirection index of this `UnionContent`. */
pragma[inline] override int getIndirectionIndex() { result = indirectionIndex }
override int getIndirectionIndex() {
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
}
override predicate impliesClearOf(Content c) { override predicate impliesClearOf(Content c) {
exists(UnionContent uc | exists(UnionContent uc |
@@ -2234,10 +2251,7 @@ class ElementContent extends Content, TElementContent {
ElementContent() { this = TElementContent(indirectionIndex) } ElementContent() { this = TElementContent(indirectionIndex) }
pragma[inline] override int getIndirectionIndex() { result = indirectionIndex }
override int getIndirectionIndex() {
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
}
override predicate impliesClearOf(Content c) { none() } override predicate impliesClearOf(Content c) { none() }

View File

@@ -12,8 +12,8 @@ import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.NonThrowing import semmle.code.cpp.models.interfaces.NonThrowing
/** /**
* The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant * The standard functions `memcpy`, `memmove` and `bcopy`; and variants such as
* `__builtin___memcpy_chk`. * `__builtin___memcpy_chk` and `__builtin___memmove_chk`.
*/ */
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction, private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction,
AliasFunction, NonCppThrowingFunction AliasFunction, NonCppThrowingFunction
@@ -27,7 +27,9 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
// bcopy(src, dest, num) // bcopy(src, dest, num)
// mempcpy(dest, src, num) // mempcpy(dest, src, num)
// memccpy(dest, src, c, n) // memccpy(dest, src, c, n)
this.hasGlobalName(["bcopy", mempcpy(), "memccpy", "__builtin___memcpy_chk"]) this.hasGlobalName([
"bcopy", mempcpy(), "memccpy", "__builtin___memcpy_chk", "__builtin___memmove_chk"
])
} }
/** /**

View File

@@ -19,7 +19,8 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
this.hasGlobalOrStdName("wmemset") this.hasGlobalOrStdName("wmemset")
or or
this.hasGlobalName([ this.hasGlobalName([
bzero(), "__builtin_memset", "__builtin_memset_chk", "RtlZeroMemory", "RtlSecureZeroMemory" bzero(), "__builtin_memset", "__builtin_memset_chk", "__builtin___memset_chk",
"RtlZeroMemory", "RtlSecureZeroMemory"
]) ])
} }
@@ -32,7 +33,7 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
or or
this.hasGlobalOrStdName("wmemset") this.hasGlobalOrStdName("wmemset")
or or
this.hasGlobalName(["__builtin_memset", "__builtin_memset_chk"]) this.hasGlobalName(["__builtin_memset", "__builtin_memset_chk", "__builtin___memset_chk"])
) and ) and
result = 1 result = 1
} }

View File

@@ -30,7 +30,9 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
"_mbsncat", // _mbsncat(dst, src, max_amount) "_mbsncat", // _mbsncat(dst, src, max_amount)
"_mbsncat_l", // _mbsncat_l(dst, src, max_amount, locale) "_mbsncat_l", // _mbsncat_l(dst, src, max_amount, locale)
"_mbsnbcat", // _mbsnbcat(dest, src, count) "_mbsnbcat", // _mbsnbcat(dest, src, count)
"_mbsnbcat_l" // _mbsnbcat_l(dest, src, count, locale) "_mbsnbcat_l", // _mbsnbcat_l(dest, src, count, locale)
"__builtin___strcat_chk", // __builtin___strcat_chk (dest, src, magic)
"__builtin___strncat_chk" // __builtin___strncat_chk (dest, src, max_amount, magic)
]) ])
} }
@@ -56,7 +58,7 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
( (
this.getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and this.getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l", "__builtin___strncat_chk"] and
input.isParameter(2) input.isParameter(2)
or or
this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and

View File

@@ -36,7 +36,11 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
"_mbsnbcpy", // _mbsnbcpy(dest, src, max_amount) "_mbsnbcpy", // _mbsnbcpy(dest, src, max_amount)
"stpcpy", // stpcpy(dest, src) "stpcpy", // stpcpy(dest, src)
"stpncpy", // stpncpy(dest, src, max_amount) "stpncpy", // stpncpy(dest, src, max_amount)
"strlcpy" // strlcpy(dst, src, dst_size) "strlcpy", // strlcpy(dst, src, dst_size)
"__builtin___strcpy_chk", // __builtin___strcpy_chk (dest, src, magic)
"__builtin___stpcpy_chk", // __builtin___stpcpy_chk (dest, src, magic)
"__builtin___stpncpy_chk", // __builtin___stpncpy_chk(dest, src, max_amount, magic)
"__builtin___strncpy_chk" // __builtin___strncpy_chk (dest, src, max_amount, magic)
]) ])
or or
( (

View File

@@ -592,7 +592,7 @@ private module BoundsEstimate {
not exists(def.getAPhiInput(v)) and not exists(def.getAPhiInput(v)) and
// If there's different `access`es, then they refer to the same variable // If there's different `access`es, then they refer to the same variable
// with the same lower bounds. Hence adding these guards make no sense (the // with the same lower bounds. Hence adding these guards make no sense (the
// implementation will take the union but they'll be removed by // implementation will take the union, but they'll be removed by
// deduplication). Hence we use `max` as an approximation. // deduplication). Hence we use `max` as an approximation.
result = result =
max(VariableAccess access | isGuardPhiWithBound(def, v, access) | nrOfBoundsExpr(access)) max(VariableAccess access | isGuardPhiWithBound(def, v, access) | nrOfBoundsExpr(access))
@@ -624,8 +624,13 @@ private module BoundsEstimate {
* Gets the number of bounds for `def` when `def` is an NE phi node for the * Gets the number of bounds for `def` when `def` is an NE phi node for the
* variable `v`. * variable `v`.
*/ */
private float nrOfBoundsNEPhi(RangeSsaDefinition def, StackVariable v) { language[monotonicAggregates]
exists(VariableAccess access | isNEPhi(v, def, access, _) and result = nrOfBoundsExpr(access)) float nrOfBoundsNEPhi(RangeSsaDefinition def, StackVariable v) {
// If there's different `access`es, then they refer to the same variable
// with the same lower bounds. Hence adding these guards make no sense (the
// implementation will take the union, but they'll be removed by
// deduplication). Hence we use `max` as an approximation.
result = max(VariableAccess access | isNEPhi(v, def, access, _) | nrOfBoundsExpr(access))
or or
def.isPhiNode(v) and def.isPhiNode(v) and
not isNEPhi(v, def, _, _) and not isNEPhi(v, def, _, _) and
@@ -636,11 +641,14 @@ private module BoundsEstimate {
* Gets the number of bounds for `def` when `def` is an unsupported guard phi * Gets the number of bounds for `def` when `def` is an unsupported guard phi
* node for the variable `v`. * node for the variable `v`.
*/ */
language[monotonicAggregates]
private float nrOfBoundsUnsupportedGuardPhi(RangeSsaDefinition def, StackVariable v) { private float nrOfBoundsUnsupportedGuardPhi(RangeSsaDefinition def, StackVariable v) {
exists(VariableAccess access | // If there's different `access`es, then they refer to the same variable
isUnsupportedGuardPhi(v, def, access) and // with the same lower bounds. Hence adding these guards make no sense (the
result = nrOfBoundsExpr(access) // implementation will take the union, but they'll be removed by
) // deduplication). Hence we use `max` as an approximation.
result =
max(VariableAccess access | isUnsupportedGuardPhi(v, def, access) | nrOfBoundsExpr(access))
or or
def.isPhiNode(v) and def.isPhiNode(v) and
not isUnsupportedGuardPhi(v, def, _) and not isUnsupportedGuardPhi(v, def, _) and
@@ -701,7 +709,7 @@ private module BoundsEstimate {
* ``` * ```
* the actual number of bounds for `y` is 1. However, the estimate will be 4 * the actual number of bounds for `y` is 1. However, the estimate will be 4
* as the conditional assignment to `x` gives two bounds for `x` on the last * as the conditional assignment to `x` gives two bounds for `x` on the last
* line and the addition gives 2 * 2 bounds. There are two sources of anncuracies: * line and the addition gives 2 * 2 bounds. There are two sources of inaccuracies:
* *
* 1. Without tracking the lower bounds we can't see that `x` is assigned a * 1. Without tracking the lower bounds we can't see that `x` is assigned a
* value that is equal to its lower bound. * value that is equal to its lower bound.

View File

@@ -47,6 +47,19 @@ compilation_args(
string arg : string ref string arg : string ref
); );
/**
* The expanded arguments that were passed to the extractor for a
* compiler invocation. This is similar to `compilation_args`, but
* for a `@someFile` argument, it includes the arguments from that
* file, rather than just taking the argument literally.
*/
#keyset[id, num]
compilation_expanded_args(
int id : @compilation ref,
int num : int ref,
string arg : string ref
);
/** /**
* Optionally, record the build mode for each compilation. * Optionally, record the build mode for each compilation.
*/ */
@@ -1327,7 +1340,8 @@ specialnamequalifyingelements(
@namequalifiableelement = @expr | @namequalifier; @namequalifiableelement = @expr | @namequalifier;
@namequalifyingelement = @namespace @namequalifyingelement = @namespace
| @specialnamequalifyingelement | @specialnamequalifyingelement
| @usertype; | @usertype
| @decltype;
namequalifiers( namequalifiers(
unique int id: @namequalifier, unique int id: @namequalifier,

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: Support expanded compilation argument lists
compatibility: backwards

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Fix decltype qualifier issue
compatibility: full

View File

@@ -1,3 +1,7 @@
## 1.5.4
No user-facing changes.
## 1.5.3 ## 1.5.3
No user-facing changes. No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.5.3 lastReleaseVersion: 1.5.4

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries name: codeql/cpp-queries
version: 1.5.4-dev version: 1.5.5-dev
groups: groups:
- cpp - cpp
- queries - queries

View File

@@ -190,7 +190,7 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Cpp::Lo
predicate isRelevantType(Type t) { any() } predicate isRelevantType(Type t) { any() }
Type getUnderlyingContentType(DataFlow::ContentSet c) { Type getUnderlyingContentType(DataFlow::ContentSet c) {
result = c.(DataFlow::FieldContent).getField().getUnspecifiedType() or result = c.(DataFlow::NonUnionFieldContent).getField().getUnspecifiedType() or
result = c.(DataFlow::UnionContent).getUnion().getUnspecifiedType() result = c.(DataFlow::UnionContent).getUnion().getUnspecifiedType()
} }
@@ -340,12 +340,7 @@ private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputS
) )
} }
predicate isField(DataFlow::ContentSet cs) { predicate isField(DataFlow::ContentSet cs) { cs.isSingleton(any(DataFlow::FieldContent fc)) }
exists(DataFlow::Content c | cs.isSingleton(c) |
c instanceof DataFlow::FieldContent or
c instanceof DataFlow::UnionContent
)
}
predicate isCallback(DataFlow::ContentSet c) { none() } predicate isCallback(DataFlow::ContentSet c) { none() }

View File

@@ -7988,6 +7988,26 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
| taint.cpp:841:21:841:35 | call to indirect_source | taint.cpp:843:16:843:17 | fp | | | taint.cpp:841:21:841:35 | call to indirect_source | taint.cpp:843:16:843:17 | fp | |
| taint.cpp:842:11:842:12 | ref arg fp | taint.cpp:843:16:843:17 | fp | | | taint.cpp:842:11:842:12 | ref arg fp | taint.cpp:843:16:843:17 | fp | |
| taint.cpp:842:15:842:16 | | taint.cpp:842:11:842:12 | ref arg fp | TAINT | | taint.cpp:842:15:842:16 | | taint.cpp:842:11:842:12 | ref arg fp | TAINT |
| taint.cpp:851:10:851:15 | call to source | taint.cpp:852:18:852:18 | s | |
| taint.cpp:851:10:851:15 | call to source | taint.cpp:854:18:854:18 | s | |
| taint.cpp:852:10:852:16 | call to toupper | taint.cpp:853:7:853:7 | u | |
| taint.cpp:854:10:854:16 | call to tolower | taint.cpp:855:7:855:7 | l | |
| taint.cpp:861:24:861:27 | size | taint.cpp:866:16:866:19 | size | |
| taint.cpp:862:12:862:26 | call to indirect_source | taint.cpp:866:12:866:12 | s | |
| taint.cpp:863:7:863:9 | out | taint.cpp:864:12:864:14 | out | |
| taint.cpp:864:12:864:14 | out | taint.cpp:866:23:866:23 | p | |
| taint.cpp:864:12:864:14 | out | taint.cpp:867:8:867:8 | p | |
| taint.cpp:865:9:865:16 | size_out | taint.cpp:866:27:866:34 | size_out | |
| taint.cpp:866:11:866:12 | ref arg & ... | taint.cpp:866:12:866:12 | s [inner post update] | |
| taint.cpp:866:12:866:12 | s | taint.cpp:866:11:866:12 | & ... | |
| taint.cpp:866:15:866:19 | ref arg & ... | taint.cpp:866:16:866:19 | size [inner post update] | |
| taint.cpp:866:16:866:19 | size | taint.cpp:866:15:866:19 | & ... | |
| taint.cpp:866:22:866:23 | ref arg & ... | taint.cpp:866:23:866:23 | p [inner post update] | |
| taint.cpp:866:22:866:23 | ref arg & ... | taint.cpp:867:8:867:8 | p | |
| taint.cpp:866:23:866:23 | p | taint.cpp:866:22:866:23 | & ... | |
| taint.cpp:866:26:866:34 | ref arg & ... | taint.cpp:866:27:866:34 | size_out [inner post update] | |
| taint.cpp:866:27:866:34 | size_out | taint.cpp:866:26:866:34 | & ... | |
| taint.cpp:867:8:867:8 | p | taint.cpp:867:7:867:8 | * ... | TAINT |
| thread.cpp:10:27:10:27 | s | thread.cpp:10:27:10:27 | s | | | thread.cpp:10:27:10:27 | s | thread.cpp:10:27:10:27 | s | |
| thread.cpp:10:27:10:27 | s | thread.cpp:11:8:11:8 | s | | | thread.cpp:10:27:10:27 | s | thread.cpp:11:8:11:8 | s | |
| thread.cpp:14:26:14:26 | s | thread.cpp:15:8:15:8 | s | | | thread.cpp:14:26:14:26 | s | thread.cpp:15:8:15:8 | s | |

View File

@@ -842,4 +842,27 @@ int f7(void)
fprintf(fp, ""); fprintf(fp, "");
indirect_sink(fp); // $ ir MISSING: ast indirect_sink(fp); // $ ir MISSING: ast
return 0; return 0;
}
int toupper(int);
int tolower(int);
void test_toupper_and_tolower() {
int s = source();
int u = toupper(s);
sink(u); // $ ir MISSING: ast
int l = tolower(s);
sink(l); // $ ir MISSING: ast
}
typedef int iconv_t;
size_t iconv(iconv_t cd, char **, size_t *, char **, size_t *);
void test_iconv(size_t size) {
char* s = indirect_source();
char out[10];
char* p = out;
size_t size_out;
iconv(0, &s, &size, &p, &size_out);
sink(*p); // $ ast,ir
} }

View File

@@ -2,7 +2,7 @@ import cpp
import semmle.code.cpp.dataflow.ExternalFlow import semmle.code.cpp.dataflow.ExternalFlow
import ExternalFlowDebug import ExternalFlowDebug
query predicate signatureMatches = signatureMatches_debug/5; query predicate signatureMatches = signatureMatches_debug/6;
query predicate getSignatureParameterName = getSignatureParameterName_debug/4; query predicate getSignatureParameterName = getSignatureParameterName_debug/4;

View File

@@ -1,5 +1,31 @@
import cpp import cpp
import utils.test.InlineExpectationsTest
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
from Expr e query predicate estimateNrOfBounds(Expr e, float nrOfBounds) {
select e, SimpleRangeAnalysisInternal::estimateNrOfBounds(e) nrOfBounds = SimpleRangeAnalysisInternal::estimateNrOfBounds(e)
}
/**
* Finds any expressions for which `nrOfBounds` is not functional. The result
* should be empty, so this predicate is useful to debug non-functional cases.
*/
private predicate nonFunctionalNrOfBounds(Expr e) {
strictcount(SimpleRangeAnalysisInternal::estimateNrOfBounds(e)) > 1
}
module FunctionalityTest implements TestSig {
string getARelevantTag() { result = "nonFunctionalNrOfBounds" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Expr e |
nonFunctionalNrOfBounds(e) and
location = e.getLocation() and
element = e.toString() and
tag = "nonFunctionalNrOfBounds" and
value = ""
)
}
}
import MakeTest<FunctionalityTest>

View File

@@ -72,77 +72,77 @@
| test.c:405:22:405:82 | ... ? ... : ... | 0.13204114 | 0.42186276 | 0.13204114 | | test.c:405:22:405:82 | ... ? ... : ... | 0.13204114 | 0.42186276 | 0.13204114 |
| test.c:405:26:405:69 | ... ? ... : ... | 0.42186276 | 0.42186276 | 0.44996679 | | test.c:405:26:405:69 | ... ? ... : ... | 0.42186276 | 0.42186276 | 0.44996679 |
| test.c:405:30:405:56 | ... ? ... : ... | 0.42186276 | 0.42186276 | 0.53843358 | | test.c:405:30:405:56 | ... ? ... : ... | 0.42186276 | 0.42186276 | 0.53843358 |
| test.c:432:4:606:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:447:4:621:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:432:5:434:49 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:447:5:449:49 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:435:6:517:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:450:6:532:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:436:8:454:41 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:451:8:469:41 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:439:10:443:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:454:10:458:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:439:31:439:79 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:454:31:454:79 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:441:13:443:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:456:13:458:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:448:12:453:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:463:12:468:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:449:12:449:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:464:12:464:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:451:15:453:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:466:15:468:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:455:6:474:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:470:6:489:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:458:8:462:19 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:473:8:477:19 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:458:29:458:77 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:473:29:473:77 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:460:11:462:19 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:475:11:477:19 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:463:6:463:54 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:478:6:478:54 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:467:10:471:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:482:10:486:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:467:31:467:79 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:482:31:482:79 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:469:13:471:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:484:13:486:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:472:9:474:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:487:9:489:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:476:10:495:43 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:491:10:510:43 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:479:12:484:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:494:12:499:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:480:12:480:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:495:12:495:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:482:15:484:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:497:15:499:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:489:14:494:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:504:14:509:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:490:14:490:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:505:14:505:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:492:17:494:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:507:17:509:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:496:9:517:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:511:9:532:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:499:14:504:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:514:14:519:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:500:14:500:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:515:14:515:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:502:17:504:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:517:17:519:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:505:12:505:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:520:12:520:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:509:12:514:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:524:12:529:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:510:12:510:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:525:12:525:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:512:15:514:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:527:15:529:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:515:11:517:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:530:11:532:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:518:9:520:51 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:533:9:535:51 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:521:9:606:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:536:9:621:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:522:14:541:47 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:537:14:556:47 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:525:16:530:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:540:16:545:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:526:16:526:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:541:16:541:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:528:19:530:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:543:19:545:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:535:18:540:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:550:18:555:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:536:18:536:66 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:551:18:551:66 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:538:21:540:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:553:21:555:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:542:12:563:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:557:12:578:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:545:14:550:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:560:14:565:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:546:14:546:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:561:14:561:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:548:17:550:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:563:17:565:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:551:12:551:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:566:12:566:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:555:16:560:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:570:16:575:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:556:16:556:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:571:16:571:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:558:19:560:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:573:19:575:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:561:15:563:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:576:15:578:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:565:12:584:45 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:580:12:599:45 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:568:14:573:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:583:14:588:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:569:14:569:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:584:14:584:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:571:17:573:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:586:17:588:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:578:16:583:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:593:16:598:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:579:16:579:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:594:16:594:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:581:19:583:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:596:19:598:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:585:11:606:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:600:11:621:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:588:16:593:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:603:16:608:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:589:16:589:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:604:16:604:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:591:19:593:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:606:19:608:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:594:14:594:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:609:14:609:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:598:14:603:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:613:14:618:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:599:14:599:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:614:14:614:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:601:17:603:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:616:17:618:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:604:13:606:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 | | test.c:619:13:621:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
| test.c:632:20:632:36 | ... ? ... : ... | 0.0 | 0.0 | 100.0 | | test.c:647:20:647:36 | ... ? ... : ... | 0.0 | 0.0 | 100.0 |
| test.c:844:5:844:14 | ... ? ... : ... | 0.0 | 1.0 | 0.0 | | test.c:859:5:859:14 | ... ? ... : ... | 0.0 | 1.0 | 0.0 |
| test.c:845:5:845:14 | ... ? ... : ... | 0.0 | 0.0 | 1.0 | | test.c:860:5:860:14 | ... ? ... : ... | 0.0 | 0.0 | 1.0 |
| test.cpp:121:3:121:12 | ... ? ... : ... | 0.0 | 1.0 | 0.0 | | test.cpp:121:3:121:12 | ... ? ... : ... | 0.0 | 1.0 | 0.0 |
| test.cpp:122:3:122:12 | ... ? ... : ... | 0.0 | 0.0 | 1.0 | | test.cpp:122:3:122:12 | ... ? ... : ... | 0.0 | 0.0 | 1.0 |

View File

@@ -72,77 +72,77 @@
| test.c:405:22:405:82 | ... ? ... : ... | 0.53843358 | 0.53843358 | 0.13204114 | | test.c:405:22:405:82 | ... ? ... : ... | 0.53843358 | 0.53843358 | 0.13204114 |
| test.c:405:26:405:69 | ... ? ... : ... | 0.53843358 | 0.53843358 | 0.44996679 | | test.c:405:26:405:69 | ... ? ... : ... | 0.53843358 | 0.53843358 | 0.44996679 |
| test.c:405:30:405:56 | ... ? ... : ... | 0.53843358 | 0.42186276 | 0.53843358 | | test.c:405:30:405:56 | ... ? ... : ... | 0.53843358 | 0.42186276 | 0.53843358 |
| test.c:432:4:606:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:447:4:621:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:432:5:434:49 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:447:5:449:49 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:435:6:517:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:450:6:532:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:436:8:454:41 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:451:8:469:41 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:439:10:443:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:454:10:458:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:439:31:439:79 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:454:31:454:79 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:441:13:443:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:456:13:458:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:448:12:453:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:463:12:468:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:449:12:449:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:464:12:464:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:451:15:453:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:466:15:468:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:455:6:474:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:470:6:489:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:458:8:462:19 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:473:8:477:19 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:458:29:458:77 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:473:29:473:77 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:460:11:462:19 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:475:11:477:19 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:463:6:463:54 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:478:6:478:54 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:467:10:471:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:482:10:486:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:467:31:467:79 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:482:31:482:79 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:469:13:471:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:484:13:486:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:472:9:474:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:487:9:489:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:476:10:495:43 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:491:10:510:43 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:479:12:484:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:494:12:499:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:480:12:480:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:495:12:495:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:482:15:484:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:497:15:499:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:489:14:494:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:504:14:509:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:490:14:490:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:505:14:505:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:492:17:494:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:507:17:509:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:496:9:517:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:511:9:532:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:499:14:504:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:514:14:519:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:500:14:500:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:515:14:515:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:502:17:504:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:517:17:519:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:505:12:505:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:520:12:520:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:509:12:514:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:524:12:529:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:510:12:510:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:525:12:525:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:512:15:514:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:527:15:529:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:515:11:517:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:530:11:532:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:518:9:520:51 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:533:9:535:51 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:521:9:606:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:536:9:621:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:522:14:541:47 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:537:14:556:47 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:525:16:530:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:540:16:545:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:526:16:526:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:541:16:541:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:528:19:530:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:543:19:545:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:535:18:540:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:550:18:555:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:536:18:536:66 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:551:18:551:66 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:538:21:540:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:553:21:555:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:542:12:563:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:557:12:578:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:545:14:550:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:560:14:565:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:546:14:546:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:561:14:561:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:548:17:550:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:563:17:565:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:551:12:551:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:566:12:566:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:555:16:560:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:570:16:575:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:556:16:556:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:571:16:571:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:558:19:560:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:573:19:575:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:561:15:563:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:576:15:578:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:565:12:584:45 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:580:12:599:45 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:568:14:573:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:583:14:588:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:569:14:569:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:584:14:584:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:571:17:573:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:586:17:588:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:578:16:583:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:593:16:598:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:579:16:579:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:594:16:594:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:581:19:583:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:596:19:598:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:585:11:606:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:600:11:621:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:588:16:593:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:603:16:608:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:589:16:589:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:604:16:604:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:591:19:593:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:606:19:608:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:594:14:594:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:609:14:609:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:598:14:603:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:613:14:618:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:599:14:599:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:614:14:614:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:601:17:603:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:616:17:618:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:604:13:606:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 | | test.c:619:13:621:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
| test.c:632:20:632:36 | ... ? ... : ... | 100.0 | 99.0 | 100.0 | | test.c:647:20:647:36 | ... ? ... : ... | 100.0 | 99.0 | 100.0 |
| test.c:844:5:844:14 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 | | test.c:859:5:859:14 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 |
| test.c:845:5:845:14 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 | | test.c:860:5:860:14 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 |
| test.cpp:121:3:121:12 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 | | test.cpp:121:3:121:12 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 |
| test.cpp:122:3:122:12 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 | | test.cpp:122:3:122:12 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 |

View File

@@ -425,6 +425,21 @@ int repeated_if_statements(unsigned int rhs) {
return rhs; // rhs has 6 bounds return rhs; // rhs has 6 bounds
} }
int ne_phi_nodes(int a, int b) {
if (a == 17) {
if (b == 23) {
a += b;
}
if (a == 18) {
b = 10;
}
}
// The statement below is an NE phi node for the access `a` in both `a == 17`
// and `a == 18`.
int c = a + b;
return a + b;
}
unsigned int conditional_nested_guards(unsigned int ip) { unsigned int conditional_nested_guards(unsigned int ip) {
// This tests a combinatorial explosion that can happen from a large number of // This tests a combinatorial explosion that can happen from a large number of
// nested linear guards. // nested linear guards.

View File

@@ -1,10 +1,16 @@
| sizeof.cpp:19:15:19:25 | sizeof(int) | 4 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int | | sizeof.cpp:19:15:19:25 | sizeof(int) | 4 | SizeofOperator.getTypeOperand() | file://:0:0:0:0 | int |
| sizeof.cpp:20:15:20:26 | sizeof(char) | 1 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char | | sizeof.cpp:20:15:20:26 | sizeof(char) | 1 | SizeofOperator.getTypeOperand() | file://:0:0:0:0 | char |
| sizeof.cpp:21:15:21:27 | sizeof(int *) | 8 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * | | sizeof.cpp:21:15:21:27 | sizeof(int *) | 8 | SizeofOperator.getTypeOperand() | file://:0:0:0:0 | int * |
| sizeof.cpp:22:15:22:29 | sizeof(MyClass) | 16 | SizeofTypeOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass | | sizeof.cpp:22:15:22:29 | sizeof(MyClass) | 16 | SizeofOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass |
| sizeof.cpp:23:15:23:23 | sizeof(<expr>) | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:23:22:23:22 | i | | sizeof.cpp:23:15:23:23 | sizeof(<expr>) | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:23:22:23:22 | i |
| sizeof.cpp:23:15:23:23 | sizeof(<expr>) | 4 | SizeofOperator.getTypeOperand() | file://:0:0:0:0 | int |
| sizeof.cpp:24:15:24:23 | sizeof(<expr>) | 1 | SizeofExprOperator.getExprOperand() | sizeof.cpp:24:22:24:22 | c | | sizeof.cpp:24:15:24:23 | sizeof(<expr>) | 1 | SizeofExprOperator.getExprOperand() | sizeof.cpp:24:22:24:22 | c |
| sizeof.cpp:24:15:24:23 | sizeof(<expr>) | 1 | SizeofOperator.getTypeOperand() | file://:0:0:0:0 | char |
| sizeof.cpp:25:15:25:25 | sizeof(<expr>) | 8 | SizeofExprOperator.getExprOperand() | sizeof.cpp:25:22:25:24 | ptr | | sizeof.cpp:25:15:25:25 | sizeof(<expr>) | 8 | SizeofExprOperator.getExprOperand() | sizeof.cpp:25:22:25:24 | ptr |
| sizeof.cpp:25:15:25:25 | sizeof(<expr>) | 8 | SizeofOperator.getTypeOperand() | file://:0:0:0:0 | int * |
| sizeof.cpp:26:15:26:24 | sizeof(<expr>) | 16 | SizeofExprOperator.getExprOperand() | sizeof.cpp:26:22:26:23 | mc | | sizeof.cpp:26:15:26:24 | sizeof(<expr>) | 16 | SizeofExprOperator.getExprOperand() | sizeof.cpp:26:22:26:23 | mc |
| sizeof.cpp:26:15:26:24 | sizeof(<expr>) | 16 | SizeofOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass |
| sizeof.cpp:27:15:27:25 | sizeof(<expr>) | 40 | SizeofExprOperator.getExprOperand() | sizeof.cpp:27:22:27:24 | arr | | sizeof.cpp:27:15:27:25 | sizeof(<expr>) | 40 | SizeofExprOperator.getExprOperand() | sizeof.cpp:27:22:27:24 | arr |
| sizeof.cpp:27:15:27:25 | sizeof(<expr>) | 40 | SizeofOperator.getTypeOperand() | file://:0:0:0:0 | int[10] |
| sizeof.cpp:28:16:28:29 | sizeof(<expr>) | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:28:23:28:28 | access to array | | sizeof.cpp:28:16:28:29 | sizeof(<expr>) | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:28:23:28:28 | access to array |
| sizeof.cpp:28:16:28:29 | sizeof(<expr>) | 4 | SizeofOperator.getTypeOperand() | file://:0:0:0:0 | int |

View File

@@ -2,8 +2,8 @@ import cpp
from SizeofOperator sto, string elemDesc, Element e from SizeofOperator sto, string elemDesc, Element e
where where
elemDesc = "SizeofTypeOperator.getTypeOperand()" and elemDesc = "SizeofOperator.getTypeOperand()" and
e = sto.(SizeofTypeOperator).getTypeOperand() e = sto.getTypeOperand()
or or
elemDesc = "SizeofExprOperator.getExprOperand()" and elemDesc = "SizeofExprOperator.getExprOperand()" and
e = sto.(SizeofExprOperator).getExprOperand() e = sto.(SizeofExprOperator).getExprOperand()

View File

@@ -84,11 +84,7 @@ namespace Semmle.Autobuild.CSharp
var temp = FileUtils.GetTemporaryWorkingDirectory(builder.Actions.GetEnvironmentVariable, builder.Options.Language.UpperCaseName, out var shouldCleanUp); var temp = FileUtils.GetTemporaryWorkingDirectory(builder.Actions.GetEnvironmentVariable, builder.Options.Language.UpperCaseName, out var shouldCleanUp);
return DotNet.WithDotNet(builder.Actions, builder.Logger, builder.Paths.Select(x => x.Item1), temp, shouldCleanUp, ensureDotNetAvailable, builder.Options.DotNetVersion, installDir => return DotNet.WithDotNet(builder.Actions, builder.Logger, builder.Paths.Select(x => x.Item1), temp, shouldCleanUp, ensureDotNetAvailable, builder.Options.DotNetVersion, installDir =>
{ {
var env = new Dictionary<string, string> var env = DotNet.MinimalEnvironment.ToDictionary();
{
{ "DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true" },
{ "MSBUILDDISABLENODEREUSE", "1" }
};
if (installDir is not null) if (installDir is not null)
{ {
// The installation succeeded, so use the newly installed .NET // The installation succeeded, so use the newly installed .NET

View File

@@ -4,6 +4,7 @@ aliases:
display_name: "C#" display_name: "C#"
version: 1.22.1 version: 1.22.1
column_kind: "utf16" column_kind: "utf16"
overlay_support_version: 20250626
extra_env_vars: extra_env_vars:
DOTNET_GENERATE_ASPNET_CERTIFICATE: "false" DOTNET_GENERATE_ASPNET_CERTIFICATE: "false"
build_modes: build_modes:
@@ -73,3 +74,8 @@ options:
[EXPERIMENTAL] The value is a path to the MsBuild binary log file that should be extracted. [EXPERIMENTAL] The value is a path to the MsBuild binary log file that should be extracted.
This option only works when `--build-mode none` is also specified. This option only works when `--build-mode none` is also specified.
type: array type: array
buildless_dependency_dir:
title: The path where buildless (standalone) extraction should keep dependencies.
description: >
If set, the buildless (standalone) extractor will store dependencies in this directory.
type: string

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: Delete databaseMetadata and overlayChangedFiles relations
compatibility: full
databaseMetadata.rel: delete
overlayChangedFiles.rel: delete

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Remove @locatable type
compatibility: full

View File

@@ -0,0 +1,62 @@
using System;
using System.IO;
using Semmle.Util;
using Semmle.Util.Logging;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
/// <summary>
/// A directory used for storing fetched dependencies.
/// When a specific directory is set via the dependency directory extractor option,
/// we store dependencies in that directory for caching purposes.
/// Otherwise, we create a temporary directory that is deleted upon disposal.
/// </summary>
public sealed class DependencyDirectory : IDisposable
{
private readonly string userReportedDirectoryPurpose;
private readonly ILogger logger;
private readonly bool attemptCleanup;
public DirectoryInfo DirInfo { get; }
public DependencyDirectory(string subfolderName, string userReportedDirectoryPurpose, ILogger logger)
{
this.logger = logger;
this.userReportedDirectoryPurpose = userReportedDirectoryPurpose;
string path;
if (EnvironmentVariables.GetBuildlessDependencyDir() is string dir)
{
path = dir;
attemptCleanup = false;
}
else
{
path = FileUtils.GetTemporaryWorkingDirectory(out _);
attemptCleanup = true;
}
DirInfo = new DirectoryInfo(Path.Join(path, subfolderName));
DirInfo.Create();
}
public void Dispose()
{
if (!attemptCleanup)
{
logger.LogInfo($"Keeping {userReportedDirectoryPurpose} directory {DirInfo.FullName} for possible caching purposes.");
return;
}
try
{
DirInfo.Delete(true);
}
catch (Exception exc)
{
logger.LogInfo($"Couldn't delete {userReportedDirectoryPurpose} directory {exc.Message}");
}
}
public override string ToString() => DirInfo.FullName;
}
}

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@@ -140,6 +141,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
// The version number should be kept in sync with the version .NET version used for building the application. // The version number should be kept in sync with the version .NET version used for building the application.
public const string LatestDotNetSdkVersion = "9.0.300"; public const string LatestDotNetSdkVersion = "9.0.300";
public static ReadOnlyDictionary<string, string> MinimalEnvironment => IDotNetCliInvoker.MinimalEnvironment;
/// <summary> /// <summary>
/// Returns a script for downloading relevant versions of the /// Returns a script for downloading relevant versions of the
/// .NET SDK. The SDK(s) will be installed at <code>installDir</code> /// .NET SDK. The SDK(s) will be installed at <code>installDir</code>
@@ -254,7 +257,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
else else
{ {
var dotnetInstallPath = actions.PathCombine(tempWorkingDirectory, ".dotnet", "dotnet-install.sh"); var dotnetInstallPath = actions.PathCombine(tempWorkingDirectory, ".dotnet", "dotnet-install.sh");
var downloadDotNetInstallSh = BuildScript.DownloadFile( var downloadDotNetInstallSh = BuildScript.DownloadFile(
"https://dot.net/v1/dotnet-install.sh", "https://dot.net/v1/dotnet-install.sh",
dotnetInstallPath, dotnetInstallPath,
@@ -269,17 +271,28 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
prelude = downloadDotNetInstallSh & chmod.Script; prelude = downloadDotNetInstallSh & chmod.Script;
postlude = shouldCleanUp ? BuildScript.DeleteFile(dotnetInstallPath) : BuildScript.Success; postlude = shouldCleanUp ? BuildScript.DeleteFile(dotnetInstallPath) : BuildScript.Success;
getInstall = version => new CommandBuilder(actions). getInstall = version =>
RunCommand(dotnetInstallPath). {
Argument("--channel"). var cb = new CommandBuilder(actions).
Argument("release"). RunCommand(dotnetInstallPath).
Argument("--version"). Argument("--channel").
Argument(version). Argument("release").
Argument("--install-dir"). Argument("--version").
Argument(path).Script; Argument(version);
// Request ARM64 architecture on Apple Silicon machines
if (actions.IsRunningOnAppleSilicon())
{
cb.Argument("--architecture").
Argument("arm64");
}
return cb.Argument("--install-dir").
Argument(path).Script;
};
} }
var dotnetInfo = new CommandBuilder(actions). var dotnetInfo = new CommandBuilder(actions, environment: MinimalEnvironment).
RunCommand(actions.PathCombine(path, "dotnet")). RunCommand(actions.PathCombine(path, "dotnet")).
Argument("--info").Script; Argument("--info").Script;
@@ -311,7 +324,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private static BuildScript GetInstalledSdksScript(IBuildActions actions) private static BuildScript GetInstalledSdksScript(IBuildActions actions)
{ {
var listSdks = new CommandBuilder(actions, silent: true). var listSdks = new CommandBuilder(actions, silent: true, environment: MinimalEnvironment).
RunCommand("dotnet"). RunCommand("dotnet").
Argument("--list-sdks"); Argument("--list-sdks");
return listSdks.Script; return listSdks.Script;

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using Semmle.Util; using Semmle.Util;
using Semmle.Util.Logging; using Semmle.Util.Logging;
@@ -36,10 +37,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{ {
startInfo.WorkingDirectory = workingDirectory; startInfo.WorkingDirectory = workingDirectory;
} }
// Set the .NET CLI language to English to avoid localized output.
startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] = "en"; // Set minimal environment variables.
startInfo.EnvironmentVariables["MSBUILDDISABLENODEREUSE"] = "1"; foreach (var kvp in IDotNetCliInvoker.MinimalEnvironment)
startInfo.EnvironmentVariables["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "true"; {
startInfo.EnvironmentVariables[kvp.Key] = kvp.Value;
}
// Configure the proxy settings, if applicable. // Configure the proxy settings, if applicable.
if (this.proxy != null) if (this.proxy != null)

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Semmle.Extraction.CSharp.DependencyFetching namespace Semmle.Extraction.CSharp.DependencyFetching
{ {
@@ -9,6 +10,20 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary> /// </summary>
string Exec { get; } string Exec { get; }
/// <summary>
/// A minimal environment for running the .NET CLI.
///
/// DOTNET_CLI_UI_LANGUAGE: The .NET CLI language is set to English to avoid localized output.
/// MSBUILDDISABLENODEREUSE: To ensure clean environment for each build.
/// DOTNET_SKIP_FIRST_TIME_EXPERIENCE: To skip first time experience messages.
/// </summary>
static ReadOnlyDictionary<string, string> MinimalEnvironment { get; } = new(new Dictionary<string, string>
{
{"DOTNET_CLI_UI_LANGUAGE", "en"},
{"MSBUILDDISABLENODEREUSE", "1"},
{"DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true"}
});
/// <summary> /// <summary>
/// Execute `dotnet <paramref name="args"/>` and return true if the command succeeded, otherwise false. /// Execute `dotnet <paramref name="args"/>` and return true if the command succeeded, otherwise false.
/// If `silent` is true the output of the command is logged as `debug` otherwise as `info`. /// If `silent` is true the output of the command is logged as `debug` otherwise as `info`.

View File

@@ -24,16 +24,16 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly FileProvider fileProvider; private readonly FileProvider fileProvider;
/// <summary> /// <summary>
/// The computed packages directory. /// The packages directory.
/// This will be in the Temp location /// This will be in the user-specified or computed Temp location
/// so as to not trample the source tree. /// so as to not trample the source tree.
/// </summary> /// </summary>
private readonly TemporaryDirectory packageDirectory; private readonly DependencyDirectory packageDirectory;
/// <summary> /// <summary>
/// Create the package manager for a specified source tree. /// Create the package manager for a specified source tree.
/// </summary> /// </summary>
public NugetExeWrapper(FileProvider fileProvider, TemporaryDirectory packageDirectory, Semmle.Util.Logging.ILogger logger) public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger)
{ {
this.fileProvider = fileProvider; this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory; this.packageDirectory = packageDirectory;

View File

@@ -24,12 +24,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly IDotNet dotnet; private readonly IDotNet dotnet;
private readonly DependabotProxy? dependabotProxy; private readonly DependabotProxy? dependabotProxy;
private readonly IDiagnosticsWriter diagnosticsWriter; private readonly IDiagnosticsWriter diagnosticsWriter;
private readonly TemporaryDirectory legacyPackageDirectory; private readonly DependencyDirectory legacyPackageDirectory;
private readonly TemporaryDirectory missingPackageDirectory; private readonly DependencyDirectory missingPackageDirectory;
private readonly ILogger logger; private readonly ILogger logger;
private readonly ICompilationInfoContainer compilationInfoContainer; private readonly ICompilationInfoContainer compilationInfoContainer;
public TemporaryDirectory PackageDirectory { get; } public DependencyDirectory PackageDirectory { get; }
public NugetPackageRestorer( public NugetPackageRestorer(
FileProvider fileProvider, FileProvider fileProvider,
@@ -48,9 +48,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
this.logger = logger; this.logger = logger;
this.compilationInfoContainer = compilationInfoContainer; this.compilationInfoContainer = compilationInfoContainer;
PackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("packages"), "package", logger); PackageDirectory = new DependencyDirectory("packages", "package", logger);
legacyPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("legacypackages"), "legacy package", logger); legacyPackageDirectory = new DependencyDirectory("legacypackages", "legacy package", logger);
missingPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("missingpackages"), "missing package", logger); missingPackageDirectory = new DependencyDirectory("missingpackages", "missing package", logger);
} }
public string? TryRestore(string package) public string? TryRestore(string package)

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
@@ -53,6 +54,20 @@ namespace Semmle.Extraction.CSharp.Standalone
} }
progressMonitor.MissingSummary(analyser.ExtractionContext!.MissingTypes.Count(), analyser.ExtractionContext!.MissingNamespaces.Count()); progressMonitor.MissingSummary(analyser.ExtractionContext!.MissingTypes.Count(), analyser.ExtractionContext!.MissingNamespaces.Count());
// If extracting a base database, we need to create an empty metadata file.
if (EnvironmentVariables.GetBaseMetaDataOutPath() is string baseMetaDataOutPath)
{
try
{
analyser.Logger.LogInfo($"Creating base metadata file at {baseMetaDataOutPath}");
File.WriteAllText(baseMetaDataOutPath, string.Empty);
}
catch (Exception ex)
{
analyser.Logger.LogError($"Failed to create base metadata file: {ex.Message}");
}
}
}); });
} }
finally finally
@@ -143,7 +158,8 @@ namespace Semmle.Extraction.CSharp.Standalone
var pathTransformer = new PathTransformer(canonicalPathCache); var pathTransformer = new PathTransformer(canonicalPathCache);
var progressMonitor = new ExtractionProgress(logger); var progressMonitor = new ExtractionProgress(logger);
using var analyser = new StandaloneAnalyser(progressMonitor, fileLogger, pathTransformer, canonicalPathCache, false); var overlayInfo = OverlayInfoFactory.Make(logger, options.SrcDir);
using var analyser = new StandaloneAnalyser(progressMonitor, fileLogger, pathTransformer, canonicalPathCache, overlayInfo, false);
try try
{ {
var extractionInput = new ExtractionInput(dependencyManager.AllSourceFiles, dependencyManager.ReferenceFiles, dependencyManager.CompilationInfos); var extractionInput = new ExtractionInput(dependencyManager.AllSourceFiles, dependencyManager.ReferenceFiles, dependencyManager.CompilationInfos);
@@ -154,7 +170,8 @@ namespace Semmle.Extraction.CSharp.Standalone
fileLogger.LogError($" Unhandled exception: {ex}"); fileLogger.LogError($" Unhandled exception: {ex}");
} }
logger.Log(Severity.Info, $"Extraction completed in {overallStopwatch.Elapsed}"); logger.Log(Severity.Info, $"Extraction completed in {analyzerStopwatch.Elapsed}");
logger.Log(Severity.Info, $"Total time: {overallStopwatch.Elapsed}");
return ExitCode.Ok; return ExitCode.Ok;
} }

View File

@@ -57,8 +57,21 @@ namespace Semmle.Extraction.CSharp.Entities
public override void Populate(TextWriter trapFile) public override void Populate(TextWriter trapFile)
{ {
// In this case, we don't extract the attribute again, as it was extracted using * ID
// originally and we re-use that.
if (Context.OnlyScaffold && (ReportingLocation is null || !ReportingLocation.IsInSource))
{
return;
}
var type = Type.Create(Context, Symbol.AttributeClass); var type = Type.Create(Context, Symbol.AttributeClass);
trapFile.attributes(this, kind, type.TypeRef, entity); trapFile.attributes(this, kind, type.TypeRef, entity);
if (Context.OnlyScaffold)
{
return;
}
WriteLocationToTrap(trapFile.attribute_location, this, Location); WriteLocationToTrap(trapFile.attribute_location, this, Location);
if (attributeSyntax is not null) if (attributeSyntax is not null)

View File

@@ -10,9 +10,13 @@ namespace Semmle.Extraction.CSharp.Entities
public override void Populate(TextWriter trapFile) public override void Populate(TextWriter trapFile)
{ {
if (Context.OnlyScaffold)
{
return;
}
trapFile.commentblock(this); trapFile.commentblock(this);
WriteLocationToTrap(trapFile.commentblock_location, this, Context.CreateLocation(Symbol.Location));
Symbol.CommentLines.ForEach((l, child) => trapFile.commentblock_child(this, l, child)); Symbol.CommentLines.ForEach((l, child) => trapFile.commentblock_child(this, l, child));
WriteLocationToTrap(trapFile.commentblock_location, this, Context.CreateLocation(Symbol.Location));
} }
public override bool NeedsPopulation => true; public override bool NeedsPopulation => true;
@@ -27,6 +31,10 @@ namespace Semmle.Extraction.CSharp.Entities
public void BindTo(Label entity, CommentBinding binding) public void BindTo(Label entity, CommentBinding binding)
{ {
if (Context.OnlyScaffold)
{
return;
}
Context.TrapWriter.Writer.commentblock_binding(this, entity, binding); Context.TrapWriter.Writer.commentblock_binding(this, entity, binding);
} }

View File

@@ -21,9 +21,14 @@ namespace Semmle.Extraction.CSharp.Entities
public override void Populate(TextWriter trapFile) public override void Populate(TextWriter trapFile)
{ {
location = Context.CreateLocation(Location); if (Context.OnlyScaffold)
{
return;
}
trapFile.commentline(this, Type == CommentLineType.MultilineContinuation ? CommentLineType.Multiline : Type, Text, RawText); trapFile.commentline(this, Type == CommentLineType.MultilineContinuation ? CommentLineType.Multiline : Type, Text, RawText);
location = Context.CreateLocation(Location);
WriteLocationToTrap(trapFile.commentline_location, this, location); WriteLocationToTrap(trapFile.commentline_location, this, location);
} }
public override Microsoft.CodeAnalysis.Location? ReportingLocation => location?.Symbol; public override Microsoft.CodeAnalysis.Location? ReportingLocation => location?.Symbol;

View File

@@ -21,6 +21,11 @@ namespace Semmle.Extraction.CSharp.Entities
protected override void Populate(TextWriter trapFile) protected override void Populate(TextWriter trapFile)
{ {
if (Context.OnlyScaffold)
{
return;
}
var key = diagnostic.Id; var key = diagnostic.Id;
var messageCount = compilation.messageCounts.AddOrUpdate(key, 1, (_, c) => c + 1); var messageCount = compilation.messageCounts.AddOrUpdate(key, 1, (_, c) => c + 1);
if (messageCount > limit) if (messageCount > limit)

View File

@@ -29,9 +29,17 @@ namespace Semmle.Extraction.CSharp.Entities
ContainingType!.PopulateGenerics(); ContainingType!.PopulateGenerics();
trapFile.constructors(this, Symbol.ContainingType.Name, ContainingType, (Constructor)OriginalDefinition); trapFile.constructors(this, Symbol.ContainingType.Name, ContainingType, (Constructor)OriginalDefinition);
if (Context.ExtractLocation(Symbol) && (!IsDefault || IsBestSourceLocation))
if (Symbol.IsImplicitlyDeclared)
{ {
WriteLocationToTrap(trapFile.constructor_location, this, Location); var lineCounts = new LineCounts() { Total = 2, Code = 1, Comment = 0 };
trapFile.numlines(this, lineCounts);
}
ExtractCompilerGenerated(trapFile);
if (Context.OnlyScaffold)
{
return;
} }
if (MakeSynthetic) if (MakeSynthetic)
@@ -40,12 +48,11 @@ namespace Semmle.Extraction.CSharp.Entities
Statements.SyntheticEmptyBlock.Create(Context, this, 0, Location); Statements.SyntheticEmptyBlock.Create(Context, this, 0, Location);
} }
if (Symbol.IsImplicitlyDeclared) if (Context.ExtractLocation(Symbol) && (!IsDefault || IsBestSourceLocation))
{ {
var lineCounts = new LineCounts() { Total = 2, Code = 1, Comment = 0 }; WriteLocationToTrap(trapFile.constructor_location, this, Location);
trapFile.numlines(this, lineCounts);
} }
ExtractCompilerGenerated(trapFile);
} }
protected override void ExtractInitializers(TextWriter trapFile) protected override void ExtractInitializers(TextWriter trapFile)
@@ -53,7 +60,7 @@ namespace Semmle.Extraction.CSharp.Entities
// Do not extract initializers for constructed types. // Do not extract initializers for constructed types.
// Extract initializers for constructors with a body, primary constructors // Extract initializers for constructors with a body, primary constructors
// and default constructors for classes and structs declared in source code. // and default constructors for classes and structs declared in source code.
if (Block is null && ExpressionBody is null && !MakeSynthetic) if (Block is null && ExpressionBody is null && !MakeSynthetic || Context.OnlyScaffold)
{ {
return; return;
} }
@@ -106,6 +113,7 @@ namespace Semmle.Extraction.CSharp.Entities
} }
var baseConstructorTarget = Create(Context, baseConstructor); var baseConstructorTarget = Create(Context, baseConstructor);
var info = new ExpressionInfo(Context, var info = new ExpressionInfo(Context,
AnnotatedTypeSymbol.CreateNotAnnotated(baseType), AnnotatedTypeSymbol.CreateNotAnnotated(baseType),
Location, Location,
@@ -179,7 +187,7 @@ namespace Semmle.Extraction.CSharp.Entities
/// </summary> /// </summary>
private bool IsBestSourceLocation => ReportingLocation is not null && Context.IsLocationInContext(ReportingLocation); private bool IsBestSourceLocation => ReportingLocation is not null && Context.IsLocationInContext(ReportingLocation);
private bool MakeSynthetic => IsPrimary || (IsDefault && IsBestSourceLocation); private bool MakeSynthetic => (IsPrimary || (IsDefault && IsBestSourceLocation)) && !Context.OnlyScaffold;
[return: NotNullIfNotNull(nameof(constructor))] [return: NotNullIfNotNull(nameof(constructor))]
public static new Constructor? Create(Context cx, IMethodSymbol? constructor) public static new Constructor? Create(Context cx, IMethodSymbol? constructor)

View File

@@ -15,6 +15,7 @@ namespace Semmle.Extraction.CSharp.Entities
ContainingType!.PopulateGenerics(); ContainingType!.PopulateGenerics();
trapFile.destructors(this, $"~{Symbol.ContainingType.Name}", ContainingType, OriginalDefinition(Context, this, Symbol)); trapFile.destructors(this, $"~{Symbol.ContainingType.Name}", ContainingType, OriginalDefinition(Context, this, Symbol));
if (Context.ExtractLocation(Symbol)) if (Context.ExtractLocation(Symbol))
{ {
WriteLocationToTrap(trapFile.destructor_location, this, Location); WriteLocationToTrap(trapFile.destructor_location, this, Location);

View File

@@ -37,7 +37,6 @@ namespace Semmle.Extraction.CSharp.Entities
Method.Create(Context, remover); Method.Create(Context, remover);
PopulateModifiers(trapFile); PopulateModifiers(trapFile);
BindComments();
var declSyntaxReferences = IsSourceDeclaration var declSyntaxReferences = IsSourceDeclaration
? Symbol.DeclaringSyntaxReferences.Select(d => d.GetSyntax()).ToArray() ? Symbol.DeclaringSyntaxReferences.Select(d => d.GetSyntax()).ToArray()
@@ -51,6 +50,13 @@ namespace Semmle.Extraction.CSharp.Entities
TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface); TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface);
} }
if (Context.OnlyScaffold)
{
return;
}
BindComments();
if (Context.ExtractLocation(Symbol)) if (Context.ExtractLocation(Symbol))
{ {
WriteLocationsToTrap(trapFile.event_location, this, Locations); WriteLocationsToTrap(trapFile.event_location, this, Locations);

View File

@@ -28,6 +28,11 @@ namespace Semmle.Extraction.CSharp.Entities
protected override void Populate(TextWriter trapFile) protected override void Populate(TextWriter trapFile)
{ {
if (Context.OnlyScaffold)
{
return;
}
// For the time being we're counting the number of messages per severity, we could introduce other groupings in the future // For the time being we're counting the number of messages per severity, we could introduce other groupings in the future
var key = msg.Severity.ToString(); var key = msg.Severity.ToString();
groupedMessageCounts.AddOrUpdate(key, 1, (_, c) => c + 1); groupedMessageCounts.AddOrUpdate(key, 1, (_, c) => c + 1);

View File

@@ -49,6 +49,11 @@ namespace Semmle.Extraction.CSharp.Entities
} }
} }
if (Context.OnlyScaffold)
{
return;
}
if (Context.ExtractLocation(Symbol)) if (Context.ExtractLocation(Symbol))
{ {
WriteLocationsToTrap(trapFile.field_location, this, Locations); WriteLocationsToTrap(trapFile.field_location, this, Locations);

View File

@@ -19,10 +19,6 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type.Create(Context, Symbol.Type); var type = Type.Create(Context, Symbol.Type);
trapFile.indexers(this, Symbol.GetName(useMetadataName: true), ContainingType!, type.TypeRef, OriginalDefinition); trapFile.indexers(this, Symbol.GetName(useMetadataName: true), ContainingType!, type.TypeRef, OriginalDefinition);
if (Context.ExtractLocation(Symbol))
{
WriteLocationsToTrap(trapFile.indexer_location, this, Locations);
}
var getter = BodyDeclaringSymbol.GetMethod; var getter = BodyDeclaringSymbol.GetMethod;
var setter = BodyDeclaringSymbol.SetMethod; var setter = BodyDeclaringSymbol.SetMethod;
@@ -42,20 +38,8 @@ namespace Semmle.Extraction.CSharp.Entities
Parameter.Create(Context, Symbol.Parameters[i], this, original); Parameter.Create(Context, Symbol.Parameters[i], this, original);
} }
if (IsSourceDeclaration)
{
var expressionBody = ExpressionBody;
if (expressionBody is not null)
{
// The expression may need to reference parameters in the getter.
// So we need to arrange that the expression is populated after the getter.
Context.PopulateLater(() => Expression.CreateFromNode(new ExpressionNodeInfo(Context, expressionBody, this, 0).SetType(Symbol.GetAnnotatedType())));
}
}
PopulateAttributes(); PopulateAttributes();
PopulateModifiers(trapFile); PopulateModifiers(trapFile);
BindComments();
var declSyntaxReferences = IsSourceDeclaration var declSyntaxReferences = IsSourceDeclaration
? Symbol.DeclaringSyntaxReferences. ? Symbol.DeclaringSyntaxReferences.
@@ -70,6 +54,28 @@ namespace Semmle.Extraction.CSharp.Entities
TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface); TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface);
} }
if (Context.OnlyScaffold)
{
return;
}
if (Context.ExtractLocation(Symbol))
{
WriteLocationsToTrap(trapFile.indexer_location, this, Locations);
}
if (IsSourceDeclaration)
{
var expressionBody = ExpressionBody;
if (expressionBody is not null)
{
// The expression may need to reference parameters in the getter.
// So we need to arrange that the expression is populated after the getter.
Context.PopulateLater(() => Expression.CreateFromNode(new ExpressionNodeInfo(Context, expressionBody, this, 0).SetType(Symbol.GetAnnotatedType())));
}
}
BindComments();
foreach (var syntax in declSyntaxReferences) foreach (var syntax in declSyntaxReferences)
TypeMention.Create(Context, syntax.Type, this, type); TypeMention.Create(Context, syntax.Type, this, type);

View File

@@ -41,6 +41,11 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.localvars(this, Kinds.VariableKind.None, Symbol.Name, @var, Type.Create(Context, parent.Type).TypeRef, parent); trapFile.localvars(this, Kinds.VariableKind.None, Symbol.Name, @var, Type.Create(Context, parent.Type).TypeRef, parent);
} }
if (Context.OnlyScaffold)
{
return;
}
WriteLocationToTrap(trapFile.localvar_location, this, Location); WriteLocationToTrap(trapFile.localvar_location, this, Location);
DefineConstantValue(trapFile); DefineConstantValue(trapFile);

View File

@@ -48,7 +48,7 @@ namespace Semmle.Extraction.CSharp.Entities
protected virtual void PopulateMethodBody(TextWriter trapFile) protected virtual void PopulateMethodBody(TextWriter trapFile)
{ {
if (!IsSourceDeclaration) if (!IsSourceDeclaration || Context.OnlyScaffold)
return; return;
var block = Block; var block = Block;

View File

@@ -35,7 +35,6 @@ namespace Semmle.Extraction.CSharp.Entities
var ns = Namespace.Create(Context, @namespace); var ns = Namespace.Create(Context, @namespace);
trapFile.namespace_declarations(this, ns); trapFile.namespace_declarations(this, ns);
WriteLocationToTrap(trapFile.namespace_declaration_location, this, Context.CreateLocation(node.Name.GetLocation()));
var visitor = new Populators.TypeOrNamespaceVisitor(Context, trapFile, this); var visitor = new Populators.TypeOrNamespaceVisitor(Context, trapFile, this);
@@ -48,6 +47,12 @@ namespace Semmle.Extraction.CSharp.Entities
{ {
trapFile.parent_namespace_declaration(this, parent); trapFile.parent_namespace_declaration(this, parent);
} }
if (Context.OnlyScaffold)
{
return;
}
WriteLocationToTrap(trapFile.namespace_declaration_location, this, Context.CreateLocation(node.Name.GetLocation()));
} }
public static NamespaceDeclaration Create(Context cx, BaseNamespaceDeclarationSyntax decl, NamespaceDeclaration parent) public static NamespaceDeclaration Create(Context cx, BaseNamespaceDeclarationSyntax decl, NamespaceDeclaration parent)

View File

@@ -34,6 +34,16 @@ namespace Semmle.Extraction.CSharp.Entities
var returnType = Type.Create(Context, Symbol.ReturnType); var returnType = Type.Create(Context, Symbol.ReturnType);
trapFile.methods(this, Name, ContainingType, returnType.TypeRef, OriginalDefinition); trapFile.methods(this, Name, ContainingType, returnType.TypeRef, OriginalDefinition);
PopulateGenerics(trapFile);
Overrides(trapFile);
ExtractRefReturn(trapFile, Symbol, this);
ExtractCompilerGenerated(trapFile);
if (Context.OnlyScaffold)
{
return;
}
if (IsSourceDeclaration) if (IsSourceDeclaration)
{ {
foreach (var declaration in Symbol.DeclaringSyntaxReferences.Select(s => s.GetSyntax()).OfType<MethodDeclarationSyntax>()) foreach (var declaration in Symbol.DeclaringSyntaxReferences.Select(s => s.GetSyntax()).OfType<MethodDeclarationSyntax>())
@@ -47,11 +57,6 @@ namespace Semmle.Extraction.CSharp.Entities
{ {
WriteLocationsToTrap(trapFile.method_location, this, Locations); WriteLocationsToTrap(trapFile.method_location, this, Locations);
} }
PopulateGenerics(trapFile);
Overrides(trapFile);
ExtractRefReturn(trapFile, Symbol, this);
ExtractCompilerGenerated(trapFile);
} }
private bool IsCompilerGeneratedDelegate() => private bool IsCompilerGeneratedDelegate() =>

View File

@@ -115,6 +115,11 @@ namespace Semmle.Extraction.CSharp.Entities
var type = Type.Create(Context, Symbol.Type); var type = Type.Create(Context, Symbol.Type);
trapFile.@params(this, Name, type.TypeRef, Ordinal, ParamKind, Parent!, Original); trapFile.@params(this, Name, type.TypeRef, Ordinal, ParamKind, Parent!, Original);
if (Context.OnlyScaffold)
{
return;
}
if (Context.ExtractLocation(Symbol)) if (Context.ExtractLocation(Symbol))
{ {
var locations = Context.GetLocations(Symbol); var locations = Context.GetLocations(Symbol);

View File

@@ -13,10 +13,15 @@ namespace Semmle.Extraction.CSharp.Entities
PopulatePreprocessor(trapFile); PopulatePreprocessor(trapFile);
trapFile.preprocessor_directive_active(this, Symbol.IsActive); trapFile.preprocessor_directive_active(this, Symbol.IsActive);
WriteLocationToTrap(trapFile.preprocessor_directive_location, this, Context.CreateLocation(ReportingLocation));
var compilation = Compilation.Create(Context); var compilation = Compilation.Create(Context);
trapFile.preprocessor_directive_compilation(this, compilation); trapFile.preprocessor_directive_compilation(this, compilation);
if (Context.OnlyScaffold)
{
return;
}
WriteLocationToTrap(trapFile.preprocessor_directive_location, this, Context.CreateLocation(ReportingLocation));
} }
protected abstract void PopulatePreprocessor(TextWriter trapFile); protected abstract void PopulatePreprocessor(TextWriter trapFile);

View File

@@ -40,7 +40,6 @@ namespace Semmle.Extraction.CSharp.Entities
{ {
PopulateAttributes(); PopulateAttributes();
PopulateModifiers(trapFile); PopulateModifiers(trapFile);
BindComments();
PopulateNullability(trapFile, Symbol.GetAnnotatedType()); PopulateNullability(trapFile, Symbol.GetAnnotatedType());
PopulateRefKind(trapFile, Symbol.RefKind); PopulateRefKind(trapFile, Symbol.RefKind);
@@ -69,6 +68,13 @@ namespace Semmle.Extraction.CSharp.Entities
TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface); TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface);
} }
if (Context.OnlyScaffold)
{
return;
}
BindComments();
if (Context.ExtractLocation(Symbol)) if (Context.ExtractLocation(Symbol))
{ {
WriteLocationsToTrap(trapFile.property_location, this, Locations); WriteLocationsToTrap(trapFile.property_location, this, Locations);

View File

@@ -59,6 +59,11 @@ namespace Semmle.Extraction.CSharp.Entities
protected override void Populate(TextWriter trapFile) protected override void Populate(TextWriter trapFile)
{ {
if (Context.OnlyScaffold)
{
return;
}
switch (syntax.Kind()) switch (syntax.Kind())
{ {
case SyntaxKind.ArrayType: case SyntaxKind.ArrayType:

View File

@@ -16,10 +16,14 @@ namespace Semmle.Extraction.CSharp.Entities
public override void Populate(TextWriter trapFile) public override void Populate(TextWriter trapFile)
{ {
trapFile.types(this, Kinds.TypeKind.DYNAMIC, "dynamic"); trapFile.types(this, Kinds.TypeKind.DYNAMIC, "dynamic");
WriteLocationToTrap(trapFile.type_location, this, Location);
trapFile.has_modifiers(this, Modifier.Create(Context, "public")); trapFile.has_modifiers(this, Modifier.Create(Context, "public"));
trapFile.parent_namespace(this, Namespace.Create(Context, Context.Compilation.GlobalNamespace)); trapFile.parent_namespace(this, Namespace.Create(Context, Context.Compilation.GlobalNamespace));
if (Context.OnlyScaffold)
{
return;
}
WriteLocationToTrap(trapFile.type_location, this, Location);
} }
public override void WriteId(EscapingTextWriter trapFile) public override void WriteId(EscapingTextWriter trapFile)

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