Merge branch 'main' into python-more-additional-taint-steps

This commit is contained in:
Rasmus Wriedt Larsen
2020-08-31 14:34:42 +02:00
182 changed files with 7288 additions and 1774 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:40:8:40:9 | copyableclass.cpp:34:22:34:27 | AST only |
| copyableclass.cpp:41:8:41:9 | copyableclass.cpp:35:24:35:29 | AST only |
| copyableclass.cpp:42:8:42:9 | copyableclass.cpp:34:22:34:27 | AST only |
@@ -91,6 +109,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 |
| structlikeclass.cpp:35:8:35:9 | structlikeclass.cpp:29:22:29:27 | AST only |
| structlikeclass.cpp:36:8:36:9 | structlikeclass.cpp:30:24:30:29 | AST only |
| structlikeclass.cpp:37:8:37:9 | structlikeclass.cpp:29:22:29:27 | AST only |
@@ -153,6 +173,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 |
@@ -173,3 +195,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 |
| format.cpp:157:7:157:22 | (int)... | format.cpp:147:12:147:25 | call to source |
| format.cpp:157:7:157:22 | access to array | format.cpp:147:12:147:25 | call to source |
| format.cpp:158:7:158:27 | ... + ... | format.cpp:148:16:148:30 | 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

@@ -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

@@ -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) |

View File

@@ -432,6 +432,18 @@ namespace Expressions
delegate int S(int x, int y);
delegate void Unit();
void MultiDimensionalArrayCreations()
{
object o = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 } };
o = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } };
o = new int[,][,]
{
{ new int[,] { {1,3}, {5,7} }, new int[,] { {0,2}, {4,6}, {8,10} }, new int[,] { {11,22}, {99,88}, {0,9} } },
{ new int[,] { {1,3}, {5,7} }, new int[,] { {0,2}, {4,6}, {8,10} }, new int[,] { {11,22}, {99,88}, {0,9} } }
};
o = new int[][,] { new int[,] { { 1, 2 } }, new int[,] { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } } };
}
void MainAnonymousFunctions()
{
Func<Int16, Byte> f1 = x => (byte)(x + 1); // Implicitly typed, expression body

View File

@@ -1,28 +0,0 @@
class Company {
private List<Customer> customers = ...;
public Customer[] getCustomerArray() {
// AVOID: Inefficient call to 'toArray' with zero-length argument
return customers.toArray(new Customer[0]);
}
}
class Company {
private List<Customer> customers = ...;
public Customer[] getCustomerArray() {
// GOOD: More efficient call to 'toArray' with argument that is big enough to store the list
return customers.toArray(new Customer[customers.size()]);
}
}
class Company {
private static final Customer[] NO_CUSTOMERS = new Customer[0];
private List<Customer> customers = ...;
public Customer[] getCustomerArray() {
// GOOD: Reuse same zero-length array on every invocation
return customers.toArray(NO_CUSTOMERS);
}
}

View File

@@ -1,61 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The <code>java.util.Collection</code> interface provides a <code>toArray</code>
method that can be used to convert a collection of objects into an array of a particular
type. This method takes an array as an argument, which is used for two purposes.
Firstly, it determines the type of the returned array. Secondly, if it is big enough to
hold all values in the collection, it is filled with those values and returned;
otherwise, a new array of sufficient size and the appropriate type is allocated and
filled.</p>
<p>It is common to pass a fresh zero-length array to <code>toArray</code>,
simply because it is easy to construct one. Unfortunately, this allocation is wasteful,
because the array clearly is not big enough to hold the elements of the collection. This can cause
considerable garbage collector churn, impacting performance.</p>
</overview>
<recommendation>
<p>There are at least two ways to address this issue.</p>
<p>The first is to always call <code>toArray</code> with a new array allocated with a
sufficient size to hold the contents of the collection. Usually, this involves calling
the collection's <code>size</code> method and allocating an array with that many
elements. While it may seem odd that adding a call to <code>size</code> improves performance, if you
do not pass a large enough array, the <code>toArray</code> method makes this call automatically.
Calling <code>size</code> explicitly and then calling <code>toArray</code> with a large enough array
avoids the possible creation of two arrays (one too small and consequently unused).</p>
<p>The second approach is to add a static field holding a constant zero-length array to the
enclosing class, and pass that field to <code>toArray</code>. In this case, <code>toArray</code>
will end up allocating a new array in (almost) every case, but because the same zero-length array
is reused every time, there is almost no overhead. (Note that if <code>toArray</code>
is invoked on an empty collection, it will return the passed-in array. If your code expects
a new array from every invocation of <code>toArray</code>, you should use the first method.)</p>
</recommendation>
<example>
<p>In the following example, the first version of class <code>Company</code> uses an inefficient
call to <code>toArray</code> by passing a zero-length array. The second and third version
illustrate the two ways of addressing this issue outlined above.</p>
<sample src="InefficientToArray.java" />
</example>
<references>
<li>
Java Platform, Standard Edition 6, API Specification:
<a href="http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html#toArray%28T[]%29">toArray</a>.
</li>
</references>
</qhelp>

View File

@@ -1,53 +0,0 @@
/**
* @name Inefficient toArray on zero-length argument
* @description Calling 'Collection.toArray' with a zero-length array argument is inefficient.
* @kind problem
* @problem.severity recommendation
* @precision low
* @id java/inefficient-to-array
* @deprecated
*/
import java
/*
* This method uses the toArray() method of a collection derived class, and passes in a
* zero-length prototype array argument.
*
* It is more efficient to use myCollection.toArray(new Foo[myCollection.size()]).
* If the array passed in is big enough to store all of the elements of the collection,
* then it is populated and returned directly. This avoids the need to create a
* second array (by reflection) to return as the result.
*
* The new array has to be created as the argument value. Values in both branches of
* a conditional has to be an empty array.
*/
predicate emptyArrayLiteral(Expr e) {
// ArrayCreationExpr with zero-length init expr
exists(ArrayCreationExpr arr | arr = e |
exists(arr.getInit()) and
not exists(arr.getInit().getAnInit())
)
or
// ArrayCreationExpr where 0th dimension is zero literal
e.(ArrayCreationExpr).getDimension(0).(IntegerLiteral).getIntValue() = 0
or
exists(ConditionalExpr cond | cond = e |
emptyArrayLiteral(cond.getTrueExpr()) and
emptyArrayLiteral(cond.getFalseExpr())
)
}
class EmptyArrayLiteral extends Expr {
EmptyArrayLiteral() { emptyArrayLiteral(this) }
}
from EmptyArrayLiteral l, MethodAccess ma, Method m, GenericInterface coll
where
coll.hasQualifiedName("java.util", "Collection") and
ma.getMethod() = m and
m.hasName("toArray") and
m.getDeclaringType().getASupertype*().getSourceDeclaration() = coll and
ma.getArgument(0) = l
select ma, "Collection.toArray(...) called with zero-length array argument."

View File

@@ -12,11 +12,10 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking2
import semmle.code.java.security.XSS
import DataFlow2::PathGraph
import DataFlow::PathGraph
class XSSConfig extends TaintTracking2::Configuration {
class XSSConfig extends TaintTracking::Configuration {
XSSConfig() { this = "XSSConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
@@ -28,7 +27,7 @@ class XSSConfig extends TaintTracking2::Configuration {
}
}
from DataFlow2::PathNode source, DataFlow2::PathNode sink, XSSConfig conf
from DataFlow::PathNode source, DataFlow::PathNode sink, XSSConfig conf
where conf.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.",
source.getNode(), "user-provided value"

View File

@@ -12,11 +12,10 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking2
import semmle.code.java.security.XSS
import DataFlow2::PathGraph
import DataFlow::PathGraph
class XSSLocalConfig extends TaintTracking2::Configuration {
class XSSLocalConfig extends TaintTracking::Configuration {
XSSLocalConfig() { this = "XSSLocalConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
@@ -24,7 +23,7 @@ class XSSLocalConfig extends TaintTracking2::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink }
}
from DataFlow2::PathNode source, DataFlow2::PathNode sink, XSSLocalConfig conf
from DataFlow::PathNode source, DataFlow::PathNode sink, XSSLocalConfig conf
where conf.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.",
source.getNode(), "user-provided value"

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