Merge branch 'main' into mathiasvp/read-step-without-memory-operands

This commit is contained in:
Mathias Vorreiter Pedersen
2020-09-01 11:08:52 +02:00
197 changed files with 7466 additions and 1823 deletions

View File

@@ -30,7 +30,7 @@
- [yargs](https://www.npmjs.com/package/yargs)
- [webpack-dev-server](https://www.npmjs.com/package/webpack-dev-server)
* TypeScript 3.9 is now supported.
* TypeScript 4.0 is now supported.
* TypeScript code embedded in HTML and Vue files is now extracted and analyzed.

View File

@@ -20,4 +20,3 @@ The following changes in version 1.25 affect Python analysis in all applications
## Changes to libraries
* Importing `semmle.python.web.HttpRequest` will no longer import `UntrustedStringKind` transitively. `UntrustedStringKind` is the most commonly used non-abstract subclass of `ExternalStringKind`. If not imported (by one mean or another), taint-tracking queries that concern `ExternalStringKind` will not produce any results. Please ensure such queries contain an explicit import (`import semmle.python.security.strings.Untrusted`).
* Added support for tainted f-strings.

View File

@@ -19,6 +19,8 @@ The following changes in version 1.26 affect C# analysis in all applications.
## Changes to code extraction
* Partial method bodies are extracted. Previously, partial method bodies were skipped completely.
* Inferring the lengths of implicitely sized arrays is fixed. Previously, multidimensional arrays were always extracted with the same length for
each dimension. With the fix, the array sizes `2` and `1` are extracted for `new int[,]{{1},{2}}`. Previously `2` and `2` were extracted.
## Changes to libraries

View File

@@ -27,6 +27,7 @@
| **Query** | **Expected impact** | **Change** |
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
| Incomplete URL substring sanitization (`js/incomplete-url-substring-sanitization`) | More results | This query now recognizes additional URLs when the substring check is an inclusion check. |
| Ambiguous HTML id attribute (`js/duplicate-html-id`) | Results no longer shown | Precision tag reduced to "low". The query is no longer run by default. |
## Changes to libraries

View File

@@ -0,0 +1,22 @@
# Improvements to Python analysis
The following changes in version 1.26 affect Python analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
## Changes to libraries
* Added taint tracking support for string formatting through f-strings.

View File

@@ -325,6 +325,10 @@
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll"
],
"Inline Test Expectations": [
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"python/ql/test/TestUtilities/InlineExpectationsTest.qll"
],
"XML": [
"cpp/ql/src/semmle/code/cpp/XML.qll",
"csharp/ql/src/semmle/code/csharp/XML.qll",

View File

@@ -0,0 +1,11 @@
void test(char *arg1, int *arg2) {
if (arg1[0] == 'A') {
if (arg2 != NULL) { //maybe redundant
*arg2 = 42;
}
}
if (arg1[1] == 'B')
{
*arg2 = 54; //dereferenced without checking first
}
}

View File

@@ -0,0 +1,29 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>This rule finds comparisons of a function parameter to null that occur when in another path the parameter is dereferenced without a guard check. It's
likely either the check is not required and can be removed, or it should be added before the dereference
so that a null pointer dereference does not occur.</p>
</overview>
<recommendation>
<p>A check should be added to before the dereference, in a way that prevents a null pointer value from
being dereferenced. If it's clear that the pointer cannot be null, consider removing the check instead.</p>
</recommendation>
<example>
<sample src="RedundantNullCheckParam.cpp" />
</example>
<references>
<li>
<a href="https://www.owasp.org/index.php/Null_Dereference">
Null Dereference
</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,56 @@
/**
* @name Redundant null check or missing null check of parameter
* @description Checking a parameter for nullness in one path,
* and not in another is likely to be a sign that either
* the check can be removed, or added in the other case.
* @kind problem
* @id cpp/redundant-null-check-param
* @problem.severity recommendation
* @tags reliability
* security
* external/cwe/cwe-476
*/
import cpp
predicate blockDominates(Block check, Block access) {
check.getLocation().getStartLine() <= access.getLocation().getStartLine() and
check.getLocation().getEndLine() >= access.getLocation().getEndLine()
}
predicate isCheckedInstruction(VariableAccess unchecked, VariableAccess checked) {
checked = any(VariableAccess va | va.getTarget() = unchecked.getTarget()) and
//Simple test if the first access in this code path is dereferenced
not dereferenced(checked) and
blockDominates(checked.getEnclosingBlock(), unchecked.getEnclosingBlock())
}
predicate candidateResultUnchecked(VariableAccess unchecked) {
not isCheckedInstruction(unchecked, _)
}
predicate candidateResultChecked(VariableAccess check, EqualityOperation eqop) {
//not dereferenced to check against pointer, not its pointed value
not dereferenced(check) and
//assert macros are not taken into account
not check.isInMacroExpansion() and
// is part of a comparison against some constant NULL
eqop.getAnOperand() = check and
eqop.getAnOperand() instanceof NullValue
}
from VariableAccess unchecked, VariableAccess check, EqualityOperation eqop, Parameter param
where
// a dereference
dereferenced(unchecked) and
// for a function parameter
unchecked.getTarget() = param and
// this function parameter is not overwritten
count(param.getAnAssignment()) = 0 and
check.getTarget() = param and
// which is once checked
candidateResultChecked(check, eqop) and
// and which has not been checked before in this code path
candidateResultUnchecked(unchecked)
select check, "This null check is redundant or there is a missing null check before $@ ", unchecked,
"where dereferencing happens"

View File

@@ -123,8 +123,18 @@ module Consistency {
n.getEnclosingCallable() != call.getEnclosingCallable()
}
// This predicate helps the compiler forget that in some languages
// it is impossible for a result of `getPreUpdateNode` to be an
// instance of `PostUpdateNode`.
private Node getPre(PostUpdateNode n) {
result = n.getPreUpdateNode()
or
none()
}
query predicate postIsNotPre(PostUpdateNode n, string msg) {
n.getPreUpdateNode() = n and msg = "PostUpdateNode should not equal its pre-update node."
getPre(n) = n and
msg = "PostUpdateNode should not equal its pre-update node."
}
query predicate postHasUniquePre(PostUpdateNode n, string msg) {
@@ -152,12 +162,6 @@ module Consistency {
msg = "Origin of readStep is missing a PostUpdateNode."
}
query predicate storeIsPostUpdate(Node n, string msg) {
storeStep(_, _, n) and
not n instanceof PostUpdateNode and
msg = "Store targets should be PostUpdateNodes."
}
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
not hasPost(n) and
not isImmutableOrUnobservable(n) and

View File

@@ -123,8 +123,18 @@ module Consistency {
n.getEnclosingCallable() != call.getEnclosingCallable()
}
// This predicate helps the compiler forget that in some languages
// it is impossible for a result of `getPreUpdateNode` to be an
// instance of `PostUpdateNode`.
private Node getPre(PostUpdateNode n) {
result = n.getPreUpdateNode()
or
none()
}
query predicate postIsNotPre(PostUpdateNode n, string msg) {
n.getPreUpdateNode() = n and msg = "PostUpdateNode should not equal its pre-update node."
getPre(n) = n and
msg = "PostUpdateNode should not equal its pre-update node."
}
query predicate postHasUniquePre(PostUpdateNode n, string msg) {
@@ -152,12 +162,6 @@ module Consistency {
msg = "Origin of readStep is missing a PostUpdateNode."
}
query predicate storeIsPostUpdate(Node n, string msg) {
storeStep(_, _, n) and
not n instanceof PostUpdateNode and
msg = "Store targets should be PostUpdateNodes."
}
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
not hasPost(n) and
not isImmutableOrUnobservable(n) and

View File

@@ -23,7 +23,7 @@ class StdSequenceContainerConstructor extends Constructor, TaintFunction {
*/
int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(0) // i.e. the `T` of this `std::vector<T>`
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -33,6 +33,24 @@ class StdSequenceContainerConstructor extends Constructor, TaintFunction {
}
}
/**
* The standard container function `data`.
*/
class StdSequenceContainerData extends TaintFunction {
StdSequenceContainerData() { this.hasQualifiedName("std", ["array", "vector"], "data") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from container itself (qualifier) to return value
input.isQualifierObject() and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier (for writes to
// `data`)
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The standard container functions `push_back` and `push_front`.
*/
@@ -70,6 +88,30 @@ class StdSequenceContainerFrontBack extends TaintFunction {
}
}
/**
* The standard container function `assign`.
*/
class StdSequenceContainerAssign extends TaintFunction {
StdSequenceContainerAssign() {
this.hasQualifiedName("std", ["vector", "deque", "list", "forward_list"], "assign")
}
/**
* Gets the index of a parameter to this function that is a reference to the
* value type of the container.
*/
int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to string itself (qualifier) and return value
input.isParameterDeref(getAValueTypeParameterIndex()) and
output.isQualifierObject()
}
}
/**
* The standard container `swap` functions.
*/

View File

@@ -8,15 +8,33 @@ class StdBasicString extends TemplateClass {
}
/**
* The `std::string` functions `c_str` and `data`.
* The `std::string` function `c_str`.
*/
class StdStringCStr extends TaintFunction {
StdStringCStr() { this.hasQualifiedName("std", "basic_string", ["c_str", "data"]) }
StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string itself (qualifier) to return value
input.isQualifierObject() and
output.isReturnValue()
output.isReturnValueDeref()
}
}
/**
* The `std::string` function `data`.
*/
class StdStringData extends TaintFunction {
StdStringData() { this.hasQualifiedName("std", "basic_string", "data") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string itself (qualifier) to return value
input.isQualifierObject() and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier (for writes to
// `data`)
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
@@ -53,17 +71,18 @@ class StdStringAppend extends TaintFunction {
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameter() {
int getAStringParameterIndex() {
getParameter(result).getType() instanceof PointerType or
getParameter(result).getType() instanceof ReferenceType or
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
getParameter(result).getUnspecifiedType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string and parameter to string (qualifier) and return value
(
input.isQualifierObject() or
input.isParameterDeref(getAStringParameter())
input.isParameterDeref(getAStringParameterIndex())
) and
(
output.isQualifierObject() or
@@ -82,15 +101,16 @@ class StdStringAssign extends TaintFunction {
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameter() {
int getAStringParameterIndex() {
getParameter(result).getType() instanceof PointerType or
getParameter(result).getType() instanceof ReferenceType or
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
getParameter(result).getUnspecifiedType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to string itself (qualifier) and return value
input.isParameterDeref(getAStringParameter()) and
input.isParameterDeref(getAStringParameterIndex()) and
(
output.isQualifierObject() or
output.isReturnValueDeref()

View File

@@ -28,11 +28,11 @@
* }
*
* override predicate hasActualResult(
* Location location, string element, string tag, string valuesasas
* Location location, string element, string tag, string value
* ) {
* exists(Expr e |
* tag = "const" and // The tag for this test.
* valuesasas = e.getValue() and // The expected value. Will only hold for constant expressions.
* value = e.getValue() and // The expected value. Will only hold for constant expressions.
* location = e.getLocation() and // The location of the result to be reported.
* element = e.toString() // The display text for the result.
* )

View File

@@ -14,7 +14,6 @@ postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
storeIsPostUpdate
argHasPostUpdate
| lambdas.cpp:18:7:18:7 | a | ArgumentNode is missing PostUpdateNode. |
| lambdas.cpp:25:2:25:2 | b | ArgumentNode is missing PostUpdateNode. |

View File

@@ -29,5 +29,4 @@ postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
storeIsPostUpdate
argHasPostUpdate

View File

@@ -16,7 +16,6 @@ postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
storeIsPostUpdate
argHasPostUpdate
| A.cpp:41:15:41:21 | new | ArgumentNode is missing PostUpdateNode. |
| A.cpp:55:12:55:19 | new | ArgumentNode is missing PostUpdateNode. |

View File

@@ -23,5 +23,4 @@ postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
storeIsPostUpdate
argHasPostUpdate

View File

@@ -0,0 +1,147 @@
int source();
void sink(int);
void sink(class MyInt);
void sink(class MyArray);
void test_pointer_deref_assignment()
{
int x = 0;
int *p_x = &x;
int *p2_x = &x;
int &r_x = x;
*p_x = source();
sink(x); // tainted [DETECTED BY IR ONLY]
sink(*p_x); // tainted [DETECTED BY IR ONLY]
sink(*p2_x); // tainted [DETECTED BY IR ONLY]
sink(r_x); // tainted [DETECTED BY IR ONLY]
}
void test_reference_deref_assignment()
{
int x = 0;
int *p_x = &x;
int &r_x = x;
int &r2_x = x;
r_x = source();
sink(x); // tainted [DETECTED BY IR ONLY]
sink(*p_x); // tainted [DETECTED BY IR ONLY]
sink(r_x); // tainted
sink(r2_x); // tainted [DETECTED BY IR ONLY]
}
class MyInt
{
public:
MyInt() : i(0) {}
int &get() { return i; }
MyInt &operator=(const int &other);
MyInt &operator=(const MyInt &other);
int i;
};
void test_myint_member_assignment()
{
MyInt mi;
mi.i = source();
sink(mi); // tainted [DETECTED BY IR ONLY]
sink(mi.get()); // tainted
}
void test_myint_method_assignment()
{
MyInt mi;
mi.get() = source();
sink(mi); // tainted [DETECTED BY IR ONLY]
sink(mi.get()); // tainted
}
void test_myint_overloaded_assignment()
{
MyInt mi, mi2;
mi = source();
mi2 = mi;
sink(mi); // tainted [NOT DETECTED]
sink(mi.get()); // tainted [NOT DETECTED]
sink(mi2); // tainted [NOT DETECTED]
sink(mi2.get()); // tainted [NOT DETECTED]
}
class MyArray
{
public:
MyArray() : values({0}) {}
int &get(int i) { return values[i]; }
int &operator[](int i);
int values[10];
};
void test_myarray_member_assignment()
{
MyArray ma;
ma.values[0] = source();
sink(ma.values[0]); // tainted
}
void test_myarray_method_assignment()
{
MyArray ma;
ma.get(0) = source();
sink(ma.get(0)); // tainted [NOT DETECTED]
}
void test_myarray_overloaded_assignment()
{
MyArray ma, ma2;
ma[0] = source();
ma2 = ma;
sink(ma[0]); // tainted [NOT DETECTED]
sink(ma2[0]); // tainted [NOT DETECTED]
}
void sink(int *);
void test_array_reference_assignment()
{
int arr1[10] = {0};
int arr2[10] = {0};
int arr3[10] = {0};
int &ref1 = arr1[5];
int *ptr2, *ptr3;
ref1 = source();
sink(ref1); // tainted
sink(arr1[5]); // tainted [DETECTED BY IR ONLY]
ptr2 = &(arr2[5]);
*ptr2 = source();
sink(*ptr2); // tainted [DETECTED BY IR ONLY]
sink(arr2[5]); // tainted [DETECTED BY IR ONLY]
ptr3 = arr3;
ptr3[5] = source();
sink(ptr3[5]); // tainted [DETECTED BY IR ONLY]
sink(arr3[5]); // tainted [DETECTED BY IR ONLY]
}

View File

@@ -1,3 +1,127 @@
| arrayassignment.cpp:9:9:9:10 | 0 | arrayassignment.cpp:10:14:10:14 | x | |
| arrayassignment.cpp:9:9:9:10 | 0 | arrayassignment.cpp:11:15:11:15 | x | |
| arrayassignment.cpp:9:9:9:10 | 0 | arrayassignment.cpp:12:13:12:13 | x | |
| arrayassignment.cpp:9:9:9:10 | 0 | arrayassignment.cpp:16:7:16:7 | x | |
| arrayassignment.cpp:10:13:10:14 | & ... | arrayassignment.cpp:14:3:14:5 | p_x | |
| arrayassignment.cpp:10:13:10:14 | & ... | arrayassignment.cpp:17:8:17:10 | p_x | |
| arrayassignment.cpp:10:14:10:14 | x | arrayassignment.cpp:10:13:10:14 | & ... | |
| arrayassignment.cpp:11:14:11:15 | & ... | arrayassignment.cpp:18:8:18:11 | p2_x | |
| arrayassignment.cpp:11:15:11:15 | x | arrayassignment.cpp:11:14:11:15 | & ... | |
| arrayassignment.cpp:12:13:12:13 | x | arrayassignment.cpp:19:7:19:9 | r_x | |
| arrayassignment.cpp:14:3:14:5 | p_x | arrayassignment.cpp:14:2:14:5 | * ... | TAINT |
| arrayassignment.cpp:14:9:14:14 | call to source | arrayassignment.cpp:14:2:14:16 | ... = ... | |
| arrayassignment.cpp:17:8:17:10 | p_x | arrayassignment.cpp:17:7:17:10 | * ... | TAINT |
| arrayassignment.cpp:18:8:18:11 | p2_x | arrayassignment.cpp:18:7:18:11 | * ... | TAINT |
| arrayassignment.cpp:24:9:24:10 | 0 | arrayassignment.cpp:25:14:25:14 | x | |
| arrayassignment.cpp:24:9:24:10 | 0 | arrayassignment.cpp:26:13:26:13 | x | |
| arrayassignment.cpp:24:9:24:10 | 0 | arrayassignment.cpp:27:14:27:14 | x | |
| arrayassignment.cpp:24:9:24:10 | 0 | arrayassignment.cpp:31:7:31:7 | x | |
| arrayassignment.cpp:25:13:25:14 | & ... | arrayassignment.cpp:32:8:32:10 | p_x | |
| arrayassignment.cpp:25:14:25:14 | x | arrayassignment.cpp:25:13:25:14 | & ... | |
| arrayassignment.cpp:27:14:27:14 | x | arrayassignment.cpp:34:7:34:10 | r2_x | |
| arrayassignment.cpp:29:8:29:13 | call to source | arrayassignment.cpp:29:2:29:15 | ... = ... | |
| arrayassignment.cpp:29:8:29:13 | call to source | arrayassignment.cpp:33:7:33:9 | r_x | |
| arrayassignment.cpp:32:8:32:10 | p_x | arrayassignment.cpp:32:7:32:10 | * ... | TAINT |
| arrayassignment.cpp:37:7:37:7 | Unknown literal | arrayassignment.cpp:37:7:37:7 | constructor init of field i | TAINT |
| arrayassignment.cpp:37:7:37:7 | this | arrayassignment.cpp:37:7:37:7 | constructor init of field i [pre-this] | |
| arrayassignment.cpp:40:2:40:6 | this | arrayassignment.cpp:40:12:40:15 | constructor init of field i [pre-this] | |
| arrayassignment.cpp:40:12:40:15 | 0 | arrayassignment.cpp:40:12:40:15 | constructor init of field i | TAINT |
| arrayassignment.cpp:42:7:42:9 | this | arrayassignment.cpp:42:22:42:22 | this | |
| arrayassignment.cpp:52:8:52:9 | call to MyInt | arrayassignment.cpp:54:2:54:3 | mi | |
| arrayassignment.cpp:52:8:52:9 | call to MyInt | arrayassignment.cpp:56:7:56:8 | mi | |
| arrayassignment.cpp:52:8:52:9 | call to MyInt | arrayassignment.cpp:57:7:57:8 | mi | |
| arrayassignment.cpp:54:2:54:3 | mi [post update] | arrayassignment.cpp:56:7:56:8 | mi | |
| arrayassignment.cpp:54:2:54:3 | mi [post update] | arrayassignment.cpp:57:7:57:8 | mi | |
| arrayassignment.cpp:54:2:54:16 | ... = ... | arrayassignment.cpp:54:5:54:5 | i [post update] | |
| arrayassignment.cpp:54:9:54:14 | call to source | arrayassignment.cpp:54:2:54:16 | ... = ... | |
| arrayassignment.cpp:62:8:62:9 | call to MyInt | arrayassignment.cpp:64:2:64:3 | mi | |
| arrayassignment.cpp:62:8:62:9 | call to MyInt | arrayassignment.cpp:66:7:66:8 | mi | |
| arrayassignment.cpp:62:8:62:9 | call to MyInt | arrayassignment.cpp:67:7:67:8 | mi | |
| arrayassignment.cpp:64:2:64:3 | ref arg mi | arrayassignment.cpp:66:7:66:8 | mi | |
| arrayassignment.cpp:64:2:64:3 | ref arg mi | arrayassignment.cpp:67:7:67:8 | mi | |
| arrayassignment.cpp:64:2:64:20 | ... = ... | arrayassignment.cpp:64:5:64:7 | call to get [post update] | |
| arrayassignment.cpp:64:13:64:18 | call to source | arrayassignment.cpp:64:2:64:20 | ... = ... | |
| arrayassignment.cpp:72:8:72:9 | call to MyInt | arrayassignment.cpp:74:2:74:3 | mi | |
| arrayassignment.cpp:72:8:72:9 | call to MyInt | arrayassignment.cpp:75:8:75:9 | mi | |
| arrayassignment.cpp:72:8:72:9 | call to MyInt | arrayassignment.cpp:77:7:77:8 | mi | |
| arrayassignment.cpp:72:8:72:9 | call to MyInt | arrayassignment.cpp:78:7:78:8 | mi | |
| arrayassignment.cpp:72:12:72:14 | call to MyInt | arrayassignment.cpp:75:2:75:4 | mi2 | |
| arrayassignment.cpp:72:12:72:14 | call to MyInt | arrayassignment.cpp:79:7:79:9 | mi2 | |
| arrayassignment.cpp:72:12:72:14 | call to MyInt | arrayassignment.cpp:80:7:80:9 | mi2 | |
| arrayassignment.cpp:74:2:74:3 | ref arg mi | arrayassignment.cpp:75:8:75:9 | mi | |
| arrayassignment.cpp:74:2:74:3 | ref arg mi | arrayassignment.cpp:77:7:77:8 | mi | |
| arrayassignment.cpp:74:2:74:3 | ref arg mi | arrayassignment.cpp:78:7:78:8 | mi | |
| arrayassignment.cpp:75:2:75:4 | ref arg mi2 | arrayassignment.cpp:79:7:79:9 | mi2 | |
| arrayassignment.cpp:75:2:75:4 | ref arg mi2 | arrayassignment.cpp:80:7:80:9 | mi2 | |
| arrayassignment.cpp:75:8:75:9 | mi | arrayassignment.cpp:75:2:75:4 | ref arg mi2 | TAINT |
| arrayassignment.cpp:75:8:75:9 | mi | arrayassignment.cpp:75:6:75:6 | call to operator= | TAINT |
| arrayassignment.cpp:86:2:86:8 | this | arrayassignment.cpp:86:14:86:24 | constructor init of field values [pre-this] | |
| arrayassignment.cpp:86:14:86:24 | {...} | arrayassignment.cpp:86:14:86:24 | constructor init of field values | TAINT |
| arrayassignment.cpp:86:22:86:22 | 0 | arrayassignment.cpp:86:14:86:24 | {...} | TAINT |
| arrayassignment.cpp:88:7:88:9 | this | arrayassignment.cpp:88:27:88:32 | this | |
| arrayassignment.cpp:88:15:88:15 | i | arrayassignment.cpp:88:34:88:34 | i | |
| arrayassignment.cpp:88:27:88:32 | values | arrayassignment.cpp:88:27:88:35 | access to array | TAINT |
| arrayassignment.cpp:88:34:88:34 | i | arrayassignment.cpp:88:27:88:35 | access to array | TAINT |
| arrayassignment.cpp:97:10:97:11 | call to MyArray | arrayassignment.cpp:99:2:99:3 | ma | |
| arrayassignment.cpp:97:10:97:11 | call to MyArray | arrayassignment.cpp:101:7:101:8 | ma | |
| arrayassignment.cpp:99:2:99:3 | ma [post update] | arrayassignment.cpp:101:7:101:8 | ma | |
| arrayassignment.cpp:99:2:99:13 | access to array [post update] | arrayassignment.cpp:99:5:99:10 | values [inner post update] | |
| arrayassignment.cpp:99:2:99:24 | ... = ... | arrayassignment.cpp:99:2:99:13 | access to array [post update] | |
| arrayassignment.cpp:99:5:99:10 | values | arrayassignment.cpp:99:2:99:13 | access to array | TAINT |
| arrayassignment.cpp:99:12:99:12 | 0 | arrayassignment.cpp:99:2:99:13 | access to array | TAINT |
| arrayassignment.cpp:99:17:99:22 | call to source | arrayassignment.cpp:99:2:99:24 | ... = ... | |
| arrayassignment.cpp:101:10:101:15 | values | arrayassignment.cpp:101:7:101:18 | access to array | TAINT |
| arrayassignment.cpp:101:17:101:17 | 0 | arrayassignment.cpp:101:7:101:18 | access to array | TAINT |
| arrayassignment.cpp:106:10:106:11 | call to MyArray | arrayassignment.cpp:108:2:108:3 | ma | |
| arrayassignment.cpp:106:10:106:11 | call to MyArray | arrayassignment.cpp:110:7:110:8 | ma | |
| arrayassignment.cpp:108:2:108:3 | ref arg ma | arrayassignment.cpp:110:7:110:8 | ma | |
| arrayassignment.cpp:108:2:108:21 | ... = ... | arrayassignment.cpp:108:5:108:7 | call to get [post update] | |
| arrayassignment.cpp:108:14:108:19 | call to source | arrayassignment.cpp:108:2:108:21 | ... = ... | |
| arrayassignment.cpp:115:10:115:11 | call to MyArray | arrayassignment.cpp:117:2:117:3 | ma | |
| arrayassignment.cpp:115:10:115:11 | call to MyArray | arrayassignment.cpp:118:8:118:9 | ma | |
| arrayassignment.cpp:115:10:115:11 | call to MyArray | arrayassignment.cpp:120:7:120:8 | ma | |
| arrayassignment.cpp:117:2:117:3 | ref arg ma | arrayassignment.cpp:118:8:118:9 | ma | |
| arrayassignment.cpp:117:2:117:3 | ref arg ma | arrayassignment.cpp:120:7:120:8 | ma | |
| arrayassignment.cpp:117:2:117:17 | ... = ... | arrayassignment.cpp:117:4:117:4 | call to operator[] [post update] | |
| arrayassignment.cpp:117:10:117:15 | call to source | arrayassignment.cpp:117:2:117:17 | ... = ... | |
| arrayassignment.cpp:118:8:118:9 | ma | arrayassignment.cpp:118:2:118:9 | ... = ... | |
| arrayassignment.cpp:118:8:118:9 | ma | arrayassignment.cpp:121:7:121:9 | ma2 | |
| arrayassignment.cpp:128:16:128:19 | {...} | arrayassignment.cpp:131:14:131:17 | arr1 | |
| arrayassignment.cpp:128:16:128:19 | {...} | arrayassignment.cpp:136:7:136:10 | arr1 | |
| arrayassignment.cpp:128:18:128:18 | 0 | arrayassignment.cpp:128:16:128:19 | {...} | TAINT |
| arrayassignment.cpp:129:16:129:19 | {...} | arrayassignment.cpp:138:11:138:14 | arr2 | |
| arrayassignment.cpp:129:16:129:19 | {...} | arrayassignment.cpp:141:7:141:10 | arr2 | |
| arrayassignment.cpp:129:18:129:18 | 0 | arrayassignment.cpp:129:16:129:19 | {...} | TAINT |
| arrayassignment.cpp:130:16:130:19 | {...} | arrayassignment.cpp:143:9:143:12 | arr3 | |
| arrayassignment.cpp:130:16:130:19 | {...} | arrayassignment.cpp:146:7:146:10 | arr3 | |
| arrayassignment.cpp:130:18:130:18 | 0 | arrayassignment.cpp:130:16:130:19 | {...} | TAINT |
| arrayassignment.cpp:131:14:131:17 | arr1 | arrayassignment.cpp:131:14:131:20 | access to array | TAINT |
| arrayassignment.cpp:131:19:131:19 | 5 | arrayassignment.cpp:131:14:131:20 | access to array | TAINT |
| arrayassignment.cpp:134:9:134:14 | call to source | arrayassignment.cpp:134:2:134:16 | ... = ... | |
| arrayassignment.cpp:134:9:134:14 | call to source | arrayassignment.cpp:135:7:135:10 | ref1 | |
| arrayassignment.cpp:136:7:136:10 | arr1 | arrayassignment.cpp:136:7:136:13 | access to array | TAINT |
| arrayassignment.cpp:136:12:136:12 | 5 | arrayassignment.cpp:136:7:136:13 | access to array | TAINT |
| arrayassignment.cpp:138:9:138:18 | & ... | arrayassignment.cpp:138:2:138:18 | ... = ... | |
| arrayassignment.cpp:138:9:138:18 | & ... | arrayassignment.cpp:139:3:139:6 | ptr2 | |
| arrayassignment.cpp:138:9:138:18 | & ... | arrayassignment.cpp:140:8:140:11 | ptr2 | |
| arrayassignment.cpp:138:11:138:14 | arr2 | arrayassignment.cpp:138:11:138:17 | access to array | TAINT |
| arrayassignment.cpp:138:11:138:17 | access to array | arrayassignment.cpp:138:9:138:18 | & ... | |
| arrayassignment.cpp:138:16:138:16 | 5 | arrayassignment.cpp:138:11:138:17 | access to array | TAINT |
| arrayassignment.cpp:139:3:139:6 | ptr2 | arrayassignment.cpp:139:2:139:6 | * ... | TAINT |
| arrayassignment.cpp:139:10:139:15 | call to source | arrayassignment.cpp:139:2:139:17 | ... = ... | |
| arrayassignment.cpp:140:8:140:11 | ptr2 | arrayassignment.cpp:140:7:140:11 | * ... | TAINT |
| arrayassignment.cpp:141:7:141:10 | arr2 | arrayassignment.cpp:141:7:141:13 | access to array | TAINT |
| arrayassignment.cpp:141:12:141:12 | 5 | arrayassignment.cpp:141:7:141:13 | access to array | TAINT |
| arrayassignment.cpp:143:9:143:12 | arr3 | arrayassignment.cpp:143:2:143:12 | ... = ... | |
| arrayassignment.cpp:143:9:143:12 | arr3 | arrayassignment.cpp:144:2:144:5 | ptr3 | |
| arrayassignment.cpp:143:9:143:12 | arr3 | arrayassignment.cpp:145:7:145:10 | ptr3 | |
| arrayassignment.cpp:144:2:144:5 | ptr3 | arrayassignment.cpp:144:2:144:8 | access to array | TAINT |
| arrayassignment.cpp:144:7:144:7 | 5 | arrayassignment.cpp:144:2:144:8 | access to array | TAINT |
| arrayassignment.cpp:144:12:144:17 | call to source | arrayassignment.cpp:144:2:144:19 | ... = ... | |
| arrayassignment.cpp:145:7:145:10 | ptr3 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT |
| arrayassignment.cpp:145:12:145:12 | 5 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT |
| arrayassignment.cpp:146:7:146:10 | arr3 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT |
| arrayassignment.cpp:146:12:146:12 | 5 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT |
| copyableclass.cpp:8:2:8:16 | this | copyableclass.cpp:8:28:8:32 | constructor init of field v [pre-this] | |
| copyableclass.cpp:8:22:8:23 | _v | copyableclass.cpp:8:30:8:31 | _v | |
| copyableclass.cpp:8:30:8:31 | _v | copyableclass.cpp:8:28:8:32 | constructor init of field v | TAINT |
@@ -313,10 +437,12 @@
| movableclass.cpp:65:13:65:18 | call to source | movableclass.cpp:65:13:65:20 | call to MyMovableClass | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:8:65:9 | ref arg s3 | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:11:65:11 | call to operator= | TAINT |
| stl.h:137:30:137:40 | call to allocator | stl.h:137:21:137:41 | noexcept(...) | TAINT |
| stl.h:137:30:137:40 | call to allocator | stl.h:137:21:137:41 | noexcept(...) | TAINT |
| stl.h:137:30:137:40 | call to allocator | stl.h:137:21:137:41 | noexcept(...) | TAINT |
| stl.h:137:53:137:63 | 0 | stl.h:137:46:137:64 | (no string representation) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:53:139:63 | 0 | stl.h:139:46:139:64 | (no string representation) | TAINT |
| string.cpp:24:12:24:17 | call to source | string.cpp:28:7:28:7 | a | |
| string.cpp:25:16:25:20 | 123 | string.cpp:25:16:25:21 | call to basic_string | TAINT |
| string.cpp:25:16:25:21 | call to basic_string | string.cpp:29:7:29:7 | b | |
@@ -717,6 +843,20 @@
| string.cpp:337:9:337:9 | a | string.cpp:337:10:337:10 | call to operator[] | TAINT |
| string.cpp:337:9:337:9 | ref arg a | string.cpp:339:7:339:7 | a | |
| string.cpp:337:10:337:10 | call to operator[] | string.cpp:337:2:337:12 | ... = ... | |
| string.cpp:346:18:346:22 | 123 | string.cpp:346:18:346:23 | call to basic_string | TAINT |
| string.cpp:346:18:346:23 | call to basic_string | string.cpp:348:2:348:4 | str | |
| string.cpp:346:18:346:23 | call to basic_string | string.cpp:349:7:349:9 | str | |
| string.cpp:346:18:346:23 | call to basic_string | string.cpp:350:7:350:9 | str | |
| string.cpp:348:2:348:4 | ref arg str | string.cpp:349:7:349:9 | str | |
| string.cpp:348:2:348:4 | ref arg str | string.cpp:350:7:350:9 | str | |
| string.cpp:348:2:348:4 | str | string.cpp:348:6:348:9 | call to data | TAINT |
| string.cpp:348:2:348:14 | access to array [post update] | string.cpp:348:6:348:9 | call to data [inner post update] | |
| string.cpp:348:2:348:34 | ... = ... | string.cpp:348:2:348:14 | access to array [post update] | |
| string.cpp:348:6:348:9 | call to data | string.cpp:348:2:348:14 | access to array | TAINT |
| string.cpp:348:6:348:9 | call to data [inner post update] | string.cpp:348:2:348:4 | ref arg str | TAINT |
| string.cpp:348:13:348:13 | 1 | string.cpp:348:2:348:14 | access to array | TAINT |
| string.cpp:348:18:348:32 | call to source | string.cpp:348:2:348:34 | ... = ... | |
| string.cpp:350:7:350:9 | str | string.cpp:350:11:350:14 | call to data | TAINT |
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:16:2:16:4 | ss1 | |
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:22:7:22:9 | ss1 | |
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:27:7:27:9 | ss1 | |
@@ -1851,14 +1991,17 @@
| vector.cpp:74:2:74:3 | ref arg v6 | vector.cpp:75:7:75:8 | v6 | |
| vector.cpp:74:2:74:3 | ref arg v6 | vector.cpp:76:7:76:8 | v6 | |
| vector.cpp:74:2:74:3 | ref arg v6 | vector.cpp:101:1:101:1 | v6 | |
| vector.cpp:74:2:74:3 | v6 | vector.cpp:74:5:74:8 | call to data | TAINT |
| vector.cpp:74:2:74:13 | access to array [post update] | vector.cpp:74:5:74:8 | call to data [inner post update] | |
| vector.cpp:74:2:74:24 | ... = ... | vector.cpp:74:2:74:13 | access to array [post update] | |
| vector.cpp:74:5:74:8 | call to data | vector.cpp:74:2:74:13 | access to array | TAINT |
| vector.cpp:74:5:74:8 | call to data [inner post update] | vector.cpp:74:2:74:3 | ref arg v6 | TAINT |
| vector.cpp:74:12:74:12 | 2 | vector.cpp:74:2:74:13 | access to array | TAINT |
| vector.cpp:74:17:74:22 | call to source | vector.cpp:74:2:74:24 | ... = ... | |
| vector.cpp:75:7:75:8 | ref arg v6 | vector.cpp:76:7:76:8 | v6 | |
| vector.cpp:75:7:75:8 | ref arg v6 | vector.cpp:101:1:101:1 | v6 | |
| vector.cpp:76:7:76:8 | ref arg v6 | vector.cpp:101:1:101:1 | v6 | |
| vector.cpp:76:7:76:8 | v6 | vector.cpp:76:10:76:13 | call to data | TAINT |
| vector.cpp:76:10:76:13 | call to data | vector.cpp:76:7:76:18 | access to array | TAINT |
| vector.cpp:76:17:76:17 | 2 | vector.cpp:76:7:76:18 | access to array | TAINT |
| vector.cpp:79:33:79:34 | v7 | vector.cpp:80:41:80:43 | v7c | |
@@ -2209,3 +2352,148 @@
| vector.cpp:212:8:212:9 | ref arg ff | vector.cpp:213:2:213:2 | ff | |
| vector.cpp:212:10:212:10 | call to operator[] [post update] | vector.cpp:212:8:212:9 | ref arg ff | TAINT |
| vector.cpp:212:14:212:15 | vs | vector.cpp:212:16:212:16 | call to operator[] | TAINT |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:237:2:237:3 | v1 | |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:241:7:241:8 | v1 | |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:249:13:249:14 | v1 | |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:249:25:249:26 | v1 | |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:235:23:235:24 | call to vector | vector.cpp:238:2:238:3 | v2 | |
| vector.cpp:235:23:235:24 | call to vector | vector.cpp:242:7:242:8 | v2 | |
| vector.cpp:235:23:235:24 | call to vector | vector.cpp:277:1:277:1 | v2 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:239:2:239:3 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:243:7:243:8 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:250:13:250:14 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:250:25:250:26 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:237:2:237:3 | ref arg v1 | vector.cpp:241:7:241:8 | v1 | |
| vector.cpp:237:2:237:3 | ref arg v1 | vector.cpp:249:13:249:14 | v1 | |
| vector.cpp:237:2:237:3 | ref arg v1 | vector.cpp:249:25:249:26 | v1 | |
| vector.cpp:237:2:237:3 | ref arg v1 | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:237:17:237:17 | 0 | vector.cpp:237:2:237:3 | ref arg v1 | TAINT |
| vector.cpp:238:2:238:3 | ref arg v2 | vector.cpp:242:7:242:8 | v2 | |
| vector.cpp:238:2:238:3 | ref arg v2 | vector.cpp:277:1:277:1 | v2 | |
| vector.cpp:238:17:238:30 | call to source | vector.cpp:238:2:238:3 | ref arg v2 | TAINT |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:243:7:243:8 | v3 | |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:250:13:250:14 | v3 | |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:250:25:250:26 | v3 | |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:239:15:239:20 | call to source | vector.cpp:239:2:239:3 | ref arg v3 | TAINT |
| vector.cpp:241:7:241:8 | ref arg v1 | vector.cpp:249:13:249:14 | v1 | |
| vector.cpp:241:7:241:8 | ref arg v1 | vector.cpp:249:25:249:26 | v1 | |
| vector.cpp:241:7:241:8 | ref arg v1 | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:242:7:242:8 | ref arg v2 | vector.cpp:277:1:277:1 | v2 | |
| vector.cpp:243:7:243:8 | ref arg v3 | vector.cpp:250:13:250:14 | v3 | |
| vector.cpp:243:7:243:8 | ref arg v3 | vector.cpp:250:25:250:26 | v3 | |
| vector.cpp:243:7:243:8 | ref arg v3 | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:243:7:243:8 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:246:20:246:21 | call to vector | vector.cpp:249:3:249:4 | v4 | |
| vector.cpp:246:20:246:21 | call to vector | vector.cpp:257:8:257:9 | v4 | |
| vector.cpp:246:20:246:21 | call to vector | vector.cpp:262:2:262:2 | v4 | |
| vector.cpp:246:24:246:25 | call to vector | vector.cpp:250:3:250:4 | v5 | |
| vector.cpp:246:24:246:25 | call to vector | vector.cpp:258:8:258:9 | v5 | |
| vector.cpp:246:24:246:25 | call to vector | vector.cpp:262:2:262:2 | v5 | |
| vector.cpp:246:28:246:29 | call to vector | vector.cpp:255:3:255:4 | v6 | |
| vector.cpp:246:28:246:29 | call to vector | vector.cpp:261:8:261:9 | v6 | |
| vector.cpp:246:28:246:29 | call to vector | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:249:3:249:4 | ref arg v4 | vector.cpp:257:8:257:9 | v4 | |
| vector.cpp:249:3:249:4 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | |
| vector.cpp:249:13:249:14 | ref arg v1 | vector.cpp:249:25:249:26 | v1 | |
| vector.cpp:249:13:249:14 | ref arg v1 | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:249:25:249:26 | ref arg v1 | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:250:3:250:4 | ref arg v5 | vector.cpp:258:8:258:9 | v5 | |
| vector.cpp:250:3:250:4 | ref arg v5 | vector.cpp:262:2:262:2 | v5 | |
| vector.cpp:250:13:250:14 | ref arg v3 | vector.cpp:250:25:250:26 | v3 | |
| vector.cpp:250:13:250:14 | ref arg v3 | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:250:13:250:14 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:250:25:250:26 | ref arg v3 | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:250:25:250:26 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:251:8:251:9 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:251:3:251:17 | ... = ... | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:252:3:252:4 | i1 | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:253:8:253:9 | i1 | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:255:13:255:14 | i1 | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:259:8:259:9 | i1 | |
| vector.cpp:252:3:252:4 | ref arg i1 | vector.cpp:253:8:253:9 | i1 | |
| vector.cpp:252:3:252:4 | ref arg i1 | vector.cpp:255:13:255:14 | i1 | |
| vector.cpp:252:3:252:4 | ref arg i1 | vector.cpp:259:8:259:9 | i1 | |
| vector.cpp:253:8:253:9 | i1 | vector.cpp:253:3:253:9 | ... = ... | |
| vector.cpp:253:8:253:9 | i1 | vector.cpp:254:3:254:4 | i2 | |
| vector.cpp:253:8:253:9 | i1 | vector.cpp:255:17:255:18 | i2 | |
| vector.cpp:253:8:253:9 | i1 | vector.cpp:260:8:260:9 | i2 | |
| vector.cpp:254:3:254:4 | ref arg i2 | vector.cpp:255:17:255:18 | i2 | |
| vector.cpp:254:3:254:4 | ref arg i2 | vector.cpp:260:8:260:9 | i2 | |
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:261:8:261:9 | v6 | |
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:257:8:257:9 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | |
| vector.cpp:258:8:258:9 | ref arg v5 | vector.cpp:262:2:262:2 | v5 | |
| vector.cpp:261:8:261:9 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:269:3:269:4 | v7 | |
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:273:8:273:9 | v7 | |
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:276:2:276:2 | v7 | |
| vector.cpp:266:24:266:25 | call to vector | vector.cpp:270:3:270:4 | v8 | |
| vector.cpp:266:24:266:25 | call to vector | vector.cpp:274:8:274:9 | v8 | |
| vector.cpp:266:24:266:25 | call to vector | vector.cpp:276:2:276:2 | v8 | |
| vector.cpp:267:28:267:29 | call to vector | vector.cpp:271:3:271:4 | v9 | |
| vector.cpp:267:28:267:29 | call to vector | vector.cpp:275:8:275:9 | v9 | |
| vector.cpp:267:28:267:29 | call to vector | vector.cpp:276:2:276:2 | v9 | |
| vector.cpp:269:3:269:4 | ref arg v7 | vector.cpp:273:8:273:9 | v7 | |
| vector.cpp:269:3:269:4 | ref arg v7 | vector.cpp:276:2:276:2 | v7 | |
| vector.cpp:269:18:269:31 | call to source | vector.cpp:269:3:269:4 | ref arg v7 | TAINT |
| vector.cpp:270:3:270:4 | ref arg v8 | vector.cpp:274:8:274:9 | v8 | |
| vector.cpp:270:3:270:4 | ref arg v8 | vector.cpp:276:2:276:2 | v8 | |
| vector.cpp:270:18:270:35 | call to source | vector.cpp:270:3:270:4 | ref arg v8 | TAINT |
| vector.cpp:271:3:271:4 | ref arg v9 | vector.cpp:275:8:275:9 | v9 | |
| vector.cpp:271:3:271:4 | ref arg v9 | vector.cpp:276:2:276:2 | v9 | |
| vector.cpp:271:18:271:34 | call to source | vector.cpp:271:3:271:4 | ref arg v9 | TAINT |
| vector.cpp:273:8:273:9 | ref arg v7 | vector.cpp:276:2:276:2 | v7 | |
| vector.cpp:274:8:274:9 | ref arg v8 | vector.cpp:276:2:276:2 | v8 | |
| vector.cpp:275:8:275:9 | ref arg v9 | vector.cpp:276:2:276:2 | v9 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:284:2:284:3 | v1 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:285:7:285:8 | v1 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:286:7:286:8 | v1 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:287:7:287:8 | v1 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:289:4:289:5 | v2 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:290:7:290:8 | v2 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:291:7:291:8 | v2 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:292:7:292:8 | v2 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:284:2:284:3 | ref arg v1 | vector.cpp:285:7:285:8 | v1 | |
| vector.cpp:284:2:284:3 | ref arg v1 | vector.cpp:286:7:286:8 | v1 | |
| vector.cpp:284:2:284:3 | ref arg v1 | vector.cpp:287:7:287:8 | v1 | |
| vector.cpp:284:2:284:3 | ref arg v1 | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:284:15:284:20 | call to source | vector.cpp:284:2:284:3 | ref arg v1 | TAINT |
| vector.cpp:285:7:285:8 | ref arg v1 | vector.cpp:286:7:286:8 | v1 | |
| vector.cpp:285:7:285:8 | ref arg v1 | vector.cpp:287:7:287:8 | v1 | |
| vector.cpp:285:7:285:8 | ref arg v1 | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:286:7:286:8 | ref arg v1 | vector.cpp:287:7:287:8 | v1 | |
| vector.cpp:286:7:286:8 | ref arg v1 | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:286:7:286:8 | v1 | vector.cpp:286:10:286:13 | call to data | TAINT |
| vector.cpp:286:10:286:13 | ref arg call to data | vector.cpp:286:7:286:8 | ref arg v1 | TAINT |
| vector.cpp:287:7:287:8 | ref arg v1 | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:287:7:287:8 | v1 | vector.cpp:287:10:287:13 | call to data | TAINT |
| vector.cpp:287:10:287:13 | call to data | vector.cpp:287:7:287:18 | access to array | TAINT |
| vector.cpp:287:17:287:17 | 2 | vector.cpp:287:7:287:18 | access to array | TAINT |
| vector.cpp:289:2:289:13 | * ... [post update] | vector.cpp:289:7:289:10 | call to data [inner post update] | |
| vector.cpp:289:2:289:32 | ... = ... | vector.cpp:289:2:289:13 | * ... [post update] | |
| vector.cpp:289:4:289:5 | ref arg v2 | vector.cpp:290:7:290:8 | v2 | |
| vector.cpp:289:4:289:5 | ref arg v2 | vector.cpp:291:7:291:8 | v2 | |
| vector.cpp:289:4:289:5 | ref arg v2 | vector.cpp:292:7:292:8 | v2 | |
| vector.cpp:289:4:289:5 | ref arg v2 | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:289:4:289:5 | v2 | vector.cpp:289:7:289:10 | call to data | TAINT |
| vector.cpp:289:7:289:10 | call to data | vector.cpp:289:2:289:13 | * ... | TAINT |
| vector.cpp:289:7:289:10 | call to data [inner post update] | vector.cpp:289:4:289:5 | ref arg v2 | TAINT |
| vector.cpp:289:17:289:30 | call to source | vector.cpp:289:2:289:32 | ... = ... | |
| vector.cpp:290:7:290:8 | ref arg v2 | vector.cpp:291:7:291:8 | v2 | |
| vector.cpp:290:7:290:8 | ref arg v2 | vector.cpp:292:7:292:8 | v2 | |
| vector.cpp:290:7:290:8 | ref arg v2 | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:291:7:291:8 | ref arg v2 | vector.cpp:292:7:292:8 | v2 | |
| vector.cpp:291:7:291:8 | ref arg v2 | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:291:7:291:8 | v2 | vector.cpp:291:10:291:13 | call to data | TAINT |
| vector.cpp:291:10:291:13 | ref arg call to data | vector.cpp:291:7:291:8 | ref arg v2 | TAINT |
| vector.cpp:292:7:292:8 | ref arg v2 | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:292:7:292:8 | v2 | vector.cpp:292:10:292:13 | call to data | TAINT |
| vector.cpp:292:10:292:13 | call to data | vector.cpp:292:7:292:18 | access to array | TAINT |
| vector.cpp:292:17:292:17 | 2 | vector.cpp:292:7:292:18 | access to array | TAINT |

View File

@@ -11,12 +11,14 @@ namespace std
struct ptrdiff_t;
template <class iterator_category,
template <class Category,
class value_type,
class difference_type = ptrdiff_t,
class pointer_type = value_type*,
class reference_type = value_type&>
struct iterator {
typedef Category iterator_category;
iterator &operator++();
iterator operator++(int);
bool operator==(iterator other) const;
@@ -142,6 +144,10 @@ namespace std {
vector& operator=(const vector& x);
vector& operator=(vector&& x) noexcept/*(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value)*/;
template<class InputIterator, class IteratorCategory = typename InputIterator::iterator_category> void assign(InputIterator first, InputIterator last);
// use of `iterator_category` makes sure InputIterator is (probably) an iterator, and not an `int` or
// similar that should match a different overload (SFINAE).
void assign(size_type n, const T& u);
iterator begin() noexcept;
const_iterator begin() const noexcept;

View File

@@ -340,3 +340,12 @@ void test_string_at()
sink(b); // tainted
sink(c); // tainted
}
void test_string_data_more()
{
std::string str("123");
str.data()[1] = ns_char::source();
sink(str); // tainted
sink(str.data()); // tainted
}

View File

@@ -1,3 +1,8 @@
| arrayassignment.cpp:33:7:33:9 | r_x | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:57:10:57:12 | call to get | arrayassignment.cpp:54:9:54:14 | call to source |
| arrayassignment.cpp:67:10:67:12 | call to get | arrayassignment.cpp:64:13:64:18 | call to source |
| arrayassignment.cpp:101:7:101:18 | access to array | arrayassignment.cpp:99:17:99:22 | call to source |
| arrayassignment.cpp:135:7:135:10 | ref1 | arrayassignment.cpp:134:9:134:14 | call to source |
| copyableclass.cpp:40:8:40:9 | s1 | copyableclass.cpp:34:22:34:27 | call to source |
| copyableclass.cpp:41:8:41:9 | s2 | copyableclass.cpp:35:24:35:29 | call to source |
| copyableclass.cpp:42:8:42:9 | s3 | copyableclass.cpp:34:22:34:27 | call to source |
@@ -94,6 +99,8 @@
| string.cpp:339:7:339:7 | a | string.cpp:335:9:335:23 | call to source |
| string.cpp:340:7:340:7 | b | string.cpp:336:12:336:26 | call to source |
| string.cpp:341:7:341:7 | c | string.cpp:335:9:335:23 | call to source |
| string.cpp:349:7:349:9 | str | string.cpp:348:18:348:32 | call to source |
| string.cpp:350:11:350:14 | call to data | string.cpp:348:18:348:32 | call to source |
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |
@@ -218,6 +225,8 @@
| vector.cpp:70:7:70:8 | v5 | vector.cpp:69:15:69:20 | call to source |
| vector.cpp:71:10:71:14 | call to front | vector.cpp:69:15:69:20 | call to source |
| vector.cpp:72:10:72:13 | call to back | vector.cpp:69:15:69:20 | call to source |
| vector.cpp:75:7:75:8 | v6 | vector.cpp:74:17:74:22 | call to source |
| vector.cpp:76:7:76:18 | access to array | vector.cpp:74:17:74:22 | call to source |
| vector.cpp:97:7:97:8 | v9 | vector.cpp:96:13:96:18 | call to source |
| vector.cpp:98:10:98:11 | call to at | vector.cpp:96:13:96:18 | call to source |
| vector.cpp:99:10:99:11 | call to at | vector.cpp:96:13:96:18 | call to source |
@@ -237,3 +246,14 @@
| vector.cpp:171:13:171:13 | call to operator[] | vector.cpp:170:14:170:19 | call to source |
| vector.cpp:180:13:180:13 | call to operator[] | vector.cpp:179:14:179:19 | call to source |
| vector.cpp:201:13:201:13 | call to operator[] | vector.cpp:200:14:200:19 | call to source |
| vector.cpp:242:7:242:8 | v2 | vector.cpp:238:17:238:30 | call to source |
| vector.cpp:243:7:243:8 | v3 | vector.cpp:239:15:239:20 | call to source |
| vector.cpp:273:8:273:9 | v7 | vector.cpp:269:18:269:31 | call to source |
| vector.cpp:274:8:274:9 | v8 | vector.cpp:270:18:270:35 | call to source |
| vector.cpp:275:8:275:9 | v9 | vector.cpp:271:18:271:34 | call to source |
| vector.cpp:285:7:285:8 | v1 | vector.cpp:284:15:284:20 | call to source |
| vector.cpp:286:10:286:13 | call to data | vector.cpp:284:15:284:20 | call to source |
| vector.cpp:287:7:287:18 | access to array | vector.cpp:284:15:284:20 | call to source |
| vector.cpp:290:7:290:8 | v2 | vector.cpp:289:17:289:30 | call to source |
| vector.cpp:291:10:291:13 | call to data | vector.cpp:289:17:289:30 | call to source |
| vector.cpp:292:7:292:18 | access to array | vector.cpp:289:17:289:30 | call to source |

View File

@@ -1,3 +1,21 @@
| arrayassignment.cpp:16:7:16:7 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:17:7:17:10 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:18:7:18:11 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:19:7:19:9 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:31:7:31:7 | arrayassignment.cpp:29:8:29:13 | IR only |
| arrayassignment.cpp:32:7:32:10 | arrayassignment.cpp:29:8:29:13 | IR only |
| arrayassignment.cpp:34:7:34:10 | arrayassignment.cpp:29:8:29:13 | IR only |
| arrayassignment.cpp:56:7:56:8 | arrayassignment.cpp:54:9:54:14 | IR only |
| arrayassignment.cpp:57:10:57:12 | arrayassignment.cpp:54:9:54:14 | AST only |
| arrayassignment.cpp:57:10:57:15 | arrayassignment.cpp:54:9:54:14 | IR only |
| arrayassignment.cpp:66:7:66:8 | arrayassignment.cpp:64:13:64:18 | IR only |
| arrayassignment.cpp:67:10:67:12 | arrayassignment.cpp:64:13:64:18 | AST only |
| arrayassignment.cpp:67:10:67:15 | arrayassignment.cpp:64:13:64:18 | IR only |
| arrayassignment.cpp:136:7:136:13 | arrayassignment.cpp:134:9:134:14 | IR only |
| arrayassignment.cpp:140:7:140:11 | arrayassignment.cpp:139:10:139:15 | IR only |
| arrayassignment.cpp:141:7:141:13 | arrayassignment.cpp:139:10:139:15 | IR only |
| arrayassignment.cpp:145:7:145:13 | arrayassignment.cpp:144:12:144:17 | IR only |
| arrayassignment.cpp:146:7:146:13 | arrayassignment.cpp:144:12:144:17 | IR only |
| copyableclass.cpp:67:11:67:11 | copyableclass.cpp:67:13:67:18 | AST only |
| copyableclass.cpp:67:11:67:21 | copyableclass.cpp:67:13:67:18 | IR only |
| copyableclass_declonly.cpp:40:8:40:9 | copyableclass_declonly.cpp:34:30:34:35 | AST only |
@@ -81,6 +99,8 @@
| string.cpp:339:7:339:7 | string.cpp:335:9:335:23 | AST only |
| string.cpp:340:7:340:7 | string.cpp:336:12:336:26 | AST only |
| string.cpp:341:7:341:7 | string.cpp:335:9:335:23 | AST only |
| string.cpp:349:7:349:9 | string.cpp:348:18:348:32 | AST only |
| string.cpp:350:11:350:14 | string.cpp:348:18:348:32 | AST only |
| swap1.cpp:78:12:78:16 | swap1.cpp:69:23:69:23 | AST only |
| swap1.cpp:87:13:87:17 | swap1.cpp:82:16:82:21 | AST only |
| swap1.cpp:88:13:88:17 | swap1.cpp:81:27:81:28 | AST only |
@@ -139,6 +159,8 @@
| vector.cpp:70:7:70:8 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:71:10:71:14 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:72:10:72:13 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:75:7:75:8 | vector.cpp:74:17:74:22 | AST only |
| vector.cpp:76:7:76:18 | vector.cpp:74:17:74:22 | AST only |
| vector.cpp:97:7:97:8 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:98:10:98:11 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:99:10:99:11 | vector.cpp:96:13:96:18 | AST only |
@@ -159,3 +181,14 @@
| vector.cpp:171:13:171:13 | vector.cpp:170:14:170:19 | AST only |
| vector.cpp:180:13:180:13 | vector.cpp:179:14:179:19 | AST only |
| vector.cpp:201:13:201:13 | vector.cpp:200:14:200:19 | AST only |
| vector.cpp:242:7:242:8 | vector.cpp:238:17:238:30 | AST only |
| vector.cpp:243:7:243:8 | vector.cpp:239:15:239:20 | AST only |
| vector.cpp:273:8:273:9 | vector.cpp:269:18:269:31 | AST only |
| vector.cpp:274:8:274:9 | vector.cpp:270:18:270:35 | AST only |
| vector.cpp:275:8:275:9 | vector.cpp:271:18:271:34 | AST only |
| vector.cpp:285:7:285:8 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:286:10:286:13 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:287:7:287:18 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:290:7:290:8 | vector.cpp:289:17:289:30 | AST only |
| vector.cpp:291:10:291:13 | vector.cpp:289:17:289:30 | AST only |
| vector.cpp:292:7:292:18 | vector.cpp:289:17:289:30 | AST only |

View File

@@ -1,3 +1,22 @@
| arrayassignment.cpp:16:7:16:7 | x | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:17:7:17:10 | * ... | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:18:7:18:11 | * ... | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:19:7:19:9 | (reference dereference) | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:31:7:31:7 | x | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:32:7:32:10 | * ... | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:33:7:33:9 | (reference dereference) | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:34:7:34:10 | (reference dereference) | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:56:7:56:8 | mi | arrayassignment.cpp:54:9:54:14 | call to source |
| arrayassignment.cpp:57:10:57:15 | (reference dereference) | arrayassignment.cpp:54:9:54:14 | call to source |
| arrayassignment.cpp:66:7:66:8 | mi | arrayassignment.cpp:64:13:64:18 | call to source |
| arrayassignment.cpp:67:10:67:15 | (reference dereference) | arrayassignment.cpp:64:13:64:18 | call to source |
| arrayassignment.cpp:101:7:101:18 | access to array | arrayassignment.cpp:99:17:99:22 | call to source |
| arrayassignment.cpp:135:7:135:10 | (reference dereference) | arrayassignment.cpp:134:9:134:14 | call to source |
| arrayassignment.cpp:136:7:136:13 | access to array | arrayassignment.cpp:134:9:134:14 | call to source |
| arrayassignment.cpp:140:7:140:11 | * ... | arrayassignment.cpp:139:10:139:15 | call to source |
| arrayassignment.cpp:141:7:141:13 | access to array | arrayassignment.cpp:139:10:139:15 | call to source |
| arrayassignment.cpp:145:7:145:13 | access to array | arrayassignment.cpp:144:12:144:17 | call to source |
| arrayassignment.cpp:146:7:146:13 | access to array | arrayassignment.cpp:144:12:144:17 | call to source |
| copyableclass.cpp:40:8:40:9 | s1 | copyableclass.cpp:34:22:34:27 | call to source |
| copyableclass.cpp:41:8:41:9 | s2 | copyableclass.cpp:35:24:35:29 | call to source |
| copyableclass.cpp:42:8:42:9 | s3 | copyableclass.cpp:34:22:34:27 | call to source |

View File

@@ -5,9 +5,9 @@ using namespace std;
int source();
namespace ns_char
namespace ns_int
{
char source();
int source();
}
void sink(int);
@@ -72,8 +72,8 @@ void test_element_taint(int x) {
sink(v5.back()); // tainted
v6.data()[2] = source();
sink(v6); // tainted [NOT DETECTED]
sink(v6.data()[2]); // tainted [NOT DETECTED]
sink(v6); // tainted
sink(v6.data()[2]); // tainted
{
const std::vector<int> &v7c = v7; // (workaround because our iterators don't convert to const_iterator)
@@ -87,7 +87,7 @@ void test_element_taint(int x) {
{
const std::vector<int> &v8c = v8;
std::vector<int>::const_iterator it = v8c.begin();
v8.insert(it, 10, ns_char::source());
v8.insert(it, 10, ns_int::source());
}
sink(v8); // tainted [NOT DETECTED]
sink(v8.front()); // tainted [NOT DETECTED]
@@ -212,3 +212,82 @@ void test_nested_vectors()
sink(ff[0].vs[0]); // tainted [NOT DETECTED]
}
}
void sink(std::vector<int>::iterator &);
typedef int myInt;
typedef float myFloat;
namespace ns_myFloat
{
myFloat source();
}
namespace ns_ci_ptr
{
const int *source();
}
void sink(std::vector<myFloat> &);
void sink(std::vector<const int *> &);
void test_vector_assign() {
std::vector<int> v1, v2, v3;
v1.assign(100, 0);
v2.assign(100, ns_int::source());
v3.push_back(source());
sink(v1);
sink(v2); // tainted
sink(v3); // tainted
{
std::vector<int> v4, v5, v6;
std::vector<int>::iterator i1, i2;
v4.assign(v1.begin(), v1.end());
v5.assign(v3.begin(), v3.end());
i1 = v3.begin();
i1++;
i2 = i1;
i2++;
v6.assign(i1, i2);
sink(v4);
sink(v5); // tainted [NOT DETECTED]
sink(i1); // tainted [NOT DETECTED]
sink(i2); // tainted [NOT DETECTED]
sink(v6); // tainted [NOT DETECTED]
}
{
std::vector<myInt> v7;
std::vector<myFloat> v8;
std::vector<const int *> v9;
v7.assign(100, ns_int::source());
v8.assign(100, ns_myFloat::source());
v9.assign(100, ns_ci_ptr::source());
sink(v7); // tainted
sink(v8); // tainted
sink(v9); // tainted
}
}
void sink(int *);
void test_data_more() {
std::vector<int> v1, v2;
v1.push_back(source());
sink(v1); // tainted
sink(v1.data()); // tainted
sink(v1.data()[2]); // tainted
*(v2.data()) = ns_int::source();
sink(v2); // tainted
sink(v2.data()); // tainted
sink(v2.data()[2]); // tainted
}

View File

@@ -60,7 +60,6 @@ postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
storeIsPostUpdate
argHasPostUpdate
| builtin.cpp:15:31:15:35 | * ... | ArgumentNode is missing PostUpdateNode. |
| conditional_destructors.cpp:30:9:30:13 | call to C1 | ArgumentNode is missing PostUpdateNode. |

View File

@@ -1473,5 +1473,4 @@ postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
storeIsPostUpdate
argHasPostUpdate

View File

@@ -450,15 +450,22 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.GetEnvironmentVariable["ProgramFiles(x86)"] = @"C:\Program Files (x86)";
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = true;
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "C:\\VS1\nC:\\VS2";
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = "10.0\n11.0";
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "C:\\VS1\nC:\\VS2\nC:\\VS3";
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = "10.0\n11.0\n16.0";
var candidates = BuildTools.GetCandidateVcVarsFiles(Actions).ToArray();
Assert.Equal("C:\\VS1\\VC\\vcvarsall.bat", candidates[0].Path);
Assert.Equal(10, candidates[0].ToolsVersion);
Assert.Equal("C:\\VS2\\VC\\vcvarsall.bat", candidates[1].Path);
Assert.Equal(11, candidates[1].ToolsVersion);
Assert.Equal(@"C:\VS3\VC\Auxiliary\Build\vcvars32.bat", candidates[2].Path);
Assert.Equal(16, candidates[2].ToolsVersion);
Assert.Equal(@"C:\VS3\VC\Auxiliary\Build\vcvars64.bat", candidates[3].Path);
Assert.Equal(16, candidates[3].ToolsVersion);
Assert.Equal(@"C:\VS3\Common7\Tools\VsDevCmd.bat", candidates[4].Path);
Assert.Equal(16, candidates[4].ToolsVersion);
Assert.Equal(5, candidates.Length);
}
[Fact]

View File

@@ -11,13 +11,11 @@ namespace Semmle.Autobuild.Shared
{
public readonly int ToolsVersion;
public readonly string Path;
public readonly string[] Platform;
public VcVarsBatFile(string path, int version, params string[] platform)
public VcVarsBatFile(string path, int version)
{
Path = path;
ToolsVersion = version;
Platform = platform;
}
};
@@ -51,12 +49,15 @@ namespace Semmle.Autobuild.Shared
{
if (majorVersion < 15)
{
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\vcvarsall.bat"), majorVersion, "x86");
// Visual Studio 2015 and below
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\vcvarsall.bat"), majorVersion);
}
else
{
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars32.bat"), majorVersion, "x86");
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars64.bat"), majorVersion, "x64");
// Visual Studio 2017 and above
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars32.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars64.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"Common7\Tools\VsDevCmd.bat"), majorVersion);
}
}
// else: Skip installation without a version
@@ -66,10 +67,10 @@ namespace Semmle.Autobuild.Shared
}
// vswhere not installed or didn't run correctly - return legacy Visual Studio versions
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 14.0\VC\vcvarsall.bat"), 14, "x86");
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 12.0\VC\vcvarsall.bat"), 12, "x86");
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 11.0\VC\vcvarsall.bat"), 11, "x86");
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 10.0\VC\vcvarsall.bat"), 10, "x86");
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 14.0\VC\vcvarsall.bat"), 14);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 12.0\VC\vcvarsall.bat"), 12);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 11.0\VC\vcvarsall.bat"), 11);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 10.0\VC\vcvarsall.bat"), 10);
}
/// <summary>

View File

@@ -33,7 +33,7 @@ namespace Semmle.Autobuild.Shared
if (vsTools == null && builder.Actions.IsWindows())
{
builder.Log(Severity.Warning, "Could not find a suitable version of vcvarsall.bat");
builder.Log(Severity.Warning, "Could not find a suitable version of VsDevCmd.bat/vcvarsall.bat");
}
var nuget =

View File

@@ -9,7 +9,7 @@ namespace Semmle.Extraction.CIL
/// </summary>
/// <typeparam name="SrcType">The type of the source.</typeparam>
/// <typeparam name="TargetType">The type of the generated object.</typeparam>
public class CachedFunction<SrcType, TargetType>
public class CachedFunction<SrcType, TargetType> where SrcType : notnull
{
readonly Func<SrcType, TargetType> generator;
readonly Dictionary<SrcType, TargetType> cache;

View File

@@ -14,13 +14,19 @@ namespace Semmle.Extraction.CIL
/// </summary>
partial class Context : IDisposable
{
public Extraction.Context cx;
readonly FileStream stream;
public readonly MetadataReader mdReader;
public readonly PEReader peReader;
public readonly string assemblyPath;
public Entities.Assembly assembly;
public PDB.IPdb pdb;
Entities.Assembly? assemblyNull;
public Extraction.Context cx { get; }
public MetadataReader mdReader { get; }
public PEReader peReader { get; }
public string assemblyPath { get; }
public Entities.Assembly assembly
{
get { return assemblyNull!; }
set { assemblyNull = value; }
}
public PDB.IPdb? pdb { get; }
public Context(Extraction.Context cx, string assemblyPath, bool extractPdbs)
{
@@ -105,7 +111,7 @@ namespace Semmle.Extraction.CIL
/// </summary>
/// <param name="handle">The handle of the method.</param>
/// <returns>The debugging information, or null if the information could not be located.</returns>
public PDB.IMethod GetMethodDebugInformation(MethodDefinitionHandle handle)
public PDB.IMethod? GetMethodDebugInformation(MethodDefinitionHandle handle)
{
return pdb == null ? null : pdb.GetMethod(handle.ToDebugInformationHandle());
}
@@ -125,7 +131,8 @@ namespace Semmle.Extraction.CIL
}
/// <summary>
/// The list of generic type parameters.
/// The list of generic type parameters, including type parameters of
/// containing types.
/// </summary>
public abstract IEnumerable<Entities.Type> TypeParameters { get; }

View File

@@ -47,9 +47,9 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(cx.assemblyPath.Replace("\\", "/"));
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return GetType() == obj.GetType() && Equals(file, ((Assembly)obj).file);
return GetType() == obj?.GetType() && Equals(file, ((Assembly)obj).file);
}
public override int GetHashCode() => 7 * file.GetHashCode();
@@ -63,7 +63,7 @@ namespace Semmle.Extraction.CIL.Entities
get
{
yield return file;
yield return Tuples.assemblies(this, file, FullName, assemblyName.Name, assemblyName.Version.ToString());
yield return Tuples.assemblies(this, file, FullName, assemblyName.Name ?? string.Empty, assemblyName.Version?.ToString() ?? string.Empty);
if (cx.pdb != null)
{
@@ -75,7 +75,7 @@ namespace Semmle.Extraction.CIL.Entities
foreach (var handle in cx.mdReader.TypeDefinitions)
{
IExtractionProduct product = null;
IExtractionProduct? product = null;
try
{
product = cx.Create(handle);
@@ -92,7 +92,7 @@ namespace Semmle.Extraction.CIL.Entities
foreach (var handle in cx.mdReader.MethodDefinitions)
{
IExtractionProduct product = null;
IExtractionProduct? product = null;
try
{
product = cx.Create(handle);

View File

@@ -27,7 +27,7 @@ namespace Semmle.Extraction.CIL.Entities
this.@object = @object;
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is Attribute attribute && handle.Equals(attribute.handle);
}
@@ -58,13 +58,15 @@ namespace Semmle.Extraction.CIL.Entities
for (int index = 0; index < decoded.FixedArguments.Length; ++index)
{
object value = decoded.FixedArguments[index].Value;
yield return Tuples.cil_attribute_positional_argument(this, index, value == null ? "null" : value.ToString());
var stringValue = value?.ToString();
yield return Tuples.cil_attribute_positional_argument(this, index, stringValue ?? "null");
}
foreach (var p in decoded.NamedArguments)
{
object value = p.Value;
yield return Tuples.cil_attribute_named_argument(this, p.Name, value == null ? "null" : value.ToString());
var stringValue = value?.ToString();
yield return Tuples.cil_attribute_named_argument(this, p.Name, stringValue ?? "null");
}
}
}

View File

@@ -36,7 +36,7 @@ namespace Semmle.Extraction.CIL.Entities
public override string IdSuffix => ";cil-event";
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is Event e && handle.Equals(e.handle);
}

View File

@@ -30,7 +30,7 @@ namespace Semmle.Extraction.CIL.Entities
{
get
{
IInstruction try_start, try_end, handler_start;
IInstruction? try_start, try_end, handler_start;
if (!jump_table.TryGetValue(r.TryOffset, out try_start))
throw new InternalError("Failed to retrieve handler");
@@ -44,7 +44,7 @@ namespace Semmle.Extraction.CIL.Entities
if (r.FilterOffset != -1)
{
IInstruction filter_start;
IInstruction? filter_start;
if (!jump_table.TryGetValue(r.FilterOffset, out filter_start))
throw new InternalError("ExceptionRegion filter clause");

View File

@@ -91,7 +91,7 @@ namespace Semmle.Extraction.CIL.Entities
fd = cx.mdReader.GetFieldDefinition(handle);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is DefinitionField field && handle.Equals(field.handle);
}
@@ -153,7 +153,7 @@ namespace Semmle.Extraction.CIL.Entities
declType = (Type)cx.CreateGeneric(gc, mr.Parent);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is MemberReferenceField field && Handle.Equals(field.Handle);
}

View File

@@ -25,9 +25,9 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(Semmle.Extraction.Entities.File.PathAsDatabaseId(path));
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return GetType() == obj.GetType() && path == ((File)obj).path;
return GetType() == obj?.GetType() && path == ((File)obj).path;
}
public override int GetHashCode() => 11 * path.GetHashCode();
@@ -36,7 +36,11 @@ namespace Semmle.Extraction.CIL.Entities
{
get
{
var parent = cx.CreateFolder(System.IO.Path.GetDirectoryName(path));
var directoryName = System.IO.Path.GetDirectoryName(path);
if (directoryName is null)
throw new InternalError($"Directory name for path '{path}' is null.");
var parent = cx.CreateFolder(directoryName);
yield return parent;
yield return Tuples.containerparent(parent, this);
yield return Tuples.files(this, path, System.IO.Path.GetFileNameWithoutExtension(path), System.IO.Path.GetExtension(path).Substring(1));

View File

@@ -41,7 +41,7 @@ namespace Semmle.Extraction.CIL.Entities
}
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is Folder folder && path == folder.path;
}

View File

@@ -365,6 +365,11 @@ namespace Semmle.Extraction.CIL.Entities
{
int offset = Offset;
if (Method.Implementation is null)
{
yield break;
}
yield return Tuples.cil_instruction(this, (int)OpCode, Index, Method.Implementation);
switch (PayloadType)
@@ -414,11 +419,17 @@ namespace Semmle.Extraction.CIL.Entities
break;
case Payload.Arg8:
case Payload.Arg16:
yield return Tuples.cil_access(this, Method.Parameters[(int)UnsignedPayloadValue]);
if (Method.Parameters is object)
{
yield return Tuples.cil_access(this, Method.Parameters[(int)UnsignedPayloadValue]);
}
break;
case Payload.Local8:
case Payload.Local16:
yield return Tuples.cil_access(this, Method.LocalVariables[(int)UnsignedPayloadValue]);
if (Method.LocalVariables is object)
{
yield return Tuples.cil_access(this, Method.LocalVariables[(int)UnsignedPayloadValue]);
}
break;
case Payload.None:
case Payload.Target8:
@@ -439,7 +450,7 @@ namespace Semmle.Extraction.CIL.Entities
public IEnumerable<IExtractionProduct> JumpContents(Dictionary<int, IInstruction> jump_table)
{
int target;
IInstruction inst;
IInstruction? inst;
switch (PayloadType)
{

View File

@@ -23,25 +23,29 @@ namespace Semmle.Extraction.CIL.Entities
/// </summary>
abstract class Method : TypeContainer, IMethod
{
protected MethodTypeParameter[]? genericParams;
protected GenericContext gc;
protected MethodSignature<ITypeSignature> signature;
protected Method(GenericContext gc) : base(gc.cx)
{
this.gc = gc;
}
public override IEnumerable<Type> TypeParameters => gc.TypeParameters.Concat(declaringType.TypeParameters);
public override IEnumerable<Type> TypeParameters => gc.TypeParameters.Concat(DeclaringType.TypeParameters);
public override IEnumerable<Type> MethodParameters =>
genericParams == null ? gc.MethodParameters : gc.MethodParameters.Concat(genericParams);
public int GenericParameterCount => signature.GenericParameterCount;
public virtual Method SourceDeclaration => this;
public virtual Method? SourceDeclaration => this;
public abstract Type DeclaringType { get; }
public abstract string Name { get; }
public virtual IList<LocalVariable> LocalVariables => throw new NotImplementedException();
public IList<Parameter> Parameters { get; private set; }
public virtual IList<LocalVariable>? LocalVariables => throw new NotImplementedException();
public IList<Parameter>? Parameters { get; protected set; }
public override void WriteId(TextWriter trapFile) => WriteMethodId(trapFile, DeclaringType, NameLabel);
@@ -70,19 +74,8 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(')');
}
protected MethodTypeParameter[] genericParams;
protected Type declaringType;
protected GenericContext gc;
protected MethodSignature<ITypeSignature> signature;
protected string name;
public override string IdSuffix => ";cil-method";
protected void PopulateParameters(IEnumerable<Type> parameterTypes)
{
Parameters = MakeParameters(parameterTypes).ToArray();
}
protected IEnumerable<IExtractionProduct> PopulateFlags
{
get
@@ -94,7 +87,7 @@ namespace Semmle.Extraction.CIL.Entities
public abstract bool IsStatic { get; }
private IEnumerable<Parameter> MakeParameters(IEnumerable<Type> parameterTypes)
protected IEnumerable<Parameter> MakeParameters(IEnumerable<Type> parameterTypes)
{
int i = 0;
@@ -145,13 +138,15 @@ namespace Semmle.Extraction.CIL.Entities
{
readonly Handle handle;
readonly MethodDefinition md;
readonly PDB.IMethod methodDebugInformation;
readonly PDB.IMethod? methodDebugInformation;
readonly Type declaringType;
LocalVariable[] locals;
readonly string name;
LocalVariable[]? locals;
public MethodImplementation Implementation { get; private set; }
public MethodImplementation? Implementation { get; private set; }
public override IList<LocalVariable> LocalVariables => locals;
public override IList<LocalVariable>? LocalVariables => locals;
public DefinitionMethod(GenericContext gc, MethodDefinitionHandle handle) : base(gc)
{
@@ -167,7 +162,7 @@ namespace Semmle.Extraction.CIL.Entities
methodDebugInformation = cx.GetMethodDebugInformation(handle);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is DefinitionMethod method && handle.Equals(method.handle);
}
@@ -206,7 +201,7 @@ namespace Semmle.Extraction.CIL.Entities
var typeSignature = md.DecodeSignature(cx.TypeSignatureDecoder, this);
PopulateParameters(typeSignature.ParameterTypes);
Parameters = MakeParameters(typeSignature.ParameterTypes).ToArray();
foreach (var c in Parameters)
yield return c;
@@ -315,8 +310,8 @@ namespace Semmle.Extraction.CIL.Entities
// The sequence point gives the location of each instruction.
// The location of an instruction is given by the sequence point *after* the
// instruction.
IEnumerator<PDB.SequencePoint> nextSequencePoint = null;
PdbSourceLocation instructionLocation = null;
IEnumerator<PDB.SequencePoint>? nextSequencePoint = null;
PdbSourceLocation? instructionLocation = null;
if (methodDebugInformation != null)
{
@@ -401,9 +396,9 @@ namespace Semmle.Extraction.CIL.Entities
{
readonly MemberReferenceHandle handle;
readonly MemberReference mr;
readonly Type declType;
readonly Type declaringType;
readonly GenericContext parent;
readonly Method sourceDeclaration;
readonly Method? sourceDeclaration;
public MemberReferenceMethod(GenericContext gc, MemberReferenceHandle handle) : base(gc)
{
@@ -416,22 +411,24 @@ namespace Semmle.Extraction.CIL.Entities
parent = (GenericContext)cx.CreateGeneric(gc, mr.Parent);
var parentMethod = parent as Method;
nameLabel = cx.GetString(mr.Name);
declType = parentMethod == null ? parent as Type : parentMethod.DeclaringType;
var declType = parentMethod is null ? parent as Type : parentMethod.DeclaringType;
if (declType is null)
throw new InternalError("Parent context of method is not a type");
var typeSourceDeclaration = declType.SourceDeclaration;
sourceDeclaration = typeSourceDeclaration == declType ? (Method)this : typeSourceDeclaration.LookupMethod(mr.Name, mr.Signature);
declaringType = declType;
nameLabel = cx.GetString(mr.Name);
var typeSourceDeclaration = declaringType.SourceDeclaration;
sourceDeclaration = typeSourceDeclaration == declaringType ? (Method)this : typeSourceDeclaration.LookupMethod(mr.Name, mr.Signature);
}
private readonly string nameLabel;
public override string NameLabel => nameLabel;
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is MemberReferenceMethod method && handle.Equals(method.handle);
}
@@ -441,11 +438,11 @@ namespace Semmle.Extraction.CIL.Entities
return handle.GetHashCode();
}
public override Method SourceDeclaration => sourceDeclaration;
public override Method? SourceDeclaration => sourceDeclaration;
public override bool IsStatic => !signature.Header.IsInstance;
public override Type DeclaringType => declType;
public override Type DeclaringType => declaringType;
public override string Name => cx.ShortName(mr.Name);
@@ -464,7 +461,7 @@ namespace Semmle.Extraction.CIL.Entities
var typeSignature = mr.DecodeMethodSignature(cx.TypeSignatureDecoder, this);
PopulateParameters(typeSignature.ParameterTypes);
Parameters = MakeParameters(typeSignature.ParameterTypes).ToArray();
foreach (var p in Parameters) yield return p;
foreach (var f in PopulateFlags) yield return f;
@@ -486,6 +483,7 @@ namespace Semmle.Extraction.CIL.Entities
readonly MethodSpecification ms;
readonly Method unboundMethod;
readonly ImmutableArray<Type> typeParams;
readonly Type declaringType;
public MethodSpecificationMethod(GenericContext gc, MethodSpecificationHandle handle) : base(gc)
{
@@ -511,7 +509,7 @@ namespace Semmle.Extraction.CIL.Entities
public override string NameLabel => throw new NotImplementedException();
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is MethodSpecificationMethod method && handle.Equals(method.handle) && typeParams.SequenceEqual(method.typeParams);
}
@@ -547,7 +545,7 @@ namespace Semmle.Extraction.CIL.Entities
throw new InternalError($"Unexpected constructed method handle kind {ms.Method.Kind}");
}
PopulateParameters(constructedTypeSignature.ParameterTypes);
Parameters = MakeParameters(constructedTypeSignature.ParameterTypes).ToArray();
foreach (var p in Parameters)
yield return p;

View File

@@ -17,10 +17,10 @@ namespace Semmle.Extraction.CIL.Entities
/// </summary>
public sealed class Namespace : TypeContainer, INamespace
{
public Namespace ParentNamespace;
public Namespace? ParentNamespace;
public readonly string Name;
public bool IsGlobalNamespace => ParentNamespace == null;
public bool IsGlobalNamespace => ParentNamespace is null;
public override string IdSuffix => ";namespace";
@@ -35,7 +35,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(Name);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (obj is Namespace ns && Name == ns.Name)
{
@@ -63,7 +63,7 @@ namespace Semmle.Extraction.CIL.Entities
return i == -1 ? fqn : fqn.Substring(i + 1);
}
static Namespace createParentNamespace(Context cx, string fqn)
static Namespace? createParentNamespace(Context cx, string fqn)
{
if (fqn == "") return null;
var i = fqn.LastIndexOf('.');
@@ -74,7 +74,7 @@ namespace Semmle.Extraction.CIL.Entities
{
}
public Namespace(Context cx, string name, Namespace parent) : base(cx)
public Namespace(Context cx, string name, Namespace? parent) : base(cx)
{
Name = name;
ParentNamespace = parent;
@@ -85,7 +85,7 @@ namespace Semmle.Extraction.CIL.Entities
get
{
yield return Tuples.namespaces(this, Name);
if (!IsGlobalNamespace)
if (ParentNamespace is object)
yield return Tuples.parent_namespace(this, ParentNamespace);
}
}

View File

@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(index);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is Parameter param && method.Equals(param.method) && index == param.index;
}

View File

@@ -48,7 +48,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(")");
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is Property property && Equals(handle, property.handle);
}

View File

@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(location.EndColumn);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is PdbSourceLocation l && location.Equals(l.location);
}

View File

@@ -8,6 +8,7 @@ using System.Reflection;
using Semmle.Util;
using System.IO;
using System.Text;
using System.Diagnostics.CodeAnalysis;
namespace Semmle.Extraction.CIL.Entities
{
@@ -103,7 +104,7 @@ namespace Semmle.Extraction.CIL.Entities
/// shortcut to comparing the signature bytes since handles are unique.
/// </param>
/// <returns>The method, or 'null' if not found or not supported.</returns>
internal virtual Method LookupMethod(StringHandle methodName, BlobHandle signature)
internal virtual Method? LookupMethod(StringHandle methodName, BlobHandle signature)
{
return null;
}
@@ -160,7 +161,7 @@ namespace Semmle.Extraction.CIL.Entities
get;
}
public virtual TypeContainer Parent => (TypeContainer)ContainingType ?? Namespace;
public virtual TypeContainer Parent => (TypeContainer?)ContainingType ?? Namespace!;
public override IEnumerable<IExtractionProduct> Contents
{
@@ -177,9 +178,9 @@ namespace Semmle.Extraction.CIL.Entities
public abstract string Name { get; }
public abstract Namespace Namespace { get; }
public abstract Namespace? Namespace { get; }
public abstract Type ContainingType { get; }
public abstract Type? ContainingType { get; }
public abstract Type Construct(IEnumerable<Type> typeArguments);
@@ -233,7 +234,7 @@ namespace Semmle.Extraction.CIL.Entities
/// </summary>
/// <param name="t">The resulting primitive type, or null.</param>
/// <returns>True if this type is a primitive type.</returns>
public bool TryGetPrimitiveType(out PrimitiveType t)
public bool TryGetPrimitiveType([NotNullWhen(true)] out PrimitiveType? t)
{
if (TryGetPrimitiveTypeCode(out var code))
{
@@ -249,7 +250,7 @@ namespace Semmle.Extraction.CIL.Entities
private bool TryGetPrimitiveTypeCode(out PrimitiveTypeCode code)
{
if (ContainingType == null && Namespace.Name == cx.SystemNamespace.Name)
if (ContainingType == null && Namespace?.Name == cx.SystemNamespace.Name)
{
switch (Name)
{
@@ -341,7 +342,7 @@ namespace Semmle.Extraction.CIL.Entities
typeParams = new Lazy<IEnumerable<TypeTypeParameter>>(MakeTypeParameters);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is TypeDefinitionType t && handle.Equals(t.handle);
}
@@ -390,9 +391,9 @@ namespace Semmle.Extraction.CIL.Entities
public override Namespace Namespace => cx.Create(td.NamespaceDefinition);
readonly Type declType;
readonly Type? declType;
public override Type ContainingType => declType;
public override Type? ContainingType => declType;
public override int ThisTypeParameters
{
@@ -562,18 +563,14 @@ namespace Semmle.Extraction.CIL.Entities
readonly TypeReference tr;
readonly Lazy<TypeTypeParameter[]> typeParams;
public TypeReferenceType(Context cx, TypeReferenceHandle handle) : this(cx, handle, cx.mdReader.GetTypeReference(handle))
{
typeParams = new Lazy<TypeTypeParameter[]>(MakeTypeParameters);
}
public TypeReferenceType(Context cx, TypeReferenceHandle handle, TypeReference tr) : base(cx)
public TypeReferenceType(Context cx, TypeReferenceHandle handle) : base(cx)
{
this.typeParams = new Lazy<TypeTypeParameter[]>(MakeTypeParameters);
this.handle = handle;
this.tr = tr;
this.tr = cx.mdReader.GetTypeReference(handle);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is TypeReferenceType t && handle.Equals(t.handle);
}
@@ -637,7 +634,7 @@ namespace Semmle.Extraction.CIL.Entities
}
}
public override Type ContainingType
public override Type? ContainingType
{
get
{
@@ -654,7 +651,7 @@ namespace Semmle.Extraction.CIL.Entities
switch (tr.ResolutionScope.Kind)
{
case HandleKind.TypeReference:
ContainingType.WriteAssemblyPrefix(trapFile);
ContainingType!.WriteAssemblyPrefix(trapFile);
break;
case HandleKind.AssemblyReference:
var assemblyDef = cx.mdReader.GetAssemblyReference((AssemblyReferenceHandle)tr.ResolutionScope);
@@ -684,7 +681,7 @@ namespace Semmle.Extraction.CIL.Entities
var ct = ContainingType;
if (ct != null)
{
ContainingType.GetId(trapFile, inContext);
ct.GetId(trapFile, inContext);
}
else
{
@@ -719,9 +716,11 @@ namespace Semmle.Extraction.CIL.Entities
public sealed class ConstructedType : Type
{
readonly Type unboundGenericType;
readonly Type[] thisTypeArguments;
public override IEnumerable<Type> ThisTypeArguments => thisTypeArguments;
// Either null or notEmpty
readonly Type[]? thisTypeArguments;
public override IEnumerable<Type> ThisTypeArguments => thisTypeArguments.EnumerateNull();
public override IEnumerable<Type> ThisGenericArguments => thisTypeArguments.EnumerateNull();
@@ -751,7 +750,6 @@ namespace Semmle.Extraction.CIL.Entities
unboundGenericType = unboundType;
var thisParams = unboundType.ThisTypeParameters;
var parentParams = suppliedArgs - thisParams;
if (typeArguments.Count() == thisParams)
{
@@ -760,16 +758,19 @@ namespace Semmle.Extraction.CIL.Entities
}
else if (thisParams == 0)
{
containingType = unboundType.ContainingType.Construct(typeArguments);
// all type arguments belong to containing type
containingType = unboundType.ContainingType!.Construct(typeArguments);
}
else
{
containingType = unboundType.ContainingType.Construct(typeArguments.Take(parentParams));
// some type arguments belong to containing type
var parentParams = suppliedArgs - thisParams;
containingType = unboundType.ContainingType!.Construct(typeArguments.Take(parentParams));
thisTypeArguments = typeArguments.Skip(parentParams).ToArray();
}
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (obj is ConstructedType t && Equals(unboundGenericType, t.unboundGenericType) && Equals(containingType, t.containingType))
{
@@ -788,12 +789,12 @@ namespace Semmle.Extraction.CIL.Entities
return h;
}
readonly Type containingType;
public override Type ContainingType => containingType;
readonly Type? containingType;
public override Type? ContainingType => containingType;
public override string Name => unboundGenericType.Name;
public override Namespace Namespace => unboundGenericType.Namespace;
public override Namespace Namespace => unboundGenericType.Namespace!;
public override int ThisTypeParameters => thisTypeArguments == null ? 0 : thisTypeArguments.Length;
@@ -851,7 +852,7 @@ namespace Semmle.Extraction.CIL.Entities
typeCode = tc;
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is PrimitiveType pt && typeCode == pt.typeCode;
}
@@ -871,7 +872,7 @@ namespace Semmle.Extraction.CIL.Entities
public override Namespace Namespace => cx.SystemNamespace;
public override Type ContainingType => null;
public override Type? ContainingType => null;
public override int ThisTypeParameters => 0;
@@ -894,19 +895,17 @@ namespace Semmle.Extraction.CIL.Entities
readonly Type elementType;
readonly int rank;
public ArrayType(Context cx, Type element, ArrayShape shape) : base(cx)
public ArrayType(Context cx, Type elementType, int rank) : base(cx)
{
rank = shape.Rank;
elementType = element;
this.rank = rank;
this.elementType = elementType;
}
public ArrayType(Context cx, Type element) : base(cx)
public ArrayType(Context cx, Type elementType) : this(cx, elementType, 1)
{
rank = 1;
elementType = element;
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is ArrayType array && elementType.Equals(array.elementType) && rank == array.rank;
}
@@ -929,7 +928,7 @@ namespace Semmle.Extraction.CIL.Entities
public override Namespace Namespace => cx.SystemNamespace;
public override Type ContainingType => null;
public override Type? ContainingType => null;
public override int ThisTypeParameters => elementType.ThisTypeParameters;
@@ -972,9 +971,9 @@ namespace Semmle.Extraction.CIL.Entities
this.gc = gc;
}
public override Namespace Namespace => null;
public override Namespace? Namespace => null;
public override Type ContainingType => null;
public override Type? ContainingType => null;
public override int ThisTypeParameters => 0;
@@ -1034,7 +1033,7 @@ namespace Semmle.Extraction.CIL.Entities
this.index = index;
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is MethodTypeParameter tp && method.Equals(tp.method) && index == tp.index;
}
@@ -1072,7 +1071,7 @@ namespace Semmle.Extraction.CIL.Entities
type = t;
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is TypeTypeParameter tp && type.Equals(tp.type) && index == tp.index;
}
@@ -1089,7 +1088,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write(index);
}
public override TypeContainer Parent => type ?? gc as TypeContainer;
public override TypeContainer Parent => type;
public override string Name => "!" + index;
public override IEnumerable<Type> TypeParameters => Enumerable.Empty<Type>();
@@ -1119,7 +1118,7 @@ namespace Semmle.Extraction.CIL.Entities
this.pointee = pointee;
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is PointerType pt && pointee.Equals(pt.pointee);
}
@@ -1138,9 +1137,9 @@ namespace Semmle.Extraction.CIL.Entities
public override string Name => pointee.Name + "*";
public override Namespace Namespace => pointee.Namespace;
public override Namespace? Namespace => pointee.Namespace;
public override Type ContainingType => pointee.ContainingType;
public override Type? ContainingType => pointee.ContainingType;
public override TypeContainer Parent => pointee.Parent;
@@ -1180,7 +1179,7 @@ namespace Semmle.Extraction.CIL.Entities
public override Namespace Namespace => cx.GlobalNamespace;
public override Type ContainingType => null;
public override Type? ContainingType => null;
public override int ThisTypeParameters => 0;
@@ -1202,8 +1201,15 @@ namespace Semmle.Extraction.CIL.Entities
{
struct Array : ITypeSignature
{
public ITypeSignature elementType;
public ArrayShape shape;
private readonly ITypeSignature elementType;
private readonly ArrayShape shape;
public Array(ITypeSignature elementType, ArrayShape shape) : this()
{
this.elementType = elementType;
this.shape = shape;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
elementType.WriteId(trapFile, gc);
@@ -1216,7 +1222,12 @@ namespace Semmle.Extraction.CIL.Entities
struct ByRef : ITypeSignature
{
public ITypeSignature elementType;
private readonly ITypeSignature elementType;
public ByRef(ITypeSignature elementType)
{
this.elementType = elementType;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
@@ -1227,7 +1238,12 @@ namespace Semmle.Extraction.CIL.Entities
struct FnPtr : ITypeSignature
{
public MethodSignature<ITypeSignature> signature;
private readonly MethodSignature<ITypeSignature> signature;
public FnPtr(MethodSignature<ITypeSignature> signature)
{
this.signature = signature;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
@@ -1236,18 +1252,25 @@ namespace Semmle.Extraction.CIL.Entities
}
ITypeSignature IConstructedTypeProvider<ITypeSignature>.GetArrayType(ITypeSignature elementType, ArrayShape shape) =>
new Array { elementType = elementType, shape = shape };
new Array(elementType, shape);
ITypeSignature IConstructedTypeProvider<ITypeSignature>.GetByReferenceType(ITypeSignature elementType) =>
new ByRef { elementType = elementType };
new ByRef(elementType);
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetFunctionPointerType(MethodSignature<ITypeSignature> signature) =>
new FnPtr { signature = signature };
new FnPtr(signature);
class Instantiation : ITypeSignature
{
public ITypeSignature genericType;
public ImmutableArray<ITypeSignature> typeArguments;
private readonly ITypeSignature genericType;
private readonly ImmutableArray<ITypeSignature> typeArguments;
public Instantiation(ITypeSignature genericType, ImmutableArray<ITypeSignature> typeArguments)
{
this.genericType = genericType;
this.typeArguments = typeArguments;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
@@ -1264,12 +1287,18 @@ namespace Semmle.Extraction.CIL.Entities
}
ITypeSignature IConstructedTypeProvider<ITypeSignature>.GetGenericInstantiation(ITypeSignature genericType, ImmutableArray<ITypeSignature> typeArguments) =>
new Instantiation { genericType = genericType, typeArguments = typeArguments };
new Instantiation(genericType, typeArguments);
class GenericMethodParameter : ITypeSignature
{
public object innerGc;
public int index;
private readonly object innerGc;
private readonly int index;
public GenericMethodParameter(object innerGc, int index)
{
this.innerGc = innerGc;
this.index = index;
}
public void WriteId(TextWriter trapFile, GenericContext outerGc)
{
@@ -1284,7 +1313,12 @@ namespace Semmle.Extraction.CIL.Entities
class GenericTypeParameter : ITypeSignature
{
public int index;
private readonly int index;
public GenericTypeParameter(int index)
{
this.index = index;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
@@ -1294,16 +1328,23 @@ namespace Semmle.Extraction.CIL.Entities
}
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetGenericMethodParameter(object genericContext, int index) =>
new GenericMethodParameter { innerGc = genericContext, index = index };
new GenericMethodParameter(genericContext, index);
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetGenericTypeParameter(object genericContext, int index) =>
new GenericTypeParameter { index = index };
new GenericTypeParameter(index);
class Modified : ITypeSignature
{
public ITypeSignature modifier;
public ITypeSignature unmodifiedType;
public bool isRequired;
private readonly ITypeSignature modifier;
private readonly ITypeSignature unmodifiedType;
private readonly bool isRequired;
public Modified(ITypeSignature modifier, ITypeSignature unmodifiedType, bool isRequired)
{
this.modifier = modifier;
this.unmodifiedType = unmodifiedType;
this.isRequired = isRequired;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
@@ -1313,12 +1354,17 @@ namespace Semmle.Extraction.CIL.Entities
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetModifiedType(ITypeSignature modifier, ITypeSignature unmodifiedType, bool isRequired)
{
return new Modified { modifier = modifier, unmodifiedType = unmodifiedType, isRequired = isRequired };
return new Modified(modifier, unmodifiedType, isRequired);
}
class Pinned : ITypeSignature
{
public ITypeSignature elementType;
private readonly ITypeSignature elementType;
public Pinned(ITypeSignature elementType)
{
this.elementType = elementType;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
@@ -1329,12 +1375,17 @@ namespace Semmle.Extraction.CIL.Entities
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetPinnedType(ITypeSignature elementType)
{
return new Pinned { elementType = elementType };
return new Pinned(elementType);
}
class PointerType : ITypeSignature
{
public ITypeSignature elementType;
private readonly ITypeSignature elementType;
public PointerType(ITypeSignature elementType)
{
this.elementType = elementType;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
@@ -1345,12 +1396,17 @@ namespace Semmle.Extraction.CIL.Entities
ITypeSignature IConstructedTypeProvider<ITypeSignature>.GetPointerType(ITypeSignature elementType)
{
return new PointerType { elementType = elementType };
return new PointerType(elementType);
}
class Primitive : ITypeSignature
{
public PrimitiveTypeCode typeCode;
private readonly PrimitiveTypeCode typeCode;
public Primitive(PrimitiveTypeCode typeCode)
{
this.typeCode = typeCode;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
@@ -1360,12 +1416,18 @@ namespace Semmle.Extraction.CIL.Entities
ITypeSignature ISimpleTypeProvider<ITypeSignature>.GetPrimitiveType(PrimitiveTypeCode typeCode)
{
return new Primitive { typeCode = typeCode };
return new Primitive(typeCode);
}
class SzArrayType : ITypeSignature
{
public ITypeSignature elementType;
private readonly ITypeSignature elementType;
public SzArrayType(ITypeSignature elementType)
{
this.elementType = elementType;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
elementType.WriteId(trapFile, gc);
@@ -1375,41 +1437,53 @@ namespace Semmle.Extraction.CIL.Entities
ITypeSignature ISZArrayTypeProvider<ITypeSignature>.GetSZArrayType(ITypeSignature elementType)
{
return new SzArrayType { elementType = elementType };
return new SzArrayType(elementType);
}
class TypeDefinition : ITypeSignature
{
public TypeDefinitionHandle handle;
public byte rawTypeKind;
Type type;
private readonly TypeDefinitionHandle handle;
private readonly byte rawTypeKind;
public TypeDefinition(TypeDefinitionHandle handle, byte rawTypeKind)
{
this.handle = handle;
this.rawTypeKind = rawTypeKind;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
type = (Type)gc.cx.Create(handle);
var type = (Type)gc.cx.Create(handle);
type.WriteId(trapFile);
}
}
ITypeSignature ISimpleTypeProvider<ITypeSignature>.GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
return new TypeDefinition { handle = handle, rawTypeKind = rawTypeKind };
return new TypeDefinition(handle, rawTypeKind);
}
class TypeReference : ITypeSignature
{
public TypeReferenceHandle handle;
public byte rawTypeKind; // struct/class (not used)
Type type;
private readonly TypeReferenceHandle handle;
private readonly byte rawTypeKind; // struct/class (not used)
public TypeReference(TypeReferenceHandle handle, byte rawTypeKind)
{
this.handle = handle;
this.rawTypeKind = rawTypeKind;
}
public void WriteId(TextWriter trapFile, GenericContext gc)
{
type = (Type)gc.cx.Create(handle);
var type = (Type)gc.cx.Create(handle);
type.WriteId(trapFile);
}
}
ITypeSignature ISimpleTypeProvider<ITypeSignature>.GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
return new TypeReference { handle = handle, rawTypeKind = rawTypeKind };
return new TypeReference(handle, rawTypeKind);
}
ITypeSignature ISignatureTypeProvider<ITypeSignature, object>.GetTypeFromSpecification(MetadataReader reader, object genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
@@ -1433,7 +1507,7 @@ namespace Semmle.Extraction.CIL.Entities
}
Type IConstructedTypeProvider<Type>.GetArrayType(Type elementType, ArrayShape shape) =>
cx.Populate(new ArrayType(cx, elementType, shape));
cx.Populate(new ArrayType(cx, elementType, shape.Rank));
Type IConstructedTypeProvider<Type>.GetByReferenceType(Type elementType) =>
elementType; // ??

View File

@@ -41,7 +41,7 @@ namespace Semmle.Extraction.CIL
e.WriteId(writer);
var id = writer.ToString();
if (debugLabels.TryGetValue(id, out IExtractedEntity previousEntity))
if (debugLabels.TryGetValue(id, out IExtractedEntity? previousEntity))
{
cx.Extractor.Message(new Message("Duplicate trap ID", id, null, severity: Util.Logging.Severity.Warning));
}

View File

@@ -25,7 +25,7 @@ namespace Semmle.Extraction.PDB
public string Path { get; private set; }
public string Contents => File.Exists(Path) ? File.ReadAllText(Path, System.Text.Encoding.Default) : null;
public string? Contents => File.Exists(Path) ? File.ReadAllText(Path, System.Text.Encoding.Default) : null;
}
// Turns out to be very important to keep the MetadataReaderProvider live
@@ -41,7 +41,7 @@ namespace Semmle.Extraction.PDB
public IEnumerable<ISourceFile> SourceFiles => reader.Documents.Select(handle => new SourceFile(reader, handle));
public IMethod GetMethod(MethodDebugInformationHandle handle)
public IMethod? GetMethod(MethodDebugInformationHandle handle)
{
var debugInfo = reader.GetMethodDebugInformation(handle);
@@ -51,10 +51,10 @@ namespace Semmle.Extraction.PDB
Where(p => p.Location.File.Path != null).
ToArray();
return sequencePoints.Any() ? new Method() { SequencePoints = sequencePoints } : null;
return sequencePoints.Any() ? new Method(sequencePoints) : null;
}
public static MetadataPdbReader CreateFromAssembly(string assemblyPath, PEReader peReader)
public static MetadataPdbReader? CreateFromAssembly(string assemblyPath, PEReader peReader)
{
foreach (var provider in peReader.
ReadDebugDirectory().

View File

@@ -23,7 +23,7 @@ namespace Semmle.Extraction.PDB
public Document(ISymUnmanagedDocument doc)
{
document = doc;
contents = new Lazy<string>(() =>
contents = new Lazy<string?>(() =>
{
bool isEmbedded;
if (document.HasEmbeddedSource(out isEmbedded) == 0 && isEmbedded)
@@ -38,7 +38,7 @@ namespace Semmle.Extraction.PDB
});
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
var otherDoc = obj as Document;
return otherDoc != null && Path.Equals(otherDoc.Path);
@@ -50,14 +50,14 @@ namespace Semmle.Extraction.PDB
public override string ToString() => Path;
readonly Lazy<string> contents;
readonly Lazy<string?> contents;
public string Contents => contents.Value;
public string? Contents => contents.Value;
}
public IEnumerable<ISourceFile> SourceFiles => reader.GetDocuments().Select(d => new Document(d));
public IMethod GetMethod(MethodDebugInformationHandle h)
public IMethod? GetMethod(MethodDebugInformationHandle h)
{
int methodToken = MetadataTokens.GetToken(h.ToDefinitionHandle());
var method = reader.GetMethod(methodToken);
@@ -72,7 +72,7 @@ namespace Semmle.Extraction.PDB
Select(sp => new SequencePoint(sp.Offset, new Location(new Document(sp.Document), sp.StartLine, sp.StartColumn, sp.EndLine, sp.EndColumn))).
ToArray();
return s.Any() ? new Method { SequencePoints = s } : null;
return s.Any() ? new Method(s) : null;
}
return null;
}
@@ -87,7 +87,7 @@ namespace Semmle.Extraction.PDB
readonly ISymUnmanagedReader5 reader;
readonly FileStream pdbStream;
public static NativePdbReader CreateFromAssembly(string assemblyPath, PEReader peReader)
public static NativePdbReader? CreateFromAssembly(string assemblyPath, PEReader peReader)
{
// The Native PDB reader uses an unmanaged Windows DLL
// so only works on Windows.
@@ -123,7 +123,7 @@ namespace Semmle.Extraction.PDB
{
}
public object GetMetadataImport() => null;
public object? GetMetadataImport() => null;
public unsafe bool TryGetStandaloneSignature(int standaloneSignatureToken, out byte* signature, out int length) =>
throw new NotImplementedException();

View File

@@ -55,7 +55,7 @@ namespace Semmle.Extraction.PDB
return string.Format("({0},{1})-({2},{3})", StartLine, StartColumn, EndLine, EndColumn);
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
var otherLocation = obj as Location;
@@ -91,7 +91,12 @@ namespace Semmle.Extraction.PDB
class Method : IMethod
{
public IEnumerable<SequencePoint> SequencePoints { get; set; }
public IEnumerable<SequencePoint> SequencePoints { get; }
public Method(IEnumerable<SequencePoint> sequencePoints)
{
SequencePoints = sequencePoints;
}
public Location Location => SequencePoints.First().Location;
}
@@ -111,7 +116,7 @@ namespace Semmle.Extraction.PDB
/// null if the contents are unavailable.
/// E.g. if the PDB file exists but the corresponding source files are missing.
/// </summary>
string Contents { get; }
string? Contents { get; }
}
/// <summary>
@@ -131,7 +136,7 @@ namespace Semmle.Extraction.PDB
/// </summary>
/// <param name="methodHandle">The handle to query.</param>
/// <returns>The method information, or null if the method does not have debug information.</returns>
IMethod GetMethod(MethodDebugInformationHandle methodHandle);
IMethod? GetMethod(MethodDebugInformationHandle methodHandle);
}
class PdbReader
@@ -140,11 +145,11 @@ namespace Semmle.Extraction.PDB
/// Returns the PDB information associated with an assembly.
/// </summary>
/// <param name="assemblyPath">The path to the assembly.</param>
/// <param name="peReader">The PE reader for the assembky.</param>
/// <param name="peReader">The PE reader for the assembly.</param>
/// <returns>A PdbReader, or null if no PDB information is available.</returns>
public static IPdb Create(string assemblyPath, PEReader peReader)
public static IPdb? Create(string assemblyPath, PEReader peReader)
{
return (IPdb)MetadataPdbReader.CreateFromAssembly(assemblyPath, peReader) ??
return (IPdb?)MetadataPdbReader.CreateFromAssembly(assemblyPath, peReader) ??
NativePdbReader.CreateFromAssembly(assemblyPath, peReader);
}
}

View File

@@ -7,6 +7,7 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -1,4 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Kinds;
using System.IO;
@@ -21,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
protected override void PopulateExpression(TextWriter trapFile)
{
var child = 0;
var explicitlySized = false;
if (TypeSyntax is null)
@@ -29,38 +30,21 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
cx.ModelError(Syntax, "Array has unexpected type syntax");
}
foreach (var rank in TypeSyntax.RankSpecifiers.SelectMany(rs => rs.Sizes))
var firstLevelSizes = TypeSyntax.RankSpecifiers.First()?.Sizes ?? SyntaxFactory.SeparatedList<ExpressionSyntax>();
if (firstLevelSizes.OfType<ExpressionSyntax>().Any(s => s is OmittedArraySizeExpressionSyntax))
{
if (rank is OmittedArraySizeExpressionSyntax)
{
// Create an expression which simulates the explicit size of the array
if (!(Initializer is null))
{
// An implicitly-sized array must have an initializer.
// Guard it just in case.
var size = Initializer.Expressions.Count;
var info = new ExpressionInfo(
cx,
new AnnotatedType(Entities.Type.Create(cx, cx.Compilation.GetSpecialType(Microsoft.CodeAnalysis.SpecialType.System_Int32)), NullableAnnotation.None),
Location,
ExprKind.INT_LITERAL,
this,
child,
true,
size.ToString());
new Expression(info);
}
}
else
{
Create(cx, rank, this, child);
explicitlySized = true;
}
child++;
SetArraySizes(Initializer, firstLevelSizes.Count);
}
else
{
for (var sizeIndex = 0; sizeIndex < firstLevelSizes.Count; sizeIndex++)
{
Create(cx, firstLevelSizes[sizeIndex], this, sizeIndex);
}
explicitlySized = true;
}
if (!(Initializer is null))
{
ArrayInitializer.Create(new ExpressionNodeInfo(cx, Initializer, this, -1));
@@ -69,6 +53,31 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
if (explicitlySized)
trapFile.explicitly_sized_array_creation(this);
}
private void SetArraySizes(InitializerExpressionSyntax initializer, int rank)
{
for (var level = 0; level < rank; level++)
{
if (initializer is null)
{
return;
}
var info = new ExpressionInfo(
cx,
new AnnotatedType(Entities.Type.Create(cx, cx.Compilation.GetSpecialType(Microsoft.CodeAnalysis.SpecialType.System_Int32)), NullableAnnotation.None),
Location,
ExprKind.INT_LITERAL,
this,
level,
true,
initializer.Expressions.Count.ToString());
new Expression(info);
initializer = initializer.Expressions.FirstOrDefault() as InitializerExpressionSyntax;
}
}
}
class NormalArrayCreation : ExplicitArrayCreation<ArrayCreationExpressionSyntax>

View File

@@ -64,7 +64,7 @@ namespace Semmle.Util
/// Enumerates a possibly null enumerable.
/// If the enumerable is null, the list is empty.
/// </summary>
public static IEnumerable<T> EnumerateNull<T>(this IEnumerable<T> items)
public static IEnumerable<T> EnumerateNull<T>(this IEnumerable<T>? items)
{
if (items == null) yield break;
foreach (var item in items) yield return item;

View File

@@ -6,18 +6,32 @@
import csharp
//#################### PREDICATES ####################
Stmt firstStmt(ForeachStmt fes) {
private Stmt firstStmt(ForeachStmt fes) {
if fes.getBody() instanceof BlockStmt
then result = fes.getBody().(BlockStmt).getStmt(0)
else result = fes.getBody()
}
private int numStmts(ForeachStmt fes) {
if fes.getBody() instanceof BlockStmt
then result = count(fes.getBody().(BlockStmt).getAStmt())
else result = 1
}
/** Holds if the type's qualified name is "System.Linq.Enumerable" */
predicate isEnumerableType(ValueOrRefType t) { t.hasQualifiedName("System.Linq.Enumerable") }
/** Holds if the type's qualified name starts with "System.Collections.Generic.IEnumerable" */
predicate isIEnumerableType(ValueOrRefType t) {
t.getQualifiedName().matches("System.Collections.Generic.IEnumerable%")
}
/**
* Holds if `foreach` statement `fes` could be converted to a `.All()` call.
* That is, the `ForeachStmt` contains a single `if` with a condition that
* accesses the loop variable and with a body that assigns `false` to a variable
* and `break`s out of the `foreach`.
*/
predicate missedAllOpportunity(ForeachStmt fes) {
exists(IfStmt is |
// The loop contains an if statement with no else case, and nothing else.
@@ -36,6 +50,12 @@ predicate missedAllOpportunity(ForeachStmt fes) {
)
}
/**
* Holds if `foreach` statement `fes` could be converted to a `.Cast()` call.
* That is, the loop variable is accessed only in the first statement of the
* block, and the access is a cast. The first statement needs to be a
* `LocalVariableDeclStmt`.
*/
predicate missedCastOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
s = firstStmt(fes) and
forex(VariableAccess va | va = fes.getVariable().getAnAccess() |
@@ -47,6 +67,12 @@ predicate missedCastOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
)
}
/**
* Holds if `foreach` statement `fes` could be converted to an `.OfType()` call.
* That is, the loop variable is accessed only in the first statement of the
* block, and the access is a cast with the `as` operator. The first statement
* needs to be a `LocalVariableDeclStmt`.
*/
predicate missedOfTypeOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
s = firstStmt(fes) and
forex(VariableAccess va | va = fes.getVariable().getAnAccess() |
@@ -58,6 +84,12 @@ predicate missedOfTypeOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
)
}
/**
* Holds if `foreach` statement `fes` could be converted to a `.Select()` call.
* That is, the loop variable is accessed only in the first statement of the
* block, and the access is not a cast. The first statement needs to be a
* `LocalVariableDeclStmt`.
*/
predicate missedSelectOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
s = firstStmt(fes) and
forex(VariableAccess va | va = fes.getVariable().getAnAccess() |
@@ -66,6 +98,12 @@ predicate missedSelectOpportunity(ForeachStmt fes, LocalVariableDeclStmt s) {
not s.getAVariableDeclExpr().getInitializer() instanceof Cast
}
/**
* Holds if `foreach` statement `fes` could be converted to a `.Where()` call.
* That is, first statement of the loop is an `if`, which accesses the loop
* variable, and the body of the `if` is either a `continue` or there's nothing
* else in the loop than the `if`.
*/
predicate missedWhereOpportunity(ForeachStmt fes, IfStmt is) {
// The very first thing the foreach loop does is test its iteration variable.
is = firstStmt(fes) and
@@ -82,12 +120,6 @@ predicate missedWhereOpportunity(ForeachStmt fes, IfStmt is) {
)
}
int numStmts(ForeachStmt fes) {
if fes.getBody() instanceof BlockStmt
then result = count(fes.getBody().(BlockStmt).getAStmt())
else result = 1
}
//#################### CLASSES ####################
/** A LINQ Any(...) call. */
class AnyCall extends MethodCall {

View File

@@ -66,9 +66,9 @@ class SimilarBlock extends Copy, @similarity {
}
}
Method sourceMethod() { method_location(result, _) and numlines(result, _, _, _) }
private Method sourceMethod() { method_location(result, _) and numlines(result, _, _, _) }
int numberOfSourceMethods(Class c) {
private int numberOfSourceMethods(Class c) {
result = count(Method m | m = sourceMethod() and m.getDeclaringType() = c)
}
@@ -97,6 +97,7 @@ private predicate duplicateStatement(Method m1, Method m2, Stmt s1, Stmt s2) {
)
}
/** Holds if `duplicate` number of statements are duplicated in the methods. */
predicate duplicateStatements(Method m1, Method m2, int duplicate, int total) {
duplicate = strictcount(Stmt s | duplicateStatement(m1, m2, s, _)) and
total = strictcount(statementInMethod(m1))
@@ -109,7 +110,7 @@ predicate duplicateMethod(Method m, Method other) {
exists(int total | duplicateStatements(m, other, total, total))
}
predicate similarLines(File f, int line) {
private predicate similarLines(File f, int line) {
exists(SimilarBlock b | b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()])
}
@@ -148,7 +149,7 @@ private predicate similarLinesCovered(File f, int coveredLines, File otherFile)
)
}
predicate duplicateLines(File f, int line) {
private predicate duplicateLines(File f, int line) {
exists(DuplicateBlock b |
b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()]
)
@@ -189,6 +190,7 @@ private predicate duplicateLinesCovered(File f, int coveredLines, File otherFile
)
}
/** Holds if the two files are not duplicated but have more than 80% similar lines. */
predicate similarFiles(File f, File other, int percent) {
exists(int covered, int total |
similarLinesCovered(f, covered, other) and
@@ -199,6 +201,7 @@ predicate similarFiles(File f, File other, int percent) {
not duplicateFiles(f, other, _)
}
/** Holds if the two files have more than 70% duplicated lines. */
predicate duplicateFiles(File f, File other, int percent) {
exists(int covered, int total |
duplicateLinesCovered(f, covered, other) and
@@ -209,7 +212,7 @@ predicate duplicateFiles(File f, File other, int percent) {
}
pragma[noopt]
predicate duplicateAnonymousClass(AnonymousClass c, AnonymousClass other) {
private predicate duplicateAnonymousClass(AnonymousClass c, AnonymousClass other) {
exists(int numDup |
numDup =
strictcount(Method m1 |
@@ -248,6 +251,7 @@ private predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int
not other instanceof AnonymousClass
}
/** Holds if the methods in the two classes are more than 80% duplicated. */
predicate mostlyDuplicateClass(Class c, Class other, string message) {
exists(int numDup, int total |
mostlyDuplicateClassBase(c, other, numDup, total) and
@@ -272,19 +276,28 @@ predicate mostlyDuplicateClass(Class c, Class other, string message) {
)
}
/** Holds if the two files are similar or duplicated. */
predicate fileLevelDuplication(File f, File other) {
similarFiles(f, other, _) or duplicateFiles(f, other, _)
}
/**
* Holds if the two classes are duplicated anonymous classes or more than 80% of
* their methods are duplicated.
*/
predicate classLevelDuplication(Class c, Class other) {
duplicateAnonymousClass(c, other) or mostlyDuplicateClass(c, other, _)
}
Element whitelistedDuplicateElement() {
private Element whitelistedDuplicateElement() {
result instanceof UsingNamespaceDirective or
result instanceof UsingStaticDirective
}
/**
* Holds if the `line` in the `file` contains an element, such as a `using`
* directive, that is not considered for code duplication.
*/
predicate whitelistedLineForDuplication(File file, int line) {
exists(Location loc | loc = whitelistedDuplicateElement().getLocation() |
line = loc.getStartLine() and file = loc.getFile()

View File

@@ -31,6 +31,7 @@ class ReadRefAccess extends ReadAccess, ReadRef { }
/** An instruction that writes a variable. */
class WriteAccess extends VariableAccess, @cil_write_access {
/** Gets the expression whose value is used in this variable write. */
Expr getExpr() { none() }
}

View File

@@ -437,6 +437,9 @@ class Operator extends Callable, Member, Attributable, @operator {
override string getName() { operators(this, _, result, _, _, _) }
/**
* Gets the metadata name of the operator, such as `op_implicit` or `op_RightShift`.
*/
string getFunctionName() { none() }
override ValueOrRefType getDeclaringType() { operators(this, _, _, result, _, _) }

View File

@@ -514,6 +514,11 @@ predicate convNullableType(ValueOrRefType fromType, NullableType toType) {
)
}
/**
* Holds if `fromType` is `NullType`, and `toType` is a type that can represent
* the `null` value, such as a reference type, `Nullable<T>` or a type parameter
* with contraints that restrict it to a reference type.
*/
// This is a deliberate, small Cartesian product, so we have manually lifted it to force the
// evaluator to evaluate it in its entirety, rather than trying to optimize it in context.
pragma[noinline]

View File

@@ -212,7 +212,12 @@ module AbstractValues {
c.isValidFor(cfe) and
foreachEmptiness(fs, cfe) and
e = fs.getIterableExpr()
)
) and
// Only when taking the non-empty successor do we know that the original iterator
// expression was non-empty. When taking the empty successor, we may have already
// iterated through the `foreach` loop zero or more times, hence the iterator
// expression can be both empty and non-empty
this.isNonEmpty()
}
override EmptyCollectionValue getDualValue() {

View File

@@ -123,8 +123,18 @@ module Consistency {
n.getEnclosingCallable() != call.getEnclosingCallable()
}
// This predicate helps the compiler forget that in some languages
// it is impossible for a result of `getPreUpdateNode` to be an
// instance of `PostUpdateNode`.
private Node getPre(PostUpdateNode n) {
result = n.getPreUpdateNode()
or
none()
}
query predicate postIsNotPre(PostUpdateNode n, string msg) {
n.getPreUpdateNode() = n and msg = "PostUpdateNode should not equal its pre-update node."
getPre(n) = n and
msg = "PostUpdateNode should not equal its pre-update node."
}
query predicate postHasUniquePre(PostUpdateNode n, string msg) {
@@ -152,12 +162,6 @@ module Consistency {
msg = "Origin of readStep is missing a PostUpdateNode."
}
query predicate storeIsPostUpdate(Node n, string msg) {
storeStep(_, _, n) and
not n instanceof PostUpdateNode and
msg = "Store targets should be PostUpdateNodes."
}
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
not hasPost(n) and
not isImmutableOrUnobservable(n) and

View File

@@ -26,6 +26,7 @@ class RuntimeMethod extends RuntimeCallable {
this instanceof CIL::Method
}
/** Holds if the method is `static`. */
predicate isStatic() { this.(Method).isStatic() or this.(CIL::Method).isStatic() }
}

View File

@@ -1011,6 +1011,7 @@ class RangeExpr extends Expr, @range_expr {
/** An index expression, for example `^1` meaning "1 from the end". */
class IndexExpr extends Expr, @index_expr {
/** Gets the sub expression of this index expression. */
Expr getExpr() { result.getParent() = this }
override string toString() { result = "^..." }

View File

@@ -8,7 +8,12 @@ private import semmle.code.csharp.frameworks.system.collections.Generic
private import semmle.code.csharp.frameworks.Sql
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
/**
* Definitions relating to the `System.ComponentModel.DataAnnotations`
* namespace.
*/
module DataAnnotations {
/** Class for `NotMappedAttribute`. */
class NotMappedAttribute extends Attribute {
NotMappedAttribute() {
this
@@ -18,6 +23,10 @@ module DataAnnotations {
}
}
/**
* Definitions relating to the `Microsoft.EntityFrameworkCore` or
* `System.Data.Entity` namespaces.
*/
module EntityFramework {
/** An EF6 or EFCore namespace. */
class EFNamespace extends Namespace {
@@ -43,12 +52,14 @@ module EntityFramework {
class DbContext extends EFClass {
DbContext() { this.getName() = "DbContext" }
/** Gets a `Find` or `FindAsync` method in the `DbContext`. */
Method getAFindMethod() {
result = this.getAMethod("Find")
or
result = this.getAMethod("FindAsync")
}
/** Gets an `Update` method in the `DbContext`. */
Method getAnUpdateMethod() { result = this.getAMethod("Update") }
}
@@ -119,6 +130,7 @@ module EntityFramework {
preservesValue = false
}
/** Gets a conversion operator from `string` to `RawSqlString`. */
ConversionOperator getAConversionTo() {
result = this.getAMember() and
result.getTargetType() instanceof RawSqlStringStruct and

View File

@@ -135,8 +135,10 @@ module JsonNET {
class JsonSerializerClass extends JsonClass, LibraryTypeDataFlow {
JsonSerializerClass() { this.hasName("JsonSerializer") }
/** Gets the method for `JsonSerializer.Serialize`. */
Method getSerializeMethod() { result = this.getAMethod("Serialize") }
/** Gets the method for `JsonSerializer.Deserialize`. */
Method getDeserializeMethod() { result = this.getAMethod("Deserialize") }
override predicate callableFlow(

View File

@@ -1,8 +1,13 @@
/**
* Classes for modelling NHibernate.
*/
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.frameworks.Sql
/** Definitions relating to the `NHibernate` package. */
module NHibernate {
/** A class that is mapped to the database. */
abstract class MappedClass extends Class { }

View File

@@ -5,6 +5,7 @@
private import csharp as csharp
private import semmle.code.csharp.frameworks.System as System
/** Definitions relating to the `System.Linq` namespace. */
module SystemLinq {
/** The `System.Linq` namespace. */
class Namespace extends csharp::Namespace {

View File

@@ -5,6 +5,7 @@
private import csharp as csharp
private import semmle.code.csharp.frameworks.system.Data as Data
/** Definitions relating to the `System.Data.Common` namespace. */
module SystemDataCommon {
/** The `System.Data.Common` namespace. */
class Namespace extends csharp::Namespace {

View File

@@ -5,6 +5,7 @@
private import csharp as csharp
private import semmle.code.csharp.frameworks.system.Data as Data
/** Definitions relating to the `System.Data.Entity` namespace. */
module SystemDataEntity {
/** The `System.Data.Entity` namespace. */
class Namespace extends csharp::Namespace {
@@ -78,6 +79,7 @@ module SystemDataEntity {
}
}
/** Definitions relating to the `System.Data.Entity.Infrastructure` namespace. */
module SystemDataEntityInfrastructure {
/** The `System.Data.Entity.Infrastructure` namespace. */
class Namespace extends csharp::Namespace {

View File

@@ -5,6 +5,7 @@
private import csharp as csharp
private import semmle.code.csharp.frameworks.system.Linq
/** Definitions relating to the `System.Linq.Expressions` namespace. */
module SystemLinqExpressions {
/** The `System.Linq.Expressions` namespace. */
class Namespace extends csharp::Namespace {

View File

@@ -1,3 +1,7 @@
/**
* Provides classes related to the namespace `System.Text.RegularExpressions`.
*/
import default
import semmle.code.csharp.frameworks.system.Text

View File

@@ -3,6 +3,7 @@
import csharp as csharp
private import semmle.code.csharp.frameworks.system.Xml as xml
/** Definitions relating to the `System.Xml.XPath` namespace. */
module SystemXmlXPath {
/** The `System.Xml.XPath` namespace. */
class Namespace extends csharp::Namespace {

View File

@@ -222,6 +222,10 @@ predicate shareFieldOrProperty(ValueOrRefType t, Method m1, Method m2) {
)
}
/**
* Holds if the declaring type of method `m` is `t` and `m` accesses declaration
* `d`, which is either a field or a property.
*/
predicate methodUsesFieldOrProperty(ValueOrRefType t, Method m, Declaration d) {
m.getDeclaringType() = t and
(

View File

@@ -8,6 +8,7 @@ import csharp
/** An unsafe deserializer. */
abstract class UnsafeDeserializer extends Callable { }
/** An unsafe deserializer method in the `System.*` namespace. */
class SystemDeserializer extends UnsafeDeserializer {
SystemDeserializer() {
this
@@ -48,12 +49,17 @@ class SystemDeserializer extends UnsafeDeserializer {
}
}
/** An unsafe deserializer method in the `Microsoft.*` namespace. */
class MicrosoftDeserializer extends UnsafeDeserializer {
MicrosoftDeserializer() {
this.hasQualifiedName("Microsoft.Web.Design.Remote.ProxyObject", "DecodeValue")
}
}
/**
* An unsafe deserializer method that calls any unsafe deserializer on any of
* the parameters.
*/
class WrapperDeserializer extends UnsafeDeserializer {
WrapperDeserializer() {
exists(Call call |

View File

@@ -1,5 +1,14 @@
/**
* Provides classes to identify any .Net serializable type such as types
* attributed with `SerializableAttribute` and types implementing the
* `ISerializable` interface.
*/
import csharp
/**
* A constructor with `SerializationInfo` and `StreamingContext` parameters.
*/
class SerializationConstructor extends Constructor {
SerializationConstructor() {
this.getNumberOfParameters() = 2 and
@@ -91,16 +100,3 @@ class CustomBinarySerializableType extends BinarySerializableType {
result.(SerializationConstructor).getDeclaringType() = this
}
}
class DangerousCallable extends Callable {
DangerousCallable() {
//files
this.(Method).getQualifiedName().matches("System.IO.File.Write%") or
this.(Method).getQualifiedName().matches("System.IO.File.%Copy%") or
this.(Method).getQualifiedName().matches("System.IO.File.%Move%") or
this.(Method).getQualifiedName().matches("System.IO.File.%Append%") or
this.(Method).getQualifiedName().matches("System.IO.%.%Delete%") or
//assembly
this.(Method).getQualifiedName().matches("System.Reflection.Assembly.%Load%")
}
}

View File

@@ -1,3 +1,8 @@
/**
* Provides `Callable` classes, which are things that can be called
* such as methods and constructors.
*/
import Declaration
import Variable
import Expr

View File

@@ -1,3 +1,5 @@
/** Provides classes for .Net variables, such as fields and parameters. */
import Declaration
import Callable

View File

@@ -18,7 +18,7 @@ abstractValue
| 0 | Collections.cs:78:36:78:36 | 0 |
| 0 | Collections.cs:80:35:80:35 | 0 |
| 0 | Collections.cs:81:36:81:36 | 0 |
| 0 | Collections.cs:87:17:87:31 | 0 |
| 0 | Collections.cs:87:17:87:32 | 0 |
| 0 | Guards.cs:12:24:12:24 | 0 |
| 0 | Guards.cs:78:26:78:26 | 0 |
| 0 | Guards.cs:80:25:80:25 | 0 |
@@ -59,8 +59,8 @@ abstractValue
| 1 | Guards.cs:331:17:331:19 | access to constant B |
| 1 | Guards.cs:334:13:334:15 | access to constant B |
| 1 | Guards.cs:335:18:335:18 | 1 |
| 3 | Collections.cs:55:13:55:41 | 3 |
| 3 | Collections.cs:63:17:63:45 | 3 |
| 3 | Collections.cs:55:13:55:42 | 3 |
| 3 | Collections.cs:63:17:63:46 | 3 |
| 10 | Guards.cs:84:25:84:26 | 10 |
| 10 | Guards.cs:86:26:86:27 | 10 |
| empty | Collections.cs:54:13:54:16 | access to parameter args |
@@ -69,22 +69,22 @@ abstractValue
| empty | Collections.cs:58:9:58:13 | ... = ... |
| empty | Collections.cs:58:13:58:13 | access to local variable x |
| empty | Collections.cs:65:13:65:13 | access to local variable x |
| empty | Collections.cs:87:17:87:31 | array creation of type String[] |
| empty | Collections.cs:87:30:87:31 | { ..., ... } |
| empty | Collections.cs:88:22:88:23 | { ..., ... } |
| empty | Collections.cs:87:17:87:32 | array creation of type String[] |
| empty | Collections.cs:87:30:87:32 | { ..., ... } |
| empty | Collections.cs:88:22:88:24 | { ..., ... } |
| false | Guards.cs:178:16:178:20 | false |
| false | Guards.cs:181:53:181:57 | false |
| false | Guards.cs:217:18:217:22 | false |
| false | Guards.cs:228:18:228:22 | false |
| false | Guards.cs:295:18:295:22 | false |
| false | Guards.cs:305:18:305:22 | false |
| non-empty | Collections.cs:55:9:55:41 | ... = ... |
| non-empty | Collections.cs:55:13:55:41 | array creation of type String[] |
| non-empty | Collections.cs:55:25:55:41 | { ..., ... } |
| non-empty | Collections.cs:55:9:55:42 | ... = ... |
| non-empty | Collections.cs:55:13:55:42 | array creation of type String[] |
| non-empty | Collections.cs:55:26:55:42 | { ..., ... } |
| non-empty | Collections.cs:56:9:56:13 | ... = ... |
| non-empty | Collections.cs:56:13:56:13 | access to local variable x |
| non-empty | Collections.cs:63:17:63:45 | array creation of type String[] |
| non-empty | Collections.cs:63:29:63:45 | { ..., ... } |
| non-empty | Collections.cs:63:17:63:46 | array creation of type String[] |
| non-empty | Collections.cs:63:30:63:46 | { ..., ... } |
| non-empty | Collections.cs:68:13:68:13 | access to local variable x |
| non-empty | Collections.cs:89:9:89:32 | ... = ... |
| non-empty | Collections.cs:89:13:89:32 | array creation of type String[] |
@@ -155,11 +155,11 @@ abstractValue
| non-null | Collections.cs:54:13:54:16 | access to parameter args |
| non-null | Collections.cs:54:13:54:26 | call to method ToArray |
| non-null | Collections.cs:55:9:55:9 | access to local variable x |
| non-null | Collections.cs:55:9:55:41 | ... = ... |
| non-null | Collections.cs:55:13:55:41 | array creation of type String[] |
| non-null | Collections.cs:55:27:55:29 | "a" |
| non-null | Collections.cs:55:32:55:34 | "b" |
| non-null | Collections.cs:55:37:55:39 | "c" |
| non-null | Collections.cs:55:9:55:42 | ... = ... |
| non-null | Collections.cs:55:13:55:42 | array creation of type String[] |
| non-null | Collections.cs:55:28:55:30 | "a" |
| non-null | Collections.cs:55:33:55:35 | "b" |
| non-null | Collections.cs:55:38:55:40 | "c" |
| non-null | Collections.cs:56:9:56:9 | access to local variable x |
| non-null | Collections.cs:56:9:56:13 | ... = ... |
| non-null | Collections.cs:56:13:56:13 | access to local variable x |
@@ -169,11 +169,11 @@ abstractValue
| non-null | Collections.cs:58:9:58:9 | access to local variable x |
| non-null | Collections.cs:58:9:58:13 | ... = ... |
| non-null | Collections.cs:58:13:58:13 | access to local variable x |
| non-null | Collections.cs:63:17:63:45 | array creation of type String[] |
| non-null | Collections.cs:63:17:63:54 | call to method ToList |
| non-null | Collections.cs:63:31:63:33 | "a" |
| non-null | Collections.cs:63:36:63:38 | "b" |
| non-null | Collections.cs:63:41:63:43 | "c" |
| non-null | Collections.cs:63:17:63:46 | array creation of type String[] |
| non-null | Collections.cs:63:17:63:55 | call to method ToList |
| non-null | Collections.cs:63:32:63:34 | "a" |
| non-null | Collections.cs:63:37:63:39 | "b" |
| non-null | Collections.cs:63:42:63:44 | "c" |
| non-null | Collections.cs:64:9:64:9 | access to local variable x |
| non-null | Collections.cs:65:13:65:13 | access to local variable x |
| non-null | Collections.cs:67:13:67:13 | access to local variable x |
@@ -214,14 +214,20 @@ abstractValue
| non-null | Collections.cs:82:24:82:30 | access to local function IsEmpty |
| non-null | Collections.cs:82:24:82:30 | delegate creation of type Func<String,Boolean> |
| non-null | Collections.cs:82:24:82:30 | this access |
| non-null | Collections.cs:87:17:87:31 | array creation of type String[] |
| non-null | Collections.cs:88:22:88:23 | array creation of type String[] |
| non-null | Collections.cs:87:17:87:32 | array creation of type String[] |
| non-null | Collections.cs:88:22:88:24 | array creation of type String[] |
| non-null | Collections.cs:89:9:89:9 | access to local variable x |
| non-null | Collections.cs:89:9:89:32 | ... = ... |
| non-null | Collections.cs:89:13:89:32 | array creation of type String[] |
| non-null | Collections.cs:89:28:89:30 | "a" |
| non-null | Collections.cs:90:22:90:28 | array creation of type String[] |
| non-null | Collections.cs:90:24:90:26 | "a" |
| non-null | Collections.cs:95:29:95:32 | access to parameter args |
| non-null | Collections.cs:96:13:96:19 | access to type Console |
| non-null | Collections.cs:96:31:96:34 | access to parameter args |
| non-null | Collections.cs:101:29:101:32 | access to parameter args |
| non-null | Collections.cs:103:9:103:15 | access to type Console |
| non-null | Collections.cs:103:27:103:30 | access to parameter args |
| non-null | Guards.cs:12:13:12:13 | access to parameter s |
| non-null | Guards.cs:14:13:14:19 | access to type Console |
| non-null | Guards.cs:14:31:14:31 | access to parameter s |

View File

@@ -52,7 +52,7 @@ public class Collections
var x = args.ToArray();
args.Clear();
x = args.ToArray();
x = new string[]{ "a", "b", "c" };
x = new string[] { "a", "b", "c" };
x = x;
x = new string[0];
x = x;
@@ -60,7 +60,7 @@ public class Collections
void M6()
{
var x = new string[]{ "a", "b", "c" }.ToList();
var x = new string[] { "a", "b", "c" }.ToList();
x.Clear();
if (x.Count == 0)
{
@@ -84,10 +84,23 @@ public class Collections
void M8()
{
var x = new string[] {};
string[] y = {};
var x = new string[] { };
string[] y = { };
x = new string[] { "a" };
string[] z = { "a" };
}
void M9(string[] args)
{
foreach (var arg in args)
Console.WriteLine(args); // guarded by `args` being non-empty
}
void M10(string[] args)
{
foreach (var arg in args)
;
Console.WriteLine(args);
}
}

View File

@@ -37,6 +37,7 @@
| Collections.cs:67:13:67:13 | access to local variable x | Collections.cs:65:13:65:13 | access to local variable x | Collections.cs:65:13:65:13 | access to local variable x | empty |
| Collections.cs:67:13:67:13 | access to local variable x | Collections.cs:65:13:65:24 | ... == ... | Collections.cs:65:13:65:13 | access to local variable x | true |
| Collections.cs:68:13:68:13 | access to local variable x | Collections.cs:65:13:65:24 | ... == ... | Collections.cs:65:13:65:13 | access to local variable x | true |
| Collections.cs:96:31:96:34 | access to parameter args | Collections.cs:95:29:95:32 | access to parameter args | Collections.cs:95:29:95:32 | access to parameter args | non-empty |
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:24 | ... == ... | Guards.cs:10:16:10:16 | access to parameter s | false |
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |

View File

@@ -37,6 +37,7 @@
| Collections.cs:67:13:67:13 | access to local variable x | Collections.cs:65:13:65:13 | access to local variable x | Collections.cs:65:13:65:13 | access to local variable x | empty |
| Collections.cs:67:13:67:13 | access to local variable x | Collections.cs:65:13:65:24 | ... == ... | Collections.cs:65:13:65:13 | access to local variable x | true |
| Collections.cs:68:13:68:13 | access to local variable x | Collections.cs:65:13:65:24 | ... == ... | Collections.cs:65:13:65:13 | access to local variable x | true |
| Collections.cs:96:31:96:34 | access to parameter args | Collections.cs:95:29:95:32 | access to parameter args | Collections.cs:95:29:95:32 | access to parameter args | non-empty |
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:24 | ... == ... | Guards.cs:10:16:10:16 | access to parameter s | false |
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |

View File

@@ -180,26 +180,26 @@
| Collections.cs:45:17:45:26 | call to method Any | true | Collections.cs:45:17:45:20 | access to parameter args | non-empty |
| Collections.cs:50:13:50:27 | ... == ... | false | Collections.cs:50:13:50:16 | access to parameter args | non-empty |
| Collections.cs:50:13:50:27 | ... == ... | true | Collections.cs:50:13:50:16 | access to parameter args | empty |
| Collections.cs:56:13:56:13 | access to local variable x | empty | Collections.cs:55:13:55:41 | array creation of type String[] | empty |
| Collections.cs:56:13:56:13 | access to local variable x | non-empty | Collections.cs:55:13:55:41 | array creation of type String[] | non-empty |
| Collections.cs:56:13:56:13 | access to local variable x | non-null | Collections.cs:55:13:55:41 | array creation of type String[] | non-null |
| Collections.cs:56:13:56:13 | access to local variable x | null | Collections.cs:55:13:55:41 | array creation of type String[] | null |
| Collections.cs:56:13:56:13 | access to local variable x | empty | Collections.cs:55:13:55:42 | array creation of type String[] | empty |
| Collections.cs:56:13:56:13 | access to local variable x | non-empty | Collections.cs:55:13:55:42 | array creation of type String[] | non-empty |
| Collections.cs:56:13:56:13 | access to local variable x | non-null | Collections.cs:55:13:55:42 | array creation of type String[] | non-null |
| Collections.cs:56:13:56:13 | access to local variable x | null | Collections.cs:55:13:55:42 | array creation of type String[] | null |
| Collections.cs:58:13:58:13 | access to local variable x | empty | Collections.cs:57:13:57:25 | array creation of type String[] | empty |
| Collections.cs:58:13:58:13 | access to local variable x | non-empty | Collections.cs:57:13:57:25 | array creation of type String[] | non-empty |
| Collections.cs:58:13:58:13 | access to local variable x | non-null | Collections.cs:57:13:57:25 | array creation of type String[] | non-null |
| Collections.cs:58:13:58:13 | access to local variable x | null | Collections.cs:57:13:57:25 | array creation of type String[] | null |
| Collections.cs:64:9:64:9 | access to local variable x | empty | Collections.cs:63:17:63:54 | call to method ToList | empty |
| Collections.cs:64:9:64:9 | access to local variable x | non-empty | Collections.cs:63:17:63:54 | call to method ToList | non-empty |
| Collections.cs:64:9:64:9 | access to local variable x | non-null | Collections.cs:63:17:63:54 | call to method ToList | non-null |
| Collections.cs:64:9:64:9 | access to local variable x | null | Collections.cs:63:17:63:54 | call to method ToList | null |
| Collections.cs:65:13:65:13 | access to local variable x | non-null | Collections.cs:63:17:63:54 | call to method ToList | non-null |
| Collections.cs:65:13:65:13 | access to local variable x | null | Collections.cs:63:17:63:54 | call to method ToList | null |
| Collections.cs:64:9:64:9 | access to local variable x | empty | Collections.cs:63:17:63:55 | call to method ToList | empty |
| Collections.cs:64:9:64:9 | access to local variable x | non-empty | Collections.cs:63:17:63:55 | call to method ToList | non-empty |
| Collections.cs:64:9:64:9 | access to local variable x | non-null | Collections.cs:63:17:63:55 | call to method ToList | non-null |
| Collections.cs:64:9:64:9 | access to local variable x | null | Collections.cs:63:17:63:55 | call to method ToList | null |
| Collections.cs:65:13:65:13 | access to local variable x | non-null | Collections.cs:63:17:63:55 | call to method ToList | non-null |
| Collections.cs:65:13:65:13 | access to local variable x | null | Collections.cs:63:17:63:55 | call to method ToList | null |
| Collections.cs:65:13:65:24 | ... == ... | false | Collections.cs:65:13:65:13 | access to local variable x | non-empty |
| Collections.cs:65:13:65:24 | ... == ... | true | Collections.cs:65:13:65:13 | access to local variable x | empty |
| Collections.cs:67:13:67:13 | access to local variable x | non-null | Collections.cs:63:17:63:54 | call to method ToList | non-null |
| Collections.cs:67:13:67:13 | access to local variable x | null | Collections.cs:63:17:63:54 | call to method ToList | null |
| Collections.cs:68:13:68:13 | access to local variable x | non-null | Collections.cs:63:17:63:54 | call to method ToList | non-null |
| Collections.cs:68:13:68:13 | access to local variable x | null | Collections.cs:63:17:63:54 | call to method ToList | null |
| Collections.cs:67:13:67:13 | access to local variable x | non-null | Collections.cs:63:17:63:55 | call to method ToList | non-null |
| Collections.cs:67:13:67:13 | access to local variable x | null | Collections.cs:63:17:63:55 | call to method ToList | null |
| Collections.cs:68:13:68:13 | access to local variable x | non-null | Collections.cs:63:17:63:55 | call to method ToList | non-null |
| Collections.cs:68:13:68:13 | access to local variable x | null | Collections.cs:63:17:63:55 | call to method ToList | null |
| Collections.cs:74:35:74:41 | ... == ... | true | Collections.cs:74:35:74:35 | access to parameter s | non-null |
| Collections.cs:74:35:74:41 | ... == ... | true | Collections.cs:74:40:74:41 | "" | non-null |
| Collections.cs:75:17:75:33 | call to method Any | true | Collections.cs:75:17:75:20 | access to parameter args | non-empty |

View File

@@ -1 +1 @@
| expressions.cs:443:33:443:66 | delegate(...) { ... } |
| expressions.cs:455:33:455:66 | delegate(...) { ... } |

View File

@@ -1 +1 @@
| expressions.cs:443:33:443:66 | delegate(...) { ... } | expressions.cs:443:47:443:47 | x |
| expressions.cs:455:33:455:66 | delegate(...) { ... } | expressions.cs:455:47:455:47 | x |

View File

@@ -1 +1 @@
| expressions.cs:443:33:443:66 | delegate(...) { ... } |
| expressions.cs:455:33:455:66 | delegate(...) { ... } |

View File

@@ -1 +1 @@
| expressions.cs:445:28:445:53 | delegate(...) { ... } | expressions.cs:445:28:445:53 | delegate(...) { ... } |
| expressions.cs:457:28:457:53 | delegate(...) { ... } | expressions.cs:457:28:457:53 | delegate(...) { ... } |

View File

@@ -1 +1 @@
| expressions.cs:445:28:445:53 | delegate(...) { ... } | expressions.cs:445:46:445:46 | access to local variable j |
| expressions.cs:457:28:457:53 | delegate(...) { ... } | expressions.cs:457:46:457:46 | access to local variable j |

View File

@@ -1,3 +1,27 @@
| expressions.cs:168:27:168:44 | array creation of type Object[] | expressions.cs:168:27:168:44 | 1 | true |
| expressions.cs:409:23:409:65 | array creation of type Int32[,] | expressions.cs:409:23:409:65 | 2 | true |
| expressions.cs:409:23:409:65 | array creation of type Int32[,] | expressions.cs:409:23:409:65 | 3 | true |
| expressions.cs:409:23:409:65 | array creation of type Int32[,] | expressions.cs:409:23:409:65 | 3 | true |
| expressions.cs:437:24:437:66 | array creation of type Int32[,] | expressions.cs:437:24:437:66 | 2 | true |
| expressions.cs:437:24:437:66 | array creation of type Int32[,] | expressions.cs:437:24:437:66 | 3 | true |
| expressions.cs:438:17:438:93 | array creation of type Int32[,,] | expressions.cs:438:17:438:93 | 2 | true |
| expressions.cs:438:17:438:93 | array creation of type Int32[,,] | expressions.cs:438:17:438:93 | 2 | true |
| expressions.cs:438:17:438:93 | array creation of type Int32[,,] | expressions.cs:438:17:438:93 | 3 | true |
| expressions.cs:439:17:443:13 | array creation of type Int32[,][,] | expressions.cs:439:17:443:13 | 2 | true |
| expressions.cs:439:17:443:13 | array creation of type Int32[,][,] | expressions.cs:439:17:443:13 | 3 | true |
| expressions.cs:441:19:441:45 | array creation of type Int32[,] | expressions.cs:441:19:441:45 | 2 | true |
| expressions.cs:441:19:441:45 | array creation of type Int32[,] | expressions.cs:441:19:441:45 | 2 | true |
| expressions.cs:441:48:441:82 | array creation of type Int32[,] | expressions.cs:441:48:441:82 | 2 | true |
| expressions.cs:441:48:441:82 | array creation of type Int32[,] | expressions.cs:441:48:441:82 | 3 | true |
| expressions.cs:441:85:441:122 | array creation of type Int32[,] | expressions.cs:441:85:441:122 | 2 | true |
| expressions.cs:441:85:441:122 | array creation of type Int32[,] | expressions.cs:441:85:441:122 | 3 | true |
| expressions.cs:442:19:442:45 | array creation of type Int32[,] | expressions.cs:442:19:442:45 | 2 | true |
| expressions.cs:442:19:442:45 | array creation of type Int32[,] | expressions.cs:442:19:442:45 | 2 | true |
| expressions.cs:442:48:442:82 | array creation of type Int32[,] | expressions.cs:442:48:442:82 | 2 | true |
| expressions.cs:442:48:442:82 | array creation of type Int32[,] | expressions.cs:442:48:442:82 | 3 | true |
| expressions.cs:442:85:442:122 | array creation of type Int32[,] | expressions.cs:442:85:442:122 | 2 | true |
| expressions.cs:442:85:442:122 | array creation of type Int32[,] | expressions.cs:442:85:442:122 | 3 | true |
| expressions.cs:444:17:444:123 | array creation of type Int32[,][] | expressions.cs:444:17:444:123 | 2 | true |
| expressions.cs:444:32:444:54 | array creation of type Int32[,] | expressions.cs:444:32:444:54 | 1 | true |
| expressions.cs:444:32:444:54 | array creation of type Int32[,] | expressions.cs:444:32:444:54 | 2 | true |
| expressions.cs:444:57:444:121 | array creation of type Int32[,] | expressions.cs:444:57:444:121 | 3 | true |
| expressions.cs:444:57:444:121 | array creation of type Int32[,] | expressions.cs:444:57:444:121 | 4 | true |

View File

@@ -1 +1 @@
| expressions.cs:437:36:437:53 | (...) => ... |
| expressions.cs:449:36:449:53 | (...) => ... |

View File

@@ -1 +1 @@
| expressions.cs:438:38:438:59 | (...) => ... |
| expressions.cs:450:38:450:59 | (...) => ... |

View File

@@ -1 +1 @@
| expressions.cs:439:33:439:48 | (...) => ... |
| expressions.cs:451:33:451:48 | (...) => ... |

View File

@@ -1 +1 @@
| expressions.cs:440:36:440:64 | (...) => ... |
| expressions.cs:452:36:452:64 | (...) => ... |

View File

@@ -1 +1 @@
| expressions.cs:441:20:441:34 | (...) => ... |
| expressions.cs:453:20:453:34 | (...) => ... |

View File

@@ -1 +1 @@
| expressions.cs:442:23:442:47 | (...) => ... |
| expressions.cs:454:23:454:47 | (...) => ... |

View File

@@ -1,4 +1,4 @@
| expressions.cs:458:20:458:27 | addition | expressions.cs:460:26:460:26 | access to parameter a | expressions.cs:473:40:473:40 | + |
| expressions.cs:458:20:458:27 | addition | expressions.cs:460:30:460:30 | access to parameter b | expressions.cs:473:40:473:40 | + |
| expressions.cs:458:20:458:27 | addition | expressions.cs:461:13:461:18 | access to local variable result | expressions.cs:473:40:473:40 | + |
| expressions.cs:458:20:458:27 | addition | expressions.cs:461:23:461:23 | access to parameter c | expressions.cs:473:40:473:40 | + |
| expressions.cs:470:20:470:27 | addition | expressions.cs:472:26:472:26 | access to parameter a | expressions.cs:485:40:485:40 | + |
| expressions.cs:470:20:470:27 | addition | expressions.cs:472:30:472:30 | access to parameter b | expressions.cs:485:40:485:40 | + |
| expressions.cs:470:20:470:27 | addition | expressions.cs:473:13:473:18 | access to local variable result | expressions.cs:485:40:485:40 | + |
| expressions.cs:470:20:470:27 | addition | expressions.cs:473:23:473:23 | access to parameter c | expressions.cs:485:40:485:40 | + |

View File

@@ -1,2 +1,2 @@
| expressions.cs:452:21:452:35 | delegateCombine | expressions.cs:450:11:450:23 | OperatorCalls | expressions.cs:455:13:455:27 | access to local variable PropertyChanged | expressions.cs:479:30:479:39 | MyDelegate |
| expressions.cs:452:21:452:35 | delegateCombine | expressions.cs:450:11:450:23 | OperatorCalls | expressions.cs:455:32:455:34 | access to parameter fun | expressions.cs:479:30:479:39 | MyDelegate |
| expressions.cs:464:21:464:35 | delegateCombine | expressions.cs:462:11:462:23 | OperatorCalls | expressions.cs:467:13:467:27 | access to local variable PropertyChanged | expressions.cs:491:30:491:39 | MyDelegate |
| expressions.cs:464:21:464:35 | delegateCombine | expressions.cs:462:11:462:23 | OperatorCalls | expressions.cs:467:32:467:34 | access to parameter fun | expressions.cs:491:30:491:39 | MyDelegate |

View File

@@ -1491,333 +1491,467 @@ expressions.cs:
# 432| 0: [Parameter] x
# 432| 1: [Parameter] y
# 433| 7: [DelegateType] Unit
# 435| 8: [Method] MainAnonymousFunctions
# 435| 8: [Method] MultiDimensionalArrayCreations
# 436| 4: [BlockStmt] {...}
# 437| 0: [LocalVariableDeclStmt] ... ...;
# 437| 0: [LocalVariableDeclAndInitExpr] Func<Int16,Byte> f1 = ...
# 437| 0: [LambdaExpr] (...) => ...
# 437| 0: [CastExpr] (...) ...
# 437| 0: [AddExpr] ... + ...
# 437| 0: [CastExpr] (...) ...
# 437| 0: [ParameterAccess] access to parameter x
# 437| 1: [IntLiteral] 1
# 437| 1: [TypeAccess] access to type Byte
# 437| 0: [LocalVariableDeclAndInitExpr] Object o = ...
# 437| 0: [ArrayCreation] array creation of type Int32[,]
# 437| -1: [ArrayInitializer] { ..., ... }
# 437| 0: [ArrayInitializer] { ..., ... }
# 437| 0: [IntLiteral] 1
# 437| 1: [IntLiteral] 2
# 437| 1: [ArrayInitializer] { ..., ... }
# 437| 0: [IntLiteral] 3
# 437| 1: [IntLiteral] 4
# 437| 2: [ArrayInitializer] { ..., ... }
# 437| 0: [IntLiteral] 5
# 437| 1: [IntLiteral] 6
# 437| 1: [LocalVariableAccess] access to local variable o
# 438| 1: [ExprStmt] ...;
# 438| 0: [AssignExpr] ... = ...
# 438| 0: [ArrayCreation] array creation of type Int32[,,]
# 438| -1: [ArrayInitializer] { ..., ... }
# 438| 0: [ArrayInitializer] { ..., ... }
# 438| 0: [ArrayInitializer] { ..., ... }
# 438| 0: [IntLiteral] 1
# 438| 1: [IntLiteral] 2
# 438| 2: [IntLiteral] 3
# 438| 1: [ArrayInitializer] { ..., ... }
# 438| 0: [IntLiteral] 4
# 438| 1: [IntLiteral] 5
# 438| 2: [IntLiteral] 6
# 438| 1: [ArrayInitializer] { ..., ... }
# 438| 0: [ArrayInitializer] { ..., ... }
# 438| 0: [IntLiteral] 7
# 438| 1: [IntLiteral] 8
# 438| 2: [IntLiteral] 9
# 438| 1: [ArrayInitializer] { ..., ... }
# 438| 0: [IntLiteral] 10
# 438| 1: [IntLiteral] 11
# 438| 2: [IntLiteral] 12
# 438| 1: [LocalVariableAccess] access to local variable o
# 439| 2: [ExprStmt] ...;
# 439| 0: [AssignExpr] ... = ...
# 439| 0: [ArrayCreation] array creation of type Int32[,][,]
# 440| -1: [ArrayInitializer] { ..., ... }
# 441| 0: [ArrayInitializer] { ..., ... }
# 441| 0: [ArrayCreation] array creation of type Int32[,]
# 441| -1: [ArrayInitializer] { ..., ... }
# 441| 0: [ArrayInitializer] { ..., ... }
# 441| 0: [IntLiteral] 1
# 441| 1: [IntLiteral] 3
# 441| 1: [ArrayInitializer] { ..., ... }
# 441| 0: [IntLiteral] 5
# 441| 1: [IntLiteral] 7
# 441| 1: [ArrayCreation] array creation of type Int32[,]
# 441| -1: [ArrayInitializer] { ..., ... }
# 441| 0: [ArrayInitializer] { ..., ... }
# 441| 0: [IntLiteral] 0
# 441| 1: [IntLiteral] 2
# 441| 1: [ArrayInitializer] { ..., ... }
# 441| 0: [IntLiteral] 4
# 441| 1: [IntLiteral] 6
# 441| 2: [ArrayInitializer] { ..., ... }
# 441| 0: [IntLiteral] 8
# 441| 1: [IntLiteral] 10
# 441| 2: [ArrayCreation] array creation of type Int32[,]
# 441| -1: [ArrayInitializer] { ..., ... }
# 441| 0: [ArrayInitializer] { ..., ... }
# 441| 0: [IntLiteral] 11
# 441| 1: [IntLiteral] 22
# 441| 1: [ArrayInitializer] { ..., ... }
# 441| 0: [IntLiteral] 99
# 441| 1: [IntLiteral] 88
# 441| 2: [ArrayInitializer] { ..., ... }
# 441| 0: [IntLiteral] 0
# 441| 1: [IntLiteral] 9
# 442| 1: [ArrayInitializer] { ..., ... }
# 442| 0: [ArrayCreation] array creation of type Int32[,]
# 442| -1: [ArrayInitializer] { ..., ... }
# 442| 0: [ArrayInitializer] { ..., ... }
# 442| 0: [IntLiteral] 1
# 442| 1: [IntLiteral] 3
# 442| 1: [ArrayInitializer] { ..., ... }
# 442| 0: [IntLiteral] 5
# 442| 1: [IntLiteral] 7
# 442| 1: [ArrayCreation] array creation of type Int32[,]
# 442| -1: [ArrayInitializer] { ..., ... }
# 442| 0: [ArrayInitializer] { ..., ... }
# 442| 0: [IntLiteral] 0
# 442| 1: [IntLiteral] 2
# 442| 1: [ArrayInitializer] { ..., ... }
# 442| 0: [IntLiteral] 4
# 442| 1: [IntLiteral] 6
# 442| 2: [ArrayInitializer] { ..., ... }
# 442| 0: [IntLiteral] 8
# 442| 1: [IntLiteral] 10
# 442| 2: [ArrayCreation] array creation of type Int32[,]
# 442| -1: [ArrayInitializer] { ..., ... }
# 442| 0: [ArrayInitializer] { ..., ... }
# 442| 0: [IntLiteral] 11
# 442| 1: [IntLiteral] 22
# 442| 1: [ArrayInitializer] { ..., ... }
# 442| 0: [IntLiteral] 99
# 442| 1: [IntLiteral] 88
# 442| 2: [ArrayInitializer] { ..., ... }
# 442| 0: [IntLiteral] 0
# 442| 1: [IntLiteral] 9
# 439| 1: [LocalVariableAccess] access to local variable o
# 444| 3: [ExprStmt] ...;
# 444| 0: [AssignExpr] ... = ...
# 444| 0: [ArrayCreation] array creation of type Int32[,][]
# 444| -1: [ArrayInitializer] { ..., ... }
# 444| 0: [ArrayCreation] array creation of type Int32[,]
# 444| -1: [ArrayInitializer] { ..., ... }
# 444| 0: [ArrayInitializer] { ..., ... }
# 444| 0: [IntLiteral] 1
# 444| 1: [IntLiteral] 2
# 444| 1: [ArrayCreation] array creation of type Int32[,]
# 444| -1: [ArrayInitializer] { ..., ... }
# 444| 0: [ArrayInitializer] { ..., ... }
# 444| 0: [IntLiteral] 1
# 444| 1: [IntLiteral] 2
# 444| 2: [IntLiteral] 3
# 444| 1: [ArrayInitializer] { ..., ... }
# 444| 0: [IntLiteral] 1
# 444| 1: [IntLiteral] 2
# 444| 2: [IntLiteral] 3
# 444| 2: [ArrayInitializer] { ..., ... }
# 444| 0: [IntLiteral] 1
# 444| 1: [IntLiteral] 2
# 444| 2: [IntLiteral] 3
# 444| 3: [ArrayInitializer] { ..., ... }
# 444| 0: [IntLiteral] 1
# 444| 1: [IntLiteral] 2
# 444| 2: [IntLiteral] 3
# 444| 1: [LocalVariableAccess] access to local variable o
# 447| 9: [Method] MainAnonymousFunctions
# 448| 4: [BlockStmt] {...}
# 449| 0: [LocalVariableDeclStmt] ... ...;
# 449| 0: [LocalVariableDeclAndInitExpr] Func<Int16,Byte> f1 = ...
# 449| 0: [LambdaExpr] (...) => ...
# 449| 0: [CastExpr] (...) ...
# 449| 0: [AddExpr] ... + ...
# 449| 0: [CastExpr] (...) ...
# 449| 0: [ParameterAccess] access to parameter x
# 449| 1: [IntLiteral] 1
# 449| 1: [TypeAccess] access to type Byte
#-----| 2: (Parameters)
# 437| 0: [Parameter] x
# 437| 1: [LocalVariableAccess] access to local variable f1
# 438| 1: [LocalVariableDeclStmt] ... ...;
# 438| 0: [LocalVariableDeclAndInitExpr] Func<Int32,Double> f2 = ...
# 438| 0: [LambdaExpr] (...) => ...
# 438| 0: [BlockStmt] {...}
# 438| 0: [ReturnStmt] return ...;
# 438| 0: [CastExpr] (...) ...
# 438| 0: [AddExpr] ... + ...
# 438| 0: [ParameterAccess] access to parameter x
# 438| 1: [IntLiteral] 1
# 449| 0: [Parameter] x
# 449| 1: [LocalVariableAccess] access to local variable f1
# 450| 1: [LocalVariableDeclStmt] ... ...;
# 450| 0: [LocalVariableDeclAndInitExpr] Func<Int32,Double> f2 = ...
# 450| 0: [LambdaExpr] (...) => ...
# 450| 0: [BlockStmt] {...}
# 450| 0: [ReturnStmt] return ...;
# 450| 0: [CastExpr] (...) ...
# 450| 0: [AddExpr] ... + ...
# 450| 0: [ParameterAccess] access to parameter x
# 450| 1: [IntLiteral] 1
#-----| 2: (Parameters)
# 438| 0: [Parameter] x
# 438| 1: [LocalVariableAccess] access to local variable f2
# 439| 2: [LocalVariableDeclStmt] ... ...;
# 439| 0: [LocalVariableDeclAndInitExpr] Func<Int32,Int32> f3 = ...
# 439| 0: [LambdaExpr] (...) => ...
# 439| 0: [AddExpr] ... + ...
# 439| 0: [ParameterAccess] access to parameter x
# 439| 1: [IntLiteral] 1
# 450| 0: [Parameter] x
# 450| 1: [LocalVariableAccess] access to local variable f2
# 451| 2: [LocalVariableDeclStmt] ... ...;
# 451| 0: [LocalVariableDeclAndInitExpr] Func<Int32,Int32> f3 = ...
# 451| 0: [LambdaExpr] (...) => ...
# 451| 0: [AddExpr] ... + ...
# 451| 0: [ParameterAccess] access to parameter x
# 451| 1: [IntLiteral] 1
#-----| 2: (Parameters)
# 439| 0: [Parameter] x
# 439| 1: [LocalVariableAccess] access to local variable f3
# 440| 3: [LocalVariableDeclStmt] ... ...;
# 440| 0: [LocalVariableDeclAndInitExpr] Func<Int32,String> f4 = ...
# 440| 0: [LambdaExpr] (...) => ...
# 440| 0: [BlockStmt] {...}
# 440| 0: [ReturnStmt] return ...;
# 440| 0: [AddExpr] ... + ...
# 440| 0: [CastExpr] (...) ...
# 440| 0: [ParameterAccess] access to parameter x
# 440| 1: [StringLiteral] ""
# 451| 0: [Parameter] x
# 451| 1: [LocalVariableAccess] access to local variable f3
# 452| 3: [LocalVariableDeclStmt] ... ...;
# 452| 0: [LocalVariableDeclAndInitExpr] Func<Int32,String> f4 = ...
# 452| 0: [LambdaExpr] (...) => ...
# 452| 0: [BlockStmt] {...}
# 452| 0: [ReturnStmt] return ...;
# 452| 0: [AddExpr] ... + ...
# 452| 0: [CastExpr] (...) ...
# 452| 0: [ParameterAccess] access to parameter x
# 452| 1: [StringLiteral] ""
#-----| 2: (Parameters)
# 440| 0: [Parameter] x
# 440| 1: [LocalVariableAccess] access to local variable f4
# 441| 4: [LocalVariableDeclStmt] ... ...;
# 441| 0: [LocalVariableDeclAndInitExpr] S f5 = ...
# 441| 0: [LambdaExpr] (...) => ...
# 441| 0: [MulExpr] ... * ...
# 441| 0: [ParameterAccess] access to parameter x
# 441| 1: [ParameterAccess] access to parameter y
# 452| 0: [Parameter] x
# 452| 1: [LocalVariableAccess] access to local variable f4
# 453| 4: [LocalVariableDeclStmt] ... ...;
# 453| 0: [LocalVariableDeclAndInitExpr] S f5 = ...
# 453| 0: [LambdaExpr] (...) => ...
# 453| 0: [MulExpr] ... * ...
# 453| 0: [ParameterAccess] access to parameter x
# 453| 1: [ParameterAccess] access to parameter y
#-----| 2: (Parameters)
# 441| 0: [Parameter] x
# 441| 1: [Parameter] y
# 441| 1: [LocalVariableAccess] access to local variable f5
# 442| 5: [LocalVariableDeclStmt] ... ...;
# 442| 0: [LocalVariableDeclAndInitExpr] Unit f6 = ...
# 442| 0: [LambdaExpr] (...) => ...
# 442| 0: [MethodCall] call to method WriteLine
# 442| -1: [TypeAccess] access to type Console
# 442| 1: [LocalVariableAccess] access to local variable f6
# 443| 6: [LocalVariableDeclStmt] ... ...;
# 443| 0: [LocalVariableDeclAndInitExpr] Func<Int32,Int32> f7 = ...
# 443| 0: [AnonymousMethodExpr] delegate(...) { ... }
# 443| 0: [BlockStmt] {...}
# 443| 0: [ReturnStmt] return ...;
# 443| 0: [AddExpr] ... + ...
# 443| 0: [ParameterAccess] access to parameter x
# 443| 1: [IntLiteral] 1
# 453| 0: [Parameter] x
# 453| 1: [Parameter] y
# 453| 1: [LocalVariableAccess] access to local variable f5
# 454| 5: [LocalVariableDeclStmt] ... ...;
# 454| 0: [LocalVariableDeclAndInitExpr] Unit f6 = ...
# 454| 0: [LambdaExpr] (...) => ...
# 454| 0: [MethodCall] call to method WriteLine
# 454| -1: [TypeAccess] access to type Console
# 454| 1: [LocalVariableAccess] access to local variable f6
# 455| 6: [LocalVariableDeclStmt] ... ...;
# 455| 0: [LocalVariableDeclAndInitExpr] Func<Int32,Int32> f7 = ...
# 455| 0: [AnonymousMethodExpr] delegate(...) { ... }
# 455| 0: [BlockStmt] {...}
# 455| 0: [ReturnStmt] return ...;
# 455| 0: [AddExpr] ... + ...
# 455| 0: [ParameterAccess] access to parameter x
# 455| 1: [IntLiteral] 1
#-----| 2: (Parameters)
# 443| 0: [Parameter] x
# 443| 1: [LocalVariableAccess] access to local variable f7
# 444| 7: [LocalVariableDeclStmt] ... ...;
# 444| 0: [LocalVariableDeclAndInitExpr] Int32 j = ...
# 444| 0: [IntLiteral] 0
# 444| 1: [LocalVariableAccess] access to local variable j
# 445| 8: [LocalVariableDeclStmt] ... ...;
# 445| 0: [LocalVariableDeclAndInitExpr] Func<Int32> f8 = ...
# 445| 0: [AnonymousMethodExpr] delegate(...) { ... }
# 445| 0: [BlockStmt] {...}
# 445| 0: [ReturnStmt] return ...;
# 445| 0: [AddExpr] ... + ...
# 445| 0: [LocalVariableAccess] access to local variable j
# 445| 1: [IntLiteral] 1
# 445| 1: [LocalVariableAccess] access to local variable f8
# 450| 18: [Class] OperatorCalls
# 452| 5: [Method] delegateCombine
# 455| 0: [Parameter] x
# 455| 1: [LocalVariableAccess] access to local variable f7
# 456| 7: [LocalVariableDeclStmt] ... ...;
# 456| 0: [LocalVariableDeclAndInitExpr] Int32 j = ...
# 456| 0: [IntLiteral] 0
# 456| 1: [LocalVariableAccess] access to local variable j
# 457| 8: [LocalVariableDeclStmt] ... ...;
# 457| 0: [LocalVariableDeclAndInitExpr] Func<Int32> f8 = ...
# 457| 0: [AnonymousMethodExpr] delegate(...) { ... }
# 457| 0: [BlockStmt] {...}
# 457| 0: [ReturnStmt] return ...;
# 457| 0: [AddExpr] ... + ...
# 457| 0: [LocalVariableAccess] access to local variable j
# 457| 1: [IntLiteral] 1
# 457| 1: [LocalVariableAccess] access to local variable f8
# 462| 18: [Class] OperatorCalls
# 464| 5: [Method] delegateCombine
#-----| 2: (Parameters)
# 452| 0: [Parameter] fun
# 453| 4: [BlockStmt] {...}
# 454| 0: [LocalVariableDeclStmt] ... ...;
# 454| 0: [LocalVariableDeclAndInitExpr] MyDelegate PropertyChanged = ...
# 454| 0: [NullLiteral] null
# 454| 1: [LocalVariableAccess] access to local variable PropertyChanged
# 455| 1: [ExprStmt] ...;
# 455| 0: [AssignAddExpr] ... += ...
# 455| 0: [ParameterAccess] access to parameter fun
# 455| 1: [LocalVariableAccess] access to local variable PropertyChanged
# 458| 6: [Method] addition
# 464| 0: [Parameter] fun
# 465| 4: [BlockStmt] {...}
# 466| 0: [LocalVariableDeclStmt] ... ...;
# 466| 0: [LocalVariableDeclAndInitExpr] MyDelegate PropertyChanged = ...
# 466| 0: [NullLiteral] null
# 466| 1: [LocalVariableAccess] access to local variable PropertyChanged
# 467| 1: [ExprStmt] ...;
# 467| 0: [AssignAddExpr] ... += ...
# 467| 0: [ParameterAccess] access to parameter fun
# 467| 1: [LocalVariableAccess] access to local variable PropertyChanged
# 470| 6: [Method] addition
#-----| 2: (Parameters)
# 458| 0: [Parameter] a
# 458| 1: [Parameter] b
# 458| 2: [Parameter] c
# 459| 4: [BlockStmt] {...}
# 460| 0: [LocalVariableDeclStmt] ... ...;
# 460| 0: [LocalVariableDeclAndInitExpr] Num result = ...
# 460| 0: [OperatorCall] call to operator +
# 460| 0: [ParameterAccess] access to parameter a
# 460| 1: [ParameterAccess] access to parameter b
# 460| 1: [LocalVariableAccess] access to local variable result
# 461| 1: [ExprStmt] ...;
# 461| 0: [AssignAddExpr] ... += ...
# 461| 0: [ParameterAccess] access to parameter c
# 461| 1: [LocalVariableAccess] access to local variable result
# 462| 2: [ReturnStmt] return ...;
# 462| 0: [LocalVariableAccess] access to local variable result
# 464| 7: [Class] Num
# 466| 4: [Field] value
# 468| 5: [InstanceConstructor] Num
# 470| 0: [Parameter] a
# 470| 1: [Parameter] b
# 470| 2: [Parameter] c
# 471| 4: [BlockStmt] {...}
# 472| 0: [LocalVariableDeclStmt] ... ...;
# 472| 0: [LocalVariableDeclAndInitExpr] Num result = ...
# 472| 0: [OperatorCall] call to operator +
# 472| 0: [ParameterAccess] access to parameter a
# 472| 1: [ParameterAccess] access to parameter b
# 472| 1: [LocalVariableAccess] access to local variable result
# 473| 1: [ExprStmt] ...;
# 473| 0: [AssignAddExpr] ... += ...
# 473| 0: [ParameterAccess] access to parameter c
# 473| 1: [LocalVariableAccess] access to local variable result
# 474| 2: [ReturnStmt] return ...;
# 474| 0: [LocalVariableAccess] access to local variable result
# 476| 7: [Class] Num
# 478| 4: [Field] value
# 480| 5: [InstanceConstructor] Num
#-----| 2: (Parameters)
# 468| 0: [Parameter] value
# 469| 4: [BlockStmt] {...}
# 470| 0: [ExprStmt] ...;
# 470| 0: [AssignExpr] ... = ...
# 470| 0: [ParameterAccess] access to parameter value
# 470| 1: [FieldAccess] access to field value
# 470| -1: [ThisAccess] this access
# 473| 6: [AddOperator] +
# 480| 0: [Parameter] value
# 481| 4: [BlockStmt] {...}
# 482| 0: [ExprStmt] ...;
# 482| 0: [AssignExpr] ... = ...
# 482| 0: [ParameterAccess] access to parameter value
# 482| 1: [FieldAccess] access to field value
# 482| -1: [ThisAccess] this access
# 485| 6: [AddOperator] +
#-----| 2: (Parameters)
# 473| 0: [Parameter] c1
# 473| 1: [Parameter] c2
# 474| 4: [BlockStmt] {...}
# 475| 0: [ReturnStmt] return ...;
# 475| 0: [ObjectCreation] object creation of type Num
# 475| 0: [AddExpr] ... + ...
# 475| 0: [FieldAccess] access to field value
# 475| -1: [ParameterAccess] access to parameter c1
# 475| 1: [FieldAccess] access to field value
# 475| -1: [ParameterAccess] access to parameter c2
# 479| 8: [DelegateType] MyDelegate
# 485| 0: [Parameter] c1
# 485| 1: [Parameter] c2
# 486| 4: [BlockStmt] {...}
# 487| 0: [ReturnStmt] return ...;
# 487| 0: [ObjectCreation] object creation of type Num
# 487| 0: [AddExpr] ... + ...
# 487| 0: [FieldAccess] access to field value
# 487| -1: [ParameterAccess] access to parameter c1
# 487| 1: [FieldAccess] access to field value
# 487| -1: [ParameterAccess] access to parameter c2
# 491| 8: [DelegateType] MyDelegate
#-----| 2: (Parameters)
# 479| 0: [Parameter] e
# 482| 19: [Class] ExpressionDepth
# 484| 5: [Field] d
# 484| 1: [AssignExpr] ... = ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [AddExpr] ... + ...
# 484| 0: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 484| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 485| 1: [IntLiteral] 1
# 484| 1: [MemberConstantAccess] access to constant d
# 488| 20: [Class] TupleExprs
# 490| 5: [Method] Test
# 491| 4: [BlockStmt] {...}
# 492| 0: [LocalVariableDeclStmt] ... ...;
# 492| 0: [LocalVariableDeclAndInitExpr] (Int32,String) a = ...
# 492| 0: [DefaultValueExpr] default(...)
# 492| 0: [TypeAccess] access to type (Int32,String)
# 492| 1: [LocalVariableAccess] access to local variable a
# 493| 1: [LocalVariableDeclStmt] ... ...;
# 493| 0: [LocalVariableDeclAndInitExpr] (Boolean,Int32[],Object) b = ...
# 493| 0: [DefaultValueExpr] default(...)
# 493| 0: [TypeAccess] access to type (Boolean,Int32[],Object)
# 493| 1: [LocalVariableAccess] access to local variable b
# 494| 2: [LocalVariableDeclStmt] ... ...;
# 494| 0: [LocalVariableDeclAndInitExpr] Type x = ...
# 494| 0: [TypeofExpr] typeof(...)
# 494| 0: [TypeAccess] access to type (Int32,String)
# 494| 1: [LocalVariableAccess] access to local variable x
# 495| 3: [LocalVariableDeclStmt] ... ...;
# 495| 0: [LocalVariableDeclAndInitExpr] Type y = ...
# 495| 0: [TypeofExpr] typeof(...)
# 495| 0: [TypeAccess] access to type (Boolean,Int32[],dynamic)
# 495| 1: [LocalVariableAccess] access to local variable y
# 491| 0: [Parameter] e
# 494| 19: [Class] ExpressionDepth
# 496| 5: [Field] d
# 496| 1: [AssignExpr] ... = ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [AddExpr] ... + ...
# 496| 0: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 496| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 497| 1: [IntLiteral] 1
# 496| 1: [MemberConstantAccess] access to constant d
# 500| 20: [Class] TupleExprs
# 502| 5: [Method] Test
# 503| 4: [BlockStmt] {...}
# 504| 0: [LocalVariableDeclStmt] ... ...;
# 504| 0: [LocalVariableDeclAndInitExpr] (Int32,String) a = ...
# 504| 0: [DefaultValueExpr] default(...)
# 504| 0: [TypeAccess] access to type (Int32,String)
# 504| 1: [LocalVariableAccess] access to local variable a
# 505| 1: [LocalVariableDeclStmt] ... ...;
# 505| 0: [LocalVariableDeclAndInitExpr] (Boolean,Int32[],Object) b = ...
# 505| 0: [DefaultValueExpr] default(...)
# 505| 0: [TypeAccess] access to type (Boolean,Int32[],Object)
# 505| 1: [LocalVariableAccess] access to local variable b
# 506| 2: [LocalVariableDeclStmt] ... ...;
# 506| 0: [LocalVariableDeclAndInitExpr] Type x = ...
# 506| 0: [TypeofExpr] typeof(...)
# 506| 0: [TypeAccess] access to type (Int32,String)
# 506| 1: [LocalVariableAccess] access to local variable x
# 507| 3: [LocalVariableDeclStmt] ... ...;
# 507| 0: [LocalVariableDeclAndInitExpr] Type y = ...
# 507| 0: [TypeofExpr] typeof(...)
# 507| 0: [TypeAccess] access to type (Boolean,Int32[],dynamic)
# 507| 1: [LocalVariableAccess] access to local variable y

View File

@@ -65,7 +65,7 @@
| expressions.cs:377:43:377:46 | access to field name | expressions.cs:377:43:377:46 | this access |
| expressions.cs:377:57:377:60 | access to field name | expressions.cs:377:57:377:60 | this access |
| expressions.cs:378:57:378:68 | access to field phoneNumbers | expressions.cs:378:57:378:68 | this access |
| expressions.cs:442:29:442:47 | call to method WriteLine | expressions.cs:442:29:442:35 | access to type Console |
| expressions.cs:470:17:470:26 | access to field value | expressions.cs:470:17:470:20 | this access |
| expressions.cs:475:32:475:39 | access to field value | expressions.cs:475:32:475:33 | access to parameter c1 |
| expressions.cs:475:43:475:50 | access to field value | expressions.cs:475:43:475:44 | access to parameter c2 |
| expressions.cs:454:29:454:47 | call to method WriteLine | expressions.cs:454:29:454:35 | access to type Console |
| expressions.cs:482:17:482:26 | access to field value | expressions.cs:482:17:482:20 | this access |
| expressions.cs:487:32:487:39 | access to field value | expressions.cs:487:32:487:33 | access to parameter c1 |
| expressions.cs:487:43:487:50 | access to field value | expressions.cs:487:43:487:44 | access to parameter c2 |

View File

@@ -50,7 +50,7 @@
| expressions.cs:334:30:334:30 | (...) ... | expressions.cs:334:30:334:30 | 8 |
| expressions.cs:414:31:414:31 | (...) ... | expressions.cs:414:31:414:31 | 1 |
| expressions.cs:414:39:414:39 | (...) ... | expressions.cs:414:39:414:39 | 2 |
| expressions.cs:437:41:437:53 | (...) ... | expressions.cs:437:48:437:52 | ... + ... |
| expressions.cs:437:48:437:48 | (...) ... | expressions.cs:437:48:437:48 | access to parameter x |
| expressions.cs:438:52:438:56 | (...) ... | expressions.cs:438:52:438:56 | ... + ... |
| expressions.cs:440:56:440:56 | (...) ... | expressions.cs:440:56:440:56 | access to parameter x |
| expressions.cs:449:41:449:53 | (...) ... | expressions.cs:449:48:449:52 | ... + ... |
| expressions.cs:449:48:449:48 | (...) ... | expressions.cs:449:48:449:48 | access to parameter x |
| expressions.cs:450:52:450:56 | (...) ... | expressions.cs:450:52:450:56 | ... + ... |
| expressions.cs:452:56:452:56 | (...) ... | expressions.cs:452:56:452:56 | access to parameter x |

View File

@@ -1,4 +1,4 @@
| expressions.cs:492:29:492:41 | access to type (Int32,String) | expressions.cs:492:29:492:41 | (Int32,String) |
| expressions.cs:493:29:493:49 | access to type (Boolean,Int32[],Object) | expressions.cs:493:29:493:49 | (Boolean,Int32[],Object) |
| expressions.cs:494:28:494:40 | access to type (Int32,String) | expressions.cs:492:29:492:41 | (Int32,String) |
| expressions.cs:495:28:495:49 | access to type (Boolean,Int32[],dynamic) | expressions.cs:495:28:495:49 | (Boolean,Int32[],dynamic) |
| expressions.cs:504:29:504:41 | access to type (Int32,String) | expressions.cs:504:29:504:41 | (Int32,String) |
| expressions.cs:505:29:505:49 | access to type (Boolean,Int32[],Object) | expressions.cs:505:29:505:49 | (Boolean,Int32[],Object) |
| expressions.cs:506:28:506:40 | access to type (Int32,String) | expressions.cs:504:29:504:41 | (Int32,String) |
| expressions.cs:507:28:507:49 | access to type (Boolean,Int32[],dynamic) | expressions.cs:507:28:507:49 | (Boolean,Int32[],dynamic) |

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