Merge branch 'main' into port-url-redirect-query

This commit is contained in:
Rasmus Wriedt Larsen
2021-02-02 13:37:34 +01:00
103 changed files with 9479 additions and 3505 deletions

View File

@@ -92,7 +92,9 @@ class Snscanf extends ScanfFunction {
this instanceof TopLevelFunction and
(
hasName("_snscanf") or // _snscanf(src, max_amount, format, args...)
hasName("_snwscanf") // _snwscanf(src, max_amount, format, args...)
hasName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
hasName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...)
hasName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...)
// note that the max_amount is not a limit on the output length, it's an input length
// limit used with non null-terminated strings.
)
@@ -101,6 +103,12 @@ class Snscanf extends ScanfFunction {
override int getInputParameterIndex() { result = 0 }
override int getFormatParameterIndex() { result = 2 }
/**
* Gets the position at which the maximum number of characters in the
* input string is specified.
*/
int getInputLengthParameterIndex() { result = 1 }
}
/**

View File

@@ -25,3 +25,4 @@ private import implementations.StdString
private import implementations.Swap
private import implementations.GetDelim
private import implementations.SmartPointer
private import implementations.Sscanf

View File

@@ -24,7 +24,8 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
or
// bcopy(src, dest, num)
// mempcpy(dest, src, num)
this.hasGlobalName(["bcopy", mempcpy(), "__builtin___memcpy_chk"])
// memccpy(dest, src, c, n)
this.hasGlobalName(["bcopy", mempcpy(), "memccpy", "__builtin___memcpy_chk"])
}
/**
@@ -41,7 +42,7 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
/**
* Gets the index of the parameter that is the size of the copy (in bytes).
*/
int getParamSize() { result = 2 }
int getParamSize() { if this.hasGlobalName("memccpy") then result = 3 else result = 2 }
override predicate hasArrayInput(int bufParam) { bufParam = getParamSrc() }
@@ -71,7 +72,10 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = getParamDest() and buffer = true and mustWrite = true
i = getParamDest() and
buffer = true and
// memccpy only writes until a given character `c` is found
(if this.hasGlobalName("memccpy") then mustWrite = false else mustWrite = true)
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
@@ -97,7 +101,7 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
}
override predicate parameterIsAlwaysReturned(int index) {
not this.hasGlobalName(["bcopy", mempcpy()]) and
not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and
index = getParamDest()
}
}

View File

@@ -15,8 +15,9 @@ import semmle.code.cpp.models.interfaces.SideEffect
private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction {
MemsetFunction() {
hasGlobalName(["memset", "wmemset", "bzero", "__builtin_memset", "__builtin_memset_chk"]) or
hasQualifiedName("std", ["memset", "wmemset"])
this.hasGlobalOrStdName(["memset", "wmemset"])
or
this.hasGlobalName([bzero(), "__builtin_memset", "__builtin_memset_chk"])
}
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
@@ -28,17 +29,17 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
bufParam = 0 and
(if hasGlobalName("bzero") then countParam = 1 else countParam = 2)
(if hasGlobalName(bzero()) then countParam = 1 else countParam = 2)
}
override predicate parameterNeverEscapes(int index) { hasGlobalName("bzero") and index = 0 }
override predicate parameterNeverEscapes(int index) { hasGlobalName(bzero()) and index = 0 }
override predicate parameterEscapesOnlyViaReturn(int index) {
not hasGlobalName("bzero") and index = 0
not hasGlobalName(bzero()) and index = 0
}
override predicate parameterIsAlwaysReturned(int index) {
not hasGlobalName("bzero") and index = 0
not hasGlobalName(bzero()) and index = 0
}
override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -51,6 +52,8 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
i = 0 and
if hasGlobalName("bzero") then result = 1 else result = 2
if hasGlobalName(bzero()) then result = 1 else result = 2
}
}
private string bzero() { result = ["bzero", "explicit_bzero"] }

View File

@@ -8,9 +8,8 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
SideEffectFunction {
PureStrFunction() {
hasGlobalOrStdName([
"atof", "atoi", "atol", "atoll", "strcasestr", "strchnul", "strchr", "strchrnul", "strstr",
"strpbrk", "strcmp", "strcspn", "strncmp", "strrchr", "strspn", "strtod", "strtof",
"strtol", "strtoll", "strtoq", "strtoul"
atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr",
"strspn", strtol(), strrev(), strcmp(), strlwr(), strupr()
])
}
@@ -24,11 +23,16 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i |
input.isParameter(i) and
exists(getParameter(i))
or
input.isParameterDeref(i) and
getParameter(i).getUnspecifiedType() instanceof PointerType
(
input.isParameter(i) and
exists(getParameter(i))
or
input.isParameterDeref(i) and
getParameter(i).getUnspecifiedType() instanceof PointerType
) and
// Functions that end with _l also take a locale argument (always as the last argument),
// and we don't want taint from those arguments.
(not this.getName().matches("%\\_l") or exists(getParameter(i + 1)))
) and
(
output.isReturnValueDeref() and
@@ -60,6 +64,31 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
}
}
private string atoi() { result = ["atof", "atoi", "atol", "atoll"] }
private string strtol() { result = ["strtod", "strtof", "strtol", "strtoll", "strtoq", "strtoul"] }
private string strlwr() {
result = ["_strlwr", "_wcslwr", "_mbslwr", "_strlwr_l", "_wcslwr_l", "_mbslwr_l"]
}
private string strupr() {
result = ["_strupr", "_wcsupr", "_mbsupr", "_strupr_l", "_wcsupr_l", "_mbsupr_l"]
}
private string strrev() { result = ["_strrev", "_wcsrev", "_mbsrev", "_mbsrev_l"] }
private string strcmp() {
// NOTE: `strcoll` doesn't satisfy _all_ the definitions of purity: its behavior depends on
// `LC_COLLATE` (which is set by `setlocale`). Not sure this behavior worth including in the model, so
// for now we interpret the function as being pure.
result =
[
"strcmp", "strcspn", "strncmp", "strcoll", "strverscmp", "_mbsnbcmp", "_mbsnbcmp_l",
"_stricmp"
]
}
/** String standard `strlen` function, and related functions for computing string lengths. */
private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction {
StrLenFunction() {
@@ -114,7 +143,12 @@ private class PureFunction extends TaintFunction, SideEffectFunction {
/** Pure raw-memory functions. */
private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction {
PureMemFunction() { hasGlobalOrStdName(["memchr", "memrchr", "rawmemchr", "memcmp", "memmem"]) }
PureMemFunction() {
hasGlobalOrStdName([
"memchr", "__builtin_memchr", "memrchr", "rawmemchr", "memcmp", "__builtin_memcmp", "memmem"
]) or
this.hasGlobalName("memfrob")
}
override predicate hasArrayInput(int bufParam) {
getParameter(bufParam).getUnspecifiedType() instanceof PointerType
@@ -122,11 +156,15 @@ private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunctio
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i |
input.isParameter(i) and
exists(getParameter(i))
or
input.isParameterDeref(i) and
getParameter(i).getUnspecifiedType() instanceof PointerType
(
input.isParameter(i) and
exists(getParameter(i))
or
input.isParameterDeref(i) and
getParameter(i).getUnspecifiedType() instanceof PointerType
) and
// `memfrob` should not have taint from the size argument.
(not this.hasGlobalName("memfrob") or i = 0)
) and
(
output.isReturnValueDeref() and

View File

@@ -0,0 +1,72 @@
/**
* Provides implementation classes modeling `sscanf`, `fscanf` and various similar
* functions. See `semmle.code.cpp.models.Models` for usage information.
*/
import semmle.code.cpp.Function
import semmle.code.cpp.commons.Scanf
import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
/**
* The standard function `sscanf`, `fscanf` and its assorted variants
*/
private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, SideEffectFunction {
SscanfModel() { this instanceof Sscanf or this instanceof Fscanf or this instanceof Snscanf }
override predicate hasArrayWithNullTerminator(int bufParam) {
bufParam = this.(ScanfFunction).getFormatParameterIndex()
or
not this instanceof Fscanf and
bufParam = this.(ScanfFunction).getInputParameterIndex()
}
override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) }
private int getLengthParameterIndex() { result = this.(Snscanf).getInputLengthParameterIndex() }
private int getLocaleParameterIndex() {
this.getName().matches("%\\_l") and
(
if exists(getLengthParameterIndex())
then result = getLengthParameterIndex() + 2
else result = 2
)
}
private int getArgsStartPosition() { result = this.getNumberOfParameters() }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and
output.isParameterDeref(any(int i | i >= getArgsStartPosition()))
}
override predicate parameterNeverEscapes(int index) {
index = [0 .. max(getACallToThisFunction().getNumberOfArguments())]
}
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i >= getArgsStartPosition() and
buffer = true and
mustWrite = true
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
buffer = true and
i =
[
this.(ScanfFunction).getInputParameterIndex(),
this.(ScanfFunction).getFormatParameterIndex(), getLocaleParameterIndex()
]
}
}

View File

@@ -13,16 +13,20 @@ import semmle.code.cpp.models.interfaces.SideEffect
*/
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction {
StrcatFunction() {
getName() =
[
this.hasGlobalOrStdName([
"strcat", // strcat(dst, src)
"strncat", // strncat(dst, src, max_amount)
"wcscat", // wcscat(dst, src)
"wcsncat" // wcsncat(dst, src, max_amount)
])
or
this.hasGlobalName([
"_mbscat", // _mbscat(dst, src)
"wcsncat", // wcsncat(dst, src, max_amount)
"_mbsncat", // _mbsncat(dst, src, max_amount)
"_mbsncat_l" // _mbsncat_l(dst, src, max_amount, locale)
]
"_mbsncat_l", // _mbsncat_l(dst, src, max_amount, locale)
"_mbsnbcat", // _mbsnbcat(dest, src, count)
"_mbsnbcat_l" // _mbsnbcat_l(dest, src, count, locale)
])
}
/**
@@ -50,7 +54,7 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
input.isParameter(2) and
output.isParameterDeref(0)
or
getName() = "_mbsncat_l" and
getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
input.isParameter(3) and
output.isParameterDeref(0)
or

View File

@@ -13,25 +13,36 @@ import semmle.code.cpp.models.interfaces.SideEffect
*/
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction {
StrcpyFunction() {
getName() =
[
this.hasGlobalOrStdName([
"strcpy", // strcpy(dst, src)
"wcscpy", // wcscpy(dst, src)
"_mbscpy", // _mbscpy(dst, src)
"strncpy", // strncpy(dst, src, max_amount)
"_strncpy_l", // _strncpy_l(dst, src, max_amount, locale)
"wcsncpy", // wcsncpy(dst, src, max_amount)
"strxfrm", // strxfrm(dest, src, max_amount)
"wcsxfrm" // wcsxfrm(dest, src, max_amount)
])
or
this.hasGlobalName([
"_mbscpy", // _mbscpy(dst, src)
"_strncpy_l", // _strncpy_l(dst, src, max_amount, locale)
"_wcsncpy_l", // _wcsncpy_l(dst, src, max_amount, locale)
"_mbsncpy", // _mbsncpy(dst, src, max_amount)
"_mbsncpy_l"
] // _mbsncpy_l(dst, src, max_amount, locale)
"_mbsncpy_l", // _mbsncpy_l(dst, src, max_amount, locale)
"_strxfrm_l", // _strxfrm_l(dest, src, max_amount, locale)
"wcsxfrm_l", // _strxfrm_l(dest, src, max_amount, locale)
"_mbsnbcpy", // _mbsnbcpy(dest, src, max_amount)
"stpcpy", // stpcpy(dest, src)
"stpncpy" // stpcpy(dest, src, max_amount)
])
or
getName() =
[
"strcpy_s", // strcpy_s(dst, max_amount, src)
"wcscpy_s", // wcscpy_s(dst, max_amount, src)
"_mbscpy_s"
] and // _mbscpy_s(dst, max_amount, src)
(
this.hasGlobalOrStdName([
"strcpy_s", // strcpy_s(dst, max_amount, src)
"wcscpy_s" // wcscpy_s(dst, max_amount, src)
])
or
this.hasGlobalName("_mbscpy_s") // _mbscpy_s(dst, max_amount, src)
) and
// exclude the 2-parameter template versions
// that find the size of a fixed size destination buffer.
getNumberOfParameters() = 3
@@ -48,10 +59,10 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
int getParamSize() {
if isSVariant()
then result = 1
else
if exists(getName().indexOf("ncpy"))
then result = 2
else none()
else (
getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and
result = 2
)
}
/**

View File

@@ -47,3 +47,42 @@ private class Strtok extends ArrayFunction, AliasFunction, TaintFunction, SideEf
i = [0, 1] and buffer = true
}
}
/**
* The function `strtok` is a variant of `strtok` that takes a `char**` parameter instead of
* a `char*` as the first parameter.
*/
private class Strsep extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction {
Strsep() { this.hasGlobalName("strsep") }
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 1 }
override predicate hasArrayInput(int bufParam) { bufParam = 1 }
override predicate parameterNeverEscapes(int index) { index = [0, 1] }
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate parameterIsAlwaysReturned(int index) { none() }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// NOTE: What we really want here is: (input.isParameterDerefDeref(0) or input.isParameterDeref(1))
// as the first conjunct.
input.isParameterDeref([0, 1]) and
(output.isReturnValue() or output.isReturnValueDeref())
}
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = 0 and buffer = false and mustWrite = false
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
i = 0 and buffer = false
or
i = 1 and buffer = true
}
}

View File

@@ -123,7 +123,7 @@ void test1()
{
int i = 0;
sink(sscanf(string::source(), "%i", &i));
sink(i); // $ MISSING: ast,ir
sink(i); // $ ast,ir
}
{
char buffer[256] = {0};
@@ -133,7 +133,7 @@ void test1()
{
char buffer[256] = {0};
sink(sscanf(string::source(), "%s", &buffer));
sink(buffer); // $ MISSING: ast,ir
sink(buffer); // $ ast,ir
}
}

View File

@@ -378,23 +378,27 @@
| format.cpp:114:37:114:50 | call to source | format.cpp:114:18:114:23 | ref arg buffer | TAINT |
| format.cpp:119:10:119:11 | 0 | format.cpp:120:29:120:29 | i | |
| format.cpp:119:10:119:11 | 0 | format.cpp:121:8:121:8 | i | |
| format.cpp:120:15:120:19 | 123 | format.cpp:120:28:120:29 | ref arg & ... | TAINT |
| format.cpp:120:28:120:29 | ref arg & ... | format.cpp:120:29:120:29 | i [inner post update] | |
| format.cpp:120:28:120:29 | ref arg & ... | format.cpp:121:8:121:8 | i | |
| format.cpp:120:29:120:29 | i | format.cpp:120:28:120:29 | & ... | |
| format.cpp:124:10:124:11 | 0 | format.cpp:125:40:125:40 | i | |
| format.cpp:124:10:124:11 | 0 | format.cpp:126:8:126:8 | i | |
| format.cpp:125:15:125:28 | call to source | format.cpp:125:39:125:40 | ref arg & ... | TAINT |
| format.cpp:125:39:125:40 | ref arg & ... | format.cpp:125:40:125:40 | i [inner post update] | |
| format.cpp:125:39:125:40 | ref arg & ... | format.cpp:126:8:126:8 | i | |
| format.cpp:125:40:125:40 | i | format.cpp:125:39:125:40 | & ... | |
| format.cpp:129:21:129:24 | {...} | format.cpp:130:32:130:37 | buffer | |
| format.cpp:129:21:129:24 | {...} | format.cpp:131:8:131:13 | buffer | |
| format.cpp:129:23:129:23 | 0 | format.cpp:129:21:129:24 | {...} | TAINT |
| format.cpp:130:15:130:22 | Hello. | format.cpp:130:31:130:37 | ref arg & ... | TAINT |
| format.cpp:130:31:130:37 | ref arg & ... | format.cpp:130:32:130:37 | buffer [inner post update] | |
| format.cpp:130:31:130:37 | ref arg & ... | format.cpp:131:8:131:13 | buffer | |
| format.cpp:130:32:130:37 | buffer | format.cpp:130:31:130:37 | & ... | |
| format.cpp:134:21:134:24 | {...} | format.cpp:135:40:135:45 | buffer | |
| format.cpp:134:21:134:24 | {...} | format.cpp:136:8:136:13 | buffer | |
| format.cpp:134:23:134:23 | 0 | format.cpp:134:21:134:24 | {...} | TAINT |
| format.cpp:135:15:135:28 | call to source | format.cpp:135:39:135:45 | ref arg & ... | TAINT |
| format.cpp:135:39:135:45 | ref arg & ... | format.cpp:135:40:135:45 | buffer [inner post update] | |
| format.cpp:135:39:135:45 | ref arg & ... | format.cpp:136:8:136:13 | buffer | |
| format.cpp:135:40:135:45 | buffer | format.cpp:135:39:135:45 | & ... | |
@@ -5883,6 +5887,89 @@
| taint.cpp:510:10:510:15 | source | taint.cpp:510:2:510:8 | call to _strset | |
| taint.cpp:510:18:510:18 | 0 | taint.cpp:510:2:510:8 | call to _strset | TAINT |
| taint.cpp:510:18:510:18 | 0 | taint.cpp:510:10:510:15 | ref arg source | |
| taint.cpp:518:24:518:29 | source | taint.cpp:520:14:520:19 | source | |
| taint.cpp:519:6:519:6 | x | taint.cpp:520:11:520:11 | x | |
| taint.cpp:519:6:519:6 | x | taint.cpp:521:7:521:7 | x | |
| taint.cpp:520:10:520:11 | & ... | taint.cpp:520:2:520:8 | call to mempcpy | |
| taint.cpp:520:10:520:11 | ref arg & ... | taint.cpp:520:11:520:11 | x [inner post update] | |
| taint.cpp:520:10:520:11 | ref arg & ... | taint.cpp:521:7:521:7 | x | |
| taint.cpp:520:11:520:11 | x | taint.cpp:520:10:520:11 | & ... | |
| taint.cpp:520:14:520:19 | source | taint.cpp:520:2:520:8 | call to mempcpy | TAINT |
| taint.cpp:520:14:520:19 | source | taint.cpp:520:10:520:11 | ref arg & ... | TAINT |
| taint.cpp:528:24:528:29 | source | taint.cpp:530:16:530:21 | source | |
| taint.cpp:529:6:529:9 | dest | taint.cpp:530:10:530:13 | dest | |
| taint.cpp:529:6:529:9 | dest | taint.cpp:530:35:530:38 | dest | |
| taint.cpp:529:6:529:9 | dest | taint.cpp:531:7:531:10 | dest | |
| taint.cpp:530:10:530:13 | dest | taint.cpp:530:2:530:8 | call to memccpy | |
| taint.cpp:530:10:530:13 | ref arg dest | taint.cpp:531:7:531:10 | dest | |
| taint.cpp:530:16:530:21 | source | taint.cpp:530:2:530:8 | call to memccpy | TAINT |
| taint.cpp:530:16:530:21 | source | taint.cpp:530:10:530:13 | ref arg dest | TAINT |
| taint.cpp:538:24:538:28 | dest1 | taint.cpp:539:9:539:13 | dest1 | |
| taint.cpp:538:24:538:28 | dest1 | taint.cpp:540:7:540:11 | dest1 | |
| taint.cpp:538:37:538:41 | dest2 | taint.cpp:542:9:542:13 | dest2 | |
| taint.cpp:538:37:538:41 | dest2 | taint.cpp:543:7:543:11 | dest2 | |
| taint.cpp:538:50:538:54 | clean | taint.cpp:542:16:542:20 | clean | |
| taint.cpp:538:63:538:68 | source | taint.cpp:539:16:539:21 | source | |
| taint.cpp:539:9:539:13 | dest1 | taint.cpp:539:2:539:7 | call to strcat | |
| taint.cpp:539:9:539:13 | dest1 | taint.cpp:539:9:539:13 | ref arg dest1 | TAINT |
| taint.cpp:539:9:539:13 | ref arg dest1 | taint.cpp:540:7:540:11 | dest1 | |
| taint.cpp:539:16:539:21 | source | taint.cpp:539:9:539:13 | ref arg dest1 | TAINT |
| taint.cpp:542:9:542:13 | dest2 | taint.cpp:542:2:542:7 | call to strcat | |
| taint.cpp:542:9:542:13 | dest2 | taint.cpp:542:9:542:13 | ref arg dest2 | TAINT |
| taint.cpp:542:9:542:13 | ref arg dest2 | taint.cpp:543:7:543:11 | dest2 | |
| taint.cpp:542:16:542:20 | clean | taint.cpp:542:9:542:13 | ref arg dest2 | TAINT |
| taint.cpp:550:37:550:41 | dest1 | taint.cpp:552:36:552:40 | dest1 | |
| taint.cpp:550:37:550:41 | dest1 | taint.cpp:553:7:553:11 | dest1 | |
| taint.cpp:550:37:550:41 | dest1 | taint.cpp:554:8:554:12 | dest1 | |
| taint.cpp:550:65:550:67 | ptr | taint.cpp:552:43:552:45 | ptr | |
| taint.cpp:550:65:550:67 | ptr | taint.cpp:558:43:558:45 | ptr | |
| taint.cpp:550:85:550:89 | dest3 | taint.cpp:558:36:558:40 | dest3 | |
| taint.cpp:550:85:550:89 | dest3 | taint.cpp:559:7:559:11 | dest3 | |
| taint.cpp:550:85:550:89 | dest3 | taint.cpp:560:8:560:12 | dest3 | |
| taint.cpp:551:32:551:36 | clean | taint.cpp:558:51:558:55 | clean | |
| taint.cpp:551:49:551:54 | source | taint.cpp:552:51:552:56 | source | |
| taint.cpp:551:61:551:61 | n | taint.cpp:552:48:552:48 | n | |
| taint.cpp:551:61:551:61 | n | taint.cpp:558:48:558:48 | n | |
| taint.cpp:552:25:552:34 | call to _mbsncat_l | taint.cpp:555:7:555:11 | dest2 | |
| taint.cpp:552:25:552:34 | call to _mbsncat_l | taint.cpp:556:8:556:12 | dest2 | |
| taint.cpp:552:36:552:40 | dest1 | taint.cpp:552:25:552:34 | call to _mbsncat_l | |
| taint.cpp:552:36:552:40 | dest1 | taint.cpp:552:36:552:40 | ref arg dest1 | TAINT |
| taint.cpp:552:36:552:40 | ref arg dest1 | taint.cpp:553:7:553:11 | dest1 | |
| taint.cpp:552:36:552:40 | ref arg dest1 | taint.cpp:554:8:554:12 | dest1 | |
| taint.cpp:552:43:552:45 | ptr | taint.cpp:552:36:552:40 | ref arg dest1 | TAINT |
| taint.cpp:552:48:552:48 | n | taint.cpp:552:36:552:40 | ref arg dest1 | TAINT |
| taint.cpp:552:51:552:56 | source | taint.cpp:552:36:552:40 | ref arg dest1 | TAINT |
| taint.cpp:553:7:553:11 | ref arg dest1 | taint.cpp:554:8:554:12 | dest1 | |
| taint.cpp:554:8:554:12 | dest1 | taint.cpp:554:7:554:12 | * ... | TAINT |
| taint.cpp:555:7:555:11 | ref arg dest2 | taint.cpp:556:8:556:12 | dest2 | |
| taint.cpp:556:8:556:12 | dest2 | taint.cpp:556:7:556:12 | * ... | TAINT |
| taint.cpp:558:25:558:34 | call to _mbsncat_l | taint.cpp:561:7:561:11 | dest4 | |
| taint.cpp:558:25:558:34 | call to _mbsncat_l | taint.cpp:562:8:562:12 | dest4 | |
| taint.cpp:558:36:558:40 | dest3 | taint.cpp:558:25:558:34 | call to _mbsncat_l | |
| taint.cpp:558:36:558:40 | dest3 | taint.cpp:558:36:558:40 | ref arg dest3 | TAINT |
| taint.cpp:558:36:558:40 | ref arg dest3 | taint.cpp:559:7:559:11 | dest3 | |
| taint.cpp:558:36:558:40 | ref arg dest3 | taint.cpp:560:8:560:12 | dest3 | |
| taint.cpp:558:43:558:45 | ptr | taint.cpp:558:36:558:40 | ref arg dest3 | TAINT |
| taint.cpp:558:48:558:48 | n | taint.cpp:558:36:558:40 | ref arg dest3 | TAINT |
| taint.cpp:558:51:558:55 | clean | taint.cpp:558:36:558:40 | ref arg dest3 | TAINT |
| taint.cpp:559:7:559:11 | ref arg dest3 | taint.cpp:560:8:560:12 | dest3 | |
| taint.cpp:560:8:560:12 | dest3 | taint.cpp:560:7:560:12 | * ... | TAINT |
| taint.cpp:561:7:561:11 | ref arg dest4 | taint.cpp:562:8:562:12 | dest4 | |
| taint.cpp:562:8:562:12 | dest4 | taint.cpp:562:7:562:12 | * ... | TAINT |
| taint.cpp:569:24:569:29 | source | taint.cpp:572:29:572:34 | source | |
| taint.cpp:570:23:570:30 | ,.-;:_ | taint.cpp:572:37:572:41 | delim | |
| taint.cpp:572:9:572:17 | tokenized | taint.cpp:572:9:572:42 | ... = ... | |
| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:572:9:572:42 | ... = ... | |
| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:573:10:573:18 | tokenized | |
| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:574:11:574:19 | tokenized | |
| taint.cpp:572:28:572:34 | & ... | taint.cpp:572:21:572:26 | call to strsep | TAINT |
| taint.cpp:572:28:572:34 | ref arg & ... | taint.cpp:572:29:572:34 | source | |
| taint.cpp:572:28:572:34 | ref arg & ... | taint.cpp:572:29:572:34 | source [inner post update] | |
| taint.cpp:572:29:572:34 | source | taint.cpp:572:21:572:26 | call to strsep | TAINT |
| taint.cpp:572:29:572:34 | source | taint.cpp:572:28:572:34 | & ... | |
| taint.cpp:572:37:572:41 | delim | taint.cpp:572:21:572:26 | call to strsep | TAINT |
| taint.cpp:573:10:573:18 | ref arg tokenized | taint.cpp:574:11:574:19 | tokenized | |
| taint.cpp:574:11:574:19 | tokenized | taint.cpp:574:10:574:19 | * ... | TAINT |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |

View File

@@ -509,4 +509,68 @@ void test_strset_1(char* ptr, char source) {
void test_strset_2(char* source) {
_strset(source, 0);
sink(source); // $ ast,ir
}
}
// --- mempcpy ---
void *mempcpy(void *dest, const void *src, size_t n);
void test_mempcpy(int *source) {
int x;
mempcpy(&x, source, sizeof(int));
sink(x); // $ ast=518:24 MISSING: ir SPURIOUS: ast=519:6
}
// --- memccpy ---
void *memccpy(void *dest, const void *src, int c, size_t n);
void test_memccpy(int *source) {
int dest[16];
memccpy(dest, source, 42, sizeof(dest));
sink(dest); // $ ast=528:24 MISSING: ir SPURIOUS: ast=529:6
}
// --- strcat and related functions ---
char* strcat (char*, const char*);
void test_strcat(char* dest1, char* dest2, char* clean, char* source) {
strcat(dest1, source);
sink(dest1); // $ ast,ir
strcat(dest2, clean);
sink(dest2);
}
typedef void* _locale_t;
unsigned char *_mbsncat_l(unsigned char *, const unsigned char *, int, _locale_t);
void test__mbsncat_l(unsigned char* dest1, unsigned const char* ptr, unsigned char* dest3,
_locale_t clean, _locale_t source, int n) {
unsigned char* dest2 = _mbsncat_l(dest1, ptr, n, source);
sink(dest1); // $ SPURIOUS: ast,ir
sink(*dest1); // $ ast,ir
sink(dest2); // $ SPURIOUS: ir
sink(*dest2); // $ ir
unsigned char* dest4 = _mbsncat_l(dest3, ptr, n, clean);
sink(dest3);
sink(*dest3);
sink(dest4);
sink(*dest4);
}
// --- strsep ---
char *strsep(char**, const char *);
void test_strsep(char *source) {
const char* delim = ",.-;:_";
char* tokenized;
while(tokenized = strsep(&source, delim)) {
sink(tokenized); // $ ast,ir
sink(*tokenized); // $ ast,ir
}
}

View File

@@ -0,0 +1,3 @@
lgtm,codescanning
* The `BinaryPatternExpr` class has been added to support C# 9 `and` and `or`
patterns.

View File

@@ -0,0 +1,28 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Entities;
using Semmle.Extraction.Kinds;
namespace Semmle.Extraction.CSharp.Entities.Expressions
{
internal class BinaryPattern : Expression
{
public BinaryPattern(Context cx, BinaryPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.Create(syntax.GetLocation()), GetKind(syntax.OperatorToken, syntax), parent, child, false, null))
{
Pattern.Create(cx, syntax.Left, this, 0);
Pattern.Create(cx, syntax.Right, this, 1);
}
private static ExprKind GetKind(SyntaxToken operatorToken, BinaryPatternSyntax syntax)
{
return operatorToken.Kind() switch
{
SyntaxKind.AndKeyword => ExprKind.AND_PATTERN,
SyntaxKind.OrKeyword => ExprKind.OR_PATTERN,
_ => throw new InternalError(syntax, $"Operator '{operatorToken.Kind()}' is not supported in binary patterns.")
};
}
}
}

View File

@@ -23,6 +23,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
case UnaryPatternSyntax unaryPattern:
return new UnaryPattern(cx, unaryPattern, parent, child);
case BinaryPatternSyntax binaryPattern:
return new BinaryPattern(cx, binaryPattern, parent, child);
case DeclarationPatternSyntax declPattern:
// Creates a single local variable declaration.
{

View File

@@ -121,6 +121,8 @@ namespace Semmle.Extraction.Kinds
LE_PATTERN = 124,
GE_PATTERN = 125,
NOT_PATTERN = 126,
AND_PATTERN = 127,
OR_PATTERN = 128,
FUNCTION_POINTER_INVOCATION = 129,
}
}

View File

@@ -566,6 +566,4 @@ class IndexerProperty extends Property {
// ```
result.getIndexer() = i
}
override string getAPrimaryQlClass() { result = "IndexerProperty" }
}

View File

@@ -551,7 +551,17 @@ private predicate mustHaveMatchingCompletion(Expr e, PatternExpr pe) {
or
pe = any(IsExpr ie | inBooleanContext(ie) and e = ie.getExpr()).getPattern()
or
pe = any(RecursivePatternExpr rpe | mustHaveMatchingCompletion(e, rpe)).getPositionalPatterns()
or
pe = any(RecursivePatternExpr rpe | mustHaveMatchingCompletion(e, rpe)).getPropertyPatterns()
or
pe = any(PositionalPatternExpr ppe | mustHaveMatchingCompletion(e, ppe)).getPattern(_)
or
pe = any(PropertyPatternExpr ppe | mustHaveMatchingCompletion(e, ppe)).getPattern(_)
or
pe = any(UnaryPatternExpr upe | mustHaveMatchingCompletion(e, upe)).getPattern()
or
pe = any(BinaryPatternExpr bpe | mustHaveMatchingCompletion(e, bpe)).getAnOperand()
}
/**

View File

@@ -51,12 +51,21 @@ private import Splitting
private import semmle.code.csharp.ExprOrStmtParent
/** An element that defines a new CFG scope. */
class CfgScope extends Element, @top_level_exprorstmt_parent { }
class CfgScope extends Element, @top_level_exprorstmt_parent {
CfgScope() { not this instanceof Attribute }
}
module ControlFlowTree {
private class Range_ = @callable or @control_flow_element;
class Range extends Element, Range_ { }
class Range extends Element, Range_ {
Range() { this = getAChild*(any(CfgScope scope)) }
}
Element getAChild(Element p) {
result = p.getAChild() or
result = p.(AssignOperation).getExpandedAssignment()
}
private predicate id(Range x, Range y) { x = y }
@@ -360,7 +369,9 @@ module Expressions {
not this instanceof SwitchExpr and
not this instanceof SwitchCaseExpr and
not this instanceof ConstructorInitializer and
not this instanceof NotPatternExpr
not this instanceof NotPatternExpr and
not this instanceof OrPatternExpr and
not this instanceof AndPatternExpr
}
final override ControlFlowElement getChildElement(int i) { result = getExprChild(this, i) }
@@ -902,6 +913,56 @@ module Expressions {
c instanceof NormalCompletion
}
}
private class AndPatternExprTree extends PostOrderTree, AndPatternExpr {
final override predicate propagatesAbnormal(ControlFlowElement child) {
child = this.getAnOperand()
}
final override predicate first(ControlFlowElement first) { first(this.getLeftOperand(), first) }
final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
// Flow from last element of left operand to first element of right operand
last(this.getLeftOperand(), pred, c) and
c.(MatchingCompletion).getValue() = true and
first(this.getRightOperand(), succ)
or
// Post-order: flow from last element of left operand to element itself
last(this.getLeftOperand(), pred, c) and
c.(MatchingCompletion).getValue() = false and
succ = this
or
// Post-order: flow from last element of right operand to element itself
last(this.getRightOperand(), pred, c) and
c instanceof MatchingCompletion and
succ = this
}
}
private class OrPatternExprTree extends PostOrderTree, OrPatternExpr {
final override predicate propagatesAbnormal(ControlFlowElement child) {
child = this.getAnOperand()
}
final override predicate first(ControlFlowElement first) { first(this.getLeftOperand(), first) }
final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
// Flow from last element of left operand to first element of right operand
last(this.getLeftOperand(), pred, c) and
c.(MatchingCompletion).getValue() = false and
first(this.getRightOperand(), succ)
or
// Post-order: flow from last element of left operand to element itself
last(this.getLeftOperand(), pred, c) and
c.(MatchingCompletion).getValue() = true and
succ = this
or
// Post-order: flow from last element of right operand to element itself
last(this.getRightOperand(), pred, c) and
c instanceof MatchingCompletion and
succ = this
}
}
}
module Statements {
@@ -1273,7 +1334,7 @@ module Statements {
/** Gets a child of `cfe` that is in CFG scope `scope`. */
pragma[noinline]
private ControlFlowElement getAChildInScope(ControlFlowElement cfe, Callable scope) {
result = [cfe.getAChild(), cfe.(AssignOperation).getExpandedAssignment()] and
result = ControlFlowTree::getAChild(cfe) and
scope = result.getEnclosingCallable()
}

View File

@@ -471,6 +471,12 @@ module ConditionalCompletionSplitting {
or
last(succ.(IsExpr).getPattern(), pred, c) and
completion.(BooleanCompletion).getValue() = c.(MatchingCompletion).getValue()
or
last(succ.(AndPatternExpr).getAnOperand(), pred, c) and
completion = c
or
last(succ.(OrPatternExpr).getAnOperand(), pred, c) and
completion = c
)
}
@@ -1535,11 +1541,7 @@ predicate succEntrySplits(CfgScope pred, ControlFlowElement succ, Splits succSpl
exists(int rnk |
scopeFirst(pred, succ) and
t instanceof NormalSuccessor and
succEntrySplitsFromRank(pred, succ, succSplits, rnk) and
// Attribute arguments in assemblies are represented as expressions, even though
// they are not from source. We are not interested in constructing a CFG for such
// expressions.
succ.fromSource()
succEntrySplitsFromRank(pred, succ, succSplits, rnk)
|
rnk = 0 and
not any(SplitImpl split).hasEntryScope(pred, succ)

View File

@@ -176,6 +176,16 @@ module Ssa {
exists(ControlFlow::BasicBlock bb, int i | this.definesAt(_, bb, i) | result = bb.getNode(i))
}
/**
* Holds is this SSA definition is live at the end of basic block `bb`.
* That is, this definition reaches the end of basic block `bb`, at which
* point it is still live, without crossing another SSA definition of the
* same source variable.
*/
final predicate isLiveAtEndOfBlock(ControlFlow::BasicBlock bb) {
SsaImpl::isLiveAtEndOfBlock(this, bb)
}
/**
* Gets a read of the source variable underlying this SSA definition that
* can be reached from this SSA definition without passing through any
@@ -233,12 +243,7 @@ module Ssa {
* node between lines 9 and 10.
*/
final AssignableRead getAReadAtNode(ControlFlow::Node cfn) {
exists(SourceVariable v, ControlFlow::BasicBlock bb, int i |
SsaImpl::ssaDefReachesRead(v, this, bb, i) and
SsaImpl::variableReadActual(bb, i, v) and
cfn = bb.getNode(i) and
result.getAControlFlowNode() = cfn
)
result = SsaImpl::getAReadAtNode(this, cfn)
}
/**

View File

@@ -8,7 +8,7 @@ import SsaImplCommon
/**
* Holds if the `i`th node of basic block `bb` reads source variable `v`.
*/
predicate variableReadActual(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v) {
private predicate variableReadActual(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v) {
v.getAnAccess().(AssignableRead) = bb.getNode(i).getElement()
}
@@ -1102,6 +1102,11 @@ private module Cached {
)
}
cached
predicate isLiveAtEndOfBlock(Definition def, ControlFlow::BasicBlock bb) {
ssaDefReachesEndOfBlock(bb, def, _)
}
private predicate adjacentDefReaches(
Definition def, ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2
) {
@@ -1122,6 +1127,16 @@ private module Cached {
variableReadActual(bb2, i2, _)
}
cached
AssignableRead getAReadAtNode(Definition def, ControlFlow::Node cfn) {
exists(Ssa::SourceVariable v, ControlFlow::BasicBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
variableReadActual(bb, i, v) and
cfn = bb.getNode(i) and
result.getAControlFlowNode() = cfn
)
}
/**
* Holds if the value defined at SSA definition `def` can reach a read at `cfn`,
* without passing through any other read.

View File

@@ -7,174 +7,174 @@ private import SsaImplSpecific
private BasicBlock getABasicBlockPredecessor(BasicBlock bb) { getABasicBlockSuccessor(result) = bb }
/**
* Liveness analysis (based on source variables) to restrict the size of the
* SSA representation.
*/
private module Liveness {
/**
* A classification of variable references into reads (of a given kind) and
* (certain or uncertain) writes.
*/
private newtype TRefKind =
Read() or
Write(boolean certain) { certain = true or certain = false }
private class RefKind extends TRefKind {
string toString() {
this = Read() and result = "read"
or
exists(boolean certain | this = Write(certain) and result = "write (" + certain + ")")
}
int getOrder() {
this = Read() and
result = 0
or
this = Write(_) and
result = 1
}
}
/**
* Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`.
*/
private predicate ref(BasicBlock bb, int i, SourceVariable v, RefKind k) {
variableRead(bb, i, v) and k = Read()
or
exists(boolean certain | variableWrite(bb, i, v, certain) | k = Write(certain))
}
private newtype OrderedRefIndex =
MkOrderedRefIndex(int i, int tag) {
exists(RefKind rk | ref(_, i, _, rk) | tag = rk.getOrder())
}
private OrderedRefIndex refOrd(BasicBlock bb, int i, SourceVariable v, RefKind k, int ord) {
ref(bb, i, v, k) and
result = MkOrderedRefIndex(i, ord) and
ord = k.getOrder()
}
/**
* Gets the (1-based) rank of the reference to `v` at the `i`th node of
* basic block `bb`, which has the given reference kind `k`.
*
* Reads are considered before writes when they happen at the same index.
*/
private int refRank(BasicBlock bb, int i, SourceVariable v, RefKind k) {
refOrd(bb, i, v, k, _) =
rank[result](int j, int ord, OrderedRefIndex res |
res = refOrd(bb, j, v, _, ord)
|
res order by j, ord
)
}
private int maxRefRank(BasicBlock bb, SourceVariable v) {
result = refRank(bb, _, v, _) and
not result + 1 = refRank(bb, _, v, _)
}
/**
* Gets the (1-based) rank of the first reference to `v` inside basic block `bb`
* that is either a read or a certain write.
*/
private int firstReadOrCertainWrite(BasicBlock bb, SourceVariable v) {
result =
min(int r, RefKind k |
r = refRank(bb, _, v, k) and
k != Write(false)
|
r
)
}
/**
* Holds if source variable `v` is live at the beginning of basic block `bb`.
*/
predicate liveAtEntry(BasicBlock bb, SourceVariable v) {
// The first read or certain write to `v` inside `bb` is a read
refRank(bb, _, v, Read()) = firstReadOrCertainWrite(bb, v)
or
// There is no certain write to `v` inside `bb`, but `v` is live at entry
// to a successor basic block of `bb`
not exists(firstReadOrCertainWrite(bb, v)) and
liveAtExit(bb, v)
}
/**
* Holds if source variable `v` is live at the end of basic block `bb`.
*/
predicate liveAtExit(BasicBlock bb, SourceVariable v) {
liveAtEntry(getABasicBlockSuccessor(bb), v)
}
/**
* Holds if variable `v` is live in basic block `bb` at index `i`.
* The rank of `i` is `rnk` as defined by `refRank()`.
*/
private predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk) {
exists(RefKind kind | rnk = refRank(bb, i, v, kind) |
rnk = maxRefRank(bb, v) and
liveAtExit(bb, v)
or
ref(bb, i, v, kind) and
kind = Read()
or
exists(RefKind nextKind |
liveAtRank(bb, _, v, rnk + 1) and
rnk + 1 = refRank(bb, _, v, nextKind) and
nextKind != Write(true)
)
)
}
/**
* Holds if variable `v` is live after the (certain or uncertain) write at
* index `i` inside basic block `bb`.
*/
predicate liveAfterWrite(BasicBlock bb, int i, SourceVariable v) {
exists(int rnk | rnk = refRank(bb, i, v, Write(_)) | liveAtRank(bb, i, v, rnk))
}
}
private import Liveness
/** Holds if `bb1` strictly dominates `bb2`. */
private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) {
bb1 = getImmediateBasicBlockDominator+(bb2)
}
/** Holds if `bb1` dominates a predecessor of `bb2`. */
private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) {
exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) |
bb1 = pred
or
strictlyDominates(bb1, pred)
)
}
/** Holds if `df` is in the dominance frontier of `bb`. */
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and
not strictlyDominates(bb, df)
}
/**
* Holds if `bb` is in the dominance frontier of a block containing a
* definition of `v`.
*/
pragma[noinline]
private predicate inDefDominanceFrontier(BasicBlock bb, SourceVariable v) {
exists(BasicBlock defbb, Definition def |
def.definesAt(v, defbb, _) and
inDominanceFrontier(defbb, bb)
)
}
cached
private module Cached {
/**
* Liveness analysis (based on source variables) to restrict the size of the
* SSA representation.
*/
private module Liveness {
/**
* A classification of variable references into reads (of a given kind) and
* (certain or uncertain) writes.
*/
private newtype TRefKind =
Read() or
Write(boolean certain) { certain = true or certain = false }
private class RefKind extends TRefKind {
string toString() {
this = Read() and result = "read"
or
exists(boolean certain | this = Write(certain) and result = "write (" + certain + ")")
}
int getOrder() {
this = Read() and
result = 0
or
this = Write(_) and
result = 1
}
}
/**
* Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`.
*/
private predicate ref(BasicBlock bb, int i, SourceVariable v, RefKind k) {
variableRead(bb, i, v) and k = Read()
or
exists(boolean certain | variableWrite(bb, i, v, certain) | k = Write(certain))
}
private newtype OrderedRefIndex =
MkOrderedRefIndex(int i, int tag) {
exists(RefKind rk | ref(_, i, _, rk) | tag = rk.getOrder())
}
private OrderedRefIndex refOrd(BasicBlock bb, int i, SourceVariable v, RefKind k, int ord) {
ref(bb, i, v, k) and
result = MkOrderedRefIndex(i, ord) and
ord = k.getOrder()
}
/**
* Gets the (1-based) rank of the reference to `v` at the `i`th node of
* basic block `bb`, which has the given reference kind `k`.
*
* Reads are considered before writes when they happen at the same index.
*/
private int refRank(BasicBlock bb, int i, SourceVariable v, RefKind k) {
refOrd(bb, i, v, k, _) =
rank[result](int j, int ord, OrderedRefIndex res |
res = refOrd(bb, j, v, _, ord)
|
res order by j, ord
)
}
private int maxRefRank(BasicBlock bb, SourceVariable v) {
result = refRank(bb, _, v, _) and
not result + 1 = refRank(bb, _, v, _)
}
/**
* Gets the (1-based) rank of the first reference to `v` inside basic block `bb`
* that is either a read or a certain write.
*/
private int firstReadOrCertainWrite(BasicBlock bb, SourceVariable v) {
result =
min(int r, RefKind k |
r = refRank(bb, _, v, k) and
k != Write(false)
|
r
)
}
/**
* Holds if source variable `v` is live at the beginning of basic block `bb`.
*/
predicate liveAtEntry(BasicBlock bb, SourceVariable v) {
// The first read or certain write to `v` inside `bb` is a read
refRank(bb, _, v, Read()) = firstReadOrCertainWrite(bb, v)
or
// There is no certain write to `v` inside `bb`, but `v` is live at entry
// to a successor basic block of `bb`
not exists(firstReadOrCertainWrite(bb, v)) and
liveAtExit(bb, v)
}
/**
* Holds if source variable `v` is live at the end of basic block `bb`.
*/
predicate liveAtExit(BasicBlock bb, SourceVariable v) {
liveAtEntry(getABasicBlockSuccessor(bb), v)
}
/**
* Holds if variable `v` is live in basic block `bb` at index `i`.
* The rank of `i` is `rnk` as defined by `refRank()`.
*/
private predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk) {
exists(RefKind kind | rnk = refRank(bb, i, v, kind) |
rnk = maxRefRank(bb, v) and
liveAtExit(bb, v)
or
ref(bb, i, v, kind) and
kind = Read()
or
exists(RefKind nextKind |
liveAtRank(bb, _, v, rnk + 1) and
rnk + 1 = refRank(bb, _, v, nextKind) and
nextKind != Write(true)
)
)
}
/**
* Holds if variable `v` is live after the (certain or uncertain) write at
* index `i` inside basic block `bb`.
*/
predicate liveAfterWrite(BasicBlock bb, int i, SourceVariable v) {
exists(int rnk | rnk = refRank(bb, i, v, Write(_)) | liveAtRank(bb, i, v, rnk))
}
}
private import Liveness
/** Holds if `bb1` strictly dominates `bb2`. */
private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) {
bb1 = getImmediateBasicBlockDominator+(bb2)
}
/** Holds if `bb1` dominates a predecessor of `bb2`. */
private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) {
exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) |
bb1 = pred
or
strictlyDominates(bb1, pred)
)
}
/** Holds if `df` is in the dominance frontier of `bb`. */
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and
not strictlyDominates(bb, df)
}
/**
* Holds if `bb` is in the dominance frontier of a block containing a
* definition of `v`.
*/
pragma[noinline]
private predicate inDefDominanceFrontier(BasicBlock bb, SourceVariable v) {
exists(BasicBlock defbb, Definition def |
def.definesAt(v, defbb, _) and
inDominanceFrontier(defbb, bb)
)
}
cached
newtype TDefinition =
TWriteDef(SourceVariable v, BasicBlock bb, int i) {
@@ -186,322 +186,312 @@ private module Cached {
liveAtEntry(bb, v)
}
private module SsaDefReaches {
newtype TSsaRefKind =
SsaRead() or
SsaDef()
/**
* A classification of SSA variable references into reads and definitions.
*/
class SsaRefKind extends TSsaRefKind {
string toString() {
this = SsaRead() and
result = "SsaRead"
or
this = SsaDef() and
result = "SsaDef"
}
int getOrder() {
this = SsaRead() and
result = 0
or
this = SsaDef() and
result = 1
}
}
/**
* Holds if the `i`th node of basic block `bb` is a reference to `v`,
* either a read (when `k` is `SsaRead()`) or an SSA definition (when `k`
* is `SsaDef()`).
*
* Unlike `Liveness::ref`, this includes `phi` nodes.
*/
predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) {
variableRead(bb, i, v) and
k = SsaRead()
or
exists(Definition def | def.definesAt(v, bb, i)) and
k = SsaDef()
}
private newtype OrderedSsaRefIndex =
MkOrderedSsaRefIndex(int i, SsaRefKind k) { ssaRef(_, i, _, k) }
private OrderedSsaRefIndex ssaRefOrd(
BasicBlock bb, int i, SourceVariable v, SsaRefKind k, int ord
) {
ssaRef(bb, i, v, k) and
result = MkOrderedSsaRefIndex(i, k) and
ord = k.getOrder()
}
/**
* Gets the (1-based) rank of the reference to `v` at the `i`th node of basic
* block `bb`, which has the given reference kind `k`.
*
* For example, if `bb` is a basic block with a phi node for `v` (considered
* to be at index -1), reads `v` at node 2, and defines it at node 5, we have:
*
* ```ql
* ssaRefRank(bb, -1, v, SsaDef()) = 1 // phi node
* ssaRefRank(bb, 2, v, Read()) = 2 // read at node 2
* ssaRefRank(bb, 5, v, SsaDef()) = 3 // definition at node 5
* ```
*
* Reads are considered before writes when they happen at the same index.
*/
int ssaRefRank(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) {
ssaRefOrd(bb, i, v, k, _) =
rank[result](int j, int ord, OrderedSsaRefIndex res |
res = ssaRefOrd(bb, j, v, _, ord)
|
res order by j, ord
)
}
int maxSsaRefRank(BasicBlock bb, SourceVariable v) {
result = ssaRefRank(bb, _, v, _) and
not result + 1 = ssaRefRank(bb, _, v, _)
}
/**
* Holds if the SSA definition `def` reaches rank index `rnk` in its own
* basic block `bb`.
*/
predicate ssaDefReachesRank(BasicBlock bb, Definition def, int rnk, SourceVariable v) {
exists(int i |
rnk = ssaRefRank(bb, i, v, SsaDef()) and
def.definesAt(v, bb, i)
)
or
ssaDefReachesRank(bb, def, rnk - 1, v) and
rnk = ssaRefRank(bb, _, v, SsaRead())
}
/**
* Holds if the SSA definition of `v` at `def` reaches index `i` in the same
* basic block `bb`, without crossing another SSA definition of `v`.
*/
predicate ssaDefReachesReadWithinBlock(SourceVariable v, Definition def, BasicBlock bb, int i) {
exists(int rnk |
ssaDefReachesRank(bb, def, rnk, v) and
rnk = ssaRefRank(bb, i, v, SsaRead()) and
variableRead(bb, i, v)
)
}
/**
* Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition
* `redef` in the same basic block, without crossing another SSA definition of `v`.
*/
predicate ssaDefReachesUncertainDefWithinBlock(
SourceVariable v, Definition def, UncertainWriteDefinition redef
) {
exists(BasicBlock bb, int rnk, int i |
ssaDefReachesRank(bb, def, rnk, v) and
rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and
redef.definesAt(v, bb, i)
)
}
/**
* Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`.
*/
int ssaDefRank(Definition def, SourceVariable v, BasicBlock bb, int i, SsaRefKind k) {
v = def.getSourceVariable() and
result = ssaRefRank(bb, i, v, k) and
(
ssaDefReachesRead(_, def, bb, i)
or
def.definesAt(_, bb, i)
)
}
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
exists(ssaDefRank(def, v, bb, _, _))
}
pragma[noinline]
private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) {
result = getABasicBlockSuccessor(bb) and
not defOccursInBlock(_, bb, def.getSourceVariable()) and
ssaDefReachesEndOfBlock(bb, def, _)
}
/**
* Holds if `def` is accessed in basic block `bb1` (either a read or a write),
* `bb2` is a transitive successor of `bb1`, `def` is live at the end of `bb1`,
* and the underlying variable for `def` is neither read nor written in any block
* on the path between `bb1` and `bb2`.
*/
predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) {
defOccursInBlock(def, bb1, _) and
bb2 = getABasicBlockSuccessor(bb1)
or
exists(BasicBlock mid | varBlockReaches(def, bb1, mid) |
bb2 = getAMaybeLiveSuccessor(def, mid)
)
}
/**
* Holds if `def` is accessed in basic block `bb1` (either a read or a write),
* `def` is read at index `i2` in basic block `bb2`, `bb2` is in a transitive
* successor block of `bb1`, and `def` is neither read nor written in any block
* on a path between `bb1` and `bb2`.
*/
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
varBlockReaches(def, bb1, bb2) and
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and
variableRead(bb2, i2, _)
}
}
private import SsaDefReaches
pragma[noinline]
private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) {
exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) |
// The construction of SSA form ensures that each read of a variable is
// dominated by its definition. An SSA definition therefore reaches a
// control flow node if it is the _closest_ SSA definition that dominates
// the node. If two definitions dominate a node then one must dominate the
// other, so therefore the definition of _closest_ is given by the dominator
// tree. Thus, reaching definitions can be calculated in terms of dominance.
idom = getImmediateBasicBlockDominator(bb)
)
}
/**
* Holds if the SSA definition of `v` at `def` reaches the end of basic
* block `bb`, at which point it is still live, without crossing another
* SSA definition of `v`.
*/
cached
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable v) {
exists(int last | last = maxSsaRefRank(bb, v) |
ssaDefReachesRank(bb, def, last, v) and
liveAtExit(bb, v)
)
or
ssaDefReachesEndOfBlockRec(bb, def, v) and
liveAtExit(bb, v) and
not ssaRef(bb, _, v, SsaDef())
predicate uncertainWriteDefinitionInput(UncertainWriteDefinition def, Definition inp) {
lastRefRedef(inp, _, _, def)
}
/**
* Holds if the SSA definition of `v` at `def` reaches a read at index `i` in
* basic block `bb`, without crossing another SSA definition of `v`. The read
* is of kind `rk`.
*/
cached
predicate ssaDefReachesRead(SourceVariable v, Definition def, BasicBlock bb, int i) {
ssaDefReachesReadWithinBlock(v, def, bb, i)
or
variableRead(bb, i, v) and
ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and
not ssaDefReachesReadWithinBlock(v, _, bb, i)
}
/**
* Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition
* `redef` without crossing another SSA definition of `v`.
*/
cached
predicate ssaDefReachesUncertainDef(
SourceVariable v, Definition def, UncertainWriteDefinition redef
) {
ssaDefReachesUncertainDefWithinBlock(v, def, redef)
or
exists(BasicBlock bb |
redef.definesAt(v, bb, _) and
ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and
not ssaDefReachesUncertainDefWithinBlock(v, _, redef)
)
}
/**
* Holds if `def` is accessed at index `i1` in basic block `bb1` (either a read
* or a write), `def` is read at index `i2` in basic block `bb2`, and there is a
* path between them without any read of `def`.
*/
cached
predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) {
exists(int rnk |
rnk = ssaDefRank(def, _, bb1, i1, _) and
rnk + 1 = ssaDefRank(def, _, bb1, i2, SsaRead()) and
variableRead(bb1, i2, _) and
bb2 = bb1
)
or
exists(SourceVariable v | ssaDefRank(def, v, bb1, i1, _) = maxSsaRefRank(bb1, v)) and
defAdjacentRead(def, bb1, bb2, i2)
}
/**
* Holds if the node at index `i` in `bb` is a last reference to SSA definition
* `def`. The reference is last because it can reach another write `next`,
* without passing through another read or write.
*/
cached
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
exists(int rnk, SourceVariable v, int j | rnk = ssaDefRank(def, v, bb, i, _) |
// Next reference to `v` inside `bb` is a write
next.definesAt(v, bb, j) and
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
or
// Can reach a write using one or more steps
rnk = maxSsaRefRank(bb, v) and
exists(BasicBlock bb2 |
varBlockReaches(def, bb, bb2) and
next.definesAt(v, bb2, j) and
1 = ssaRefRank(bb2, j, v, SsaDef())
)
)
}
/**
* Holds if the node at index `i` in `bb` is a last reference to SSA
* definition `def`.
*
* That is, the node can reach the end of the enclosing callable, or another
* SSA definition for the underlying source variable, without passing through
* another read.
*/
cached
predicate lastRef(Definition def, BasicBlock bb, int i) {
lastRefRedef(def, bb, i, _)
or
exists(SourceVariable v | ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) |
// Can reach exit directly
bb instanceof ExitBasicBlock
or
// Can reach a block using one or more steps, where `def` is no longer live
exists(BasicBlock bb2 | varBlockReaches(def, bb, bb2) |
not defOccursInBlock(def, bb2, _) and
not ssaDefReachesEndOfBlock(bb2, def, _)
)
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) {
exists(SourceVariable v, BasicBlock bbDef |
phi.definesAt(v, bbDef, _) and
getABasicBlockPredecessor(bbDef) = bb and
ssaDefReachesEndOfBlock(bb, inp, v)
)
}
}
import Cached
private module SsaDefReaches {
newtype TSsaRefKind =
SsaRead() or
SsaDef()
/**
* A classification of SSA variable references into reads and definitions.
*/
class SsaRefKind extends TSsaRefKind {
string toString() {
this = SsaRead() and
result = "SsaRead"
or
this = SsaDef() and
result = "SsaDef"
}
int getOrder() {
this = SsaRead() and
result = 0
or
this = SsaDef() and
result = 1
}
}
/**
* Holds if the `i`th node of basic block `bb` is a reference to `v`,
* either a read (when `k` is `SsaRead()`) or an SSA definition (when `k`
* is `SsaDef()`).
*
* Unlike `Liveness::ref`, this includes `phi` nodes.
*/
predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) {
variableRead(bb, i, v) and
k = SsaRead()
or
exists(Definition def | def.definesAt(v, bb, i)) and
k = SsaDef()
}
private newtype OrderedSsaRefIndex =
MkOrderedSsaRefIndex(int i, SsaRefKind k) { ssaRef(_, i, _, k) }
private OrderedSsaRefIndex ssaRefOrd(BasicBlock bb, int i, SourceVariable v, SsaRefKind k, int ord) {
ssaRef(bb, i, v, k) and
result = MkOrderedSsaRefIndex(i, k) and
ord = k.getOrder()
}
/**
* Gets the (1-based) rank of the reference to `v` at the `i`th node of basic
* block `bb`, which has the given reference kind `k`.
*
* For example, if `bb` is a basic block with a phi node for `v` (considered
* to be at index -1), reads `v` at node 2, and defines it at node 5, we have:
*
* ```ql
* ssaRefRank(bb, -1, v, SsaDef()) = 1 // phi node
* ssaRefRank(bb, 2, v, Read()) = 2 // read at node 2
* ssaRefRank(bb, 5, v, SsaDef()) = 3 // definition at node 5
* ```
*
* Reads are considered before writes when they happen at the same index.
*/
int ssaRefRank(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) {
ssaRefOrd(bb, i, v, k, _) =
rank[result](int j, int ord, OrderedSsaRefIndex res |
res = ssaRefOrd(bb, j, v, _, ord)
|
res order by j, ord
)
}
int maxSsaRefRank(BasicBlock bb, SourceVariable v) {
result = ssaRefRank(bb, _, v, _) and
not result + 1 = ssaRefRank(bb, _, v, _)
}
/**
* Holds if the SSA definition `def` reaches rank index `rnk` in its own
* basic block `bb`.
*/
predicate ssaDefReachesRank(BasicBlock bb, Definition def, int rnk, SourceVariable v) {
exists(int i |
rnk = ssaRefRank(bb, i, v, SsaDef()) and
def.definesAt(v, bb, i)
)
or
ssaDefReachesRank(bb, def, rnk - 1, v) and
rnk = ssaRefRank(bb, _, v, SsaRead())
}
/**
* Holds if the SSA definition of `v` at `def` reaches index `i` in the same
* basic block `bb`, without crossing another SSA definition of `v`.
*/
predicate ssaDefReachesReadWithinBlock(SourceVariable v, Definition def, BasicBlock bb, int i) {
exists(int rnk |
ssaDefReachesRank(bb, def, rnk, v) and
rnk = ssaRefRank(bb, i, v, SsaRead()) and
variableRead(bb, i, v)
)
}
/**
* Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition
* `redef` in the same basic block, without crossing another SSA definition of `v`.
*/
predicate ssaDefReachesUncertainDefWithinBlock(
SourceVariable v, Definition def, UncertainWriteDefinition redef
) {
exists(BasicBlock bb, int rnk, int i |
ssaDefReachesRank(bb, def, rnk, v) and
rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and
redef.definesAt(v, bb, i)
)
}
/**
* Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`.
*/
int ssaDefRank(Definition def, SourceVariable v, BasicBlock bb, int i, SsaRefKind k) {
v = def.getSourceVariable() and
result = ssaRefRank(bb, i, v, k) and
(
ssaDefReachesRead(_, def, bb, i)
or
def.definesAt(_, bb, i)
)
}
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
exists(ssaDefRank(def, v, bb, _, _))
}
pragma[noinline]
private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) {
result = getABasicBlockSuccessor(bb) and
not defOccursInBlock(_, bb, def.getSourceVariable()) and
ssaDefReachesEndOfBlock(bb, def, _)
}
/**
* Holds if `def` is accessed in basic block `bb1` (either a read or a write),
* `bb2` is a transitive successor of `bb1`, `def` is live at the end of `bb1`,
* and the underlying variable for `def` is neither read nor written in any block
* on the path between `bb1` and `bb2`.
*/
predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) {
defOccursInBlock(def, bb1, _) and
bb2 = getABasicBlockSuccessor(bb1)
or
exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid))
}
/**
* Holds if `def` is accessed in basic block `bb1` (either a read or a write),
* `def` is read at index `i2` in basic block `bb2`, `bb2` is in a transitive
* successor block of `bb1`, and `def` is neither read nor written in any block
* on a path between `bb1` and `bb2`.
*/
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
varBlockReaches(def, bb1, bb2) and
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and
variableRead(bb2, i2, _)
}
}
private import SsaDefReaches
pragma[noinline]
private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) {
exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) |
// The construction of SSA form ensures that each read of a variable is
// dominated by its definition. An SSA definition therefore reaches a
// control flow node if it is the _closest_ SSA definition that dominates
// the node. If two definitions dominate a node then one must dominate the
// other, so therefore the definition of _closest_ is given by the dominator
// tree. Thus, reaching definitions can be calculated in terms of dominance.
idom = getImmediateBasicBlockDominator(bb)
)
}
/**
* NB: If this predicate is exposed, it should be cached.
*
* Holds if the SSA definition of `v` at `def` reaches the end of basic
* block `bb`, at which point it is still live, without crossing another
* SSA definition of `v`.
*/
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable v) {
exists(int last | last = maxSsaRefRank(bb, v) |
ssaDefReachesRank(bb, def, last, v) and
liveAtExit(bb, v)
)
or
ssaDefReachesEndOfBlockRec(bb, def, v) and
liveAtExit(bb, v) and
not ssaRef(bb, _, v, SsaDef())
}
/**
* NB: If this predicate is exposed, it should be cached.
*
* Holds if the SSA definition of `v` at `def` reaches a read at index `i` in
* basic block `bb`, without crossing another SSA definition of `v`. The read
* is of kind `rk`.
*/
predicate ssaDefReachesRead(SourceVariable v, Definition def, BasicBlock bb, int i) {
ssaDefReachesReadWithinBlock(v, def, bb, i)
or
variableRead(bb, i, v) and
ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and
not ssaDefReachesReadWithinBlock(v, _, bb, i)
}
/**
* NB: If this predicate is exposed, it should be cached.
*
* Holds if `def` is accessed at index `i1` in basic block `bb1` (either a read
* or a write), `def` is read at index `i2` in basic block `bb2`, and there is a
* path between them without any read of `def`.
*/
predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) {
exists(int rnk |
rnk = ssaDefRank(def, _, bb1, i1, _) and
rnk + 1 = ssaDefRank(def, _, bb1, i2, SsaRead()) and
variableRead(bb1, i2, _) and
bb2 = bb1
)
or
exists(SourceVariable v | ssaDefRank(def, v, bb1, i1, _) = maxSsaRefRank(bb1, v)) and
defAdjacentRead(def, bb1, bb2, i2)
}
/**
* NB: If this predicate is exposed, it should be cached.
*
* Holds if the node at index `i` in `bb` is a last reference to SSA definition
* `def`. The reference is last because it can reach another write `next`,
* without passing through another read or write.
*/
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
exists(int rnk, SourceVariable v, int j | rnk = ssaDefRank(def, v, bb, i, _) |
// Next reference to `v` inside `bb` is a write
next.definesAt(v, bb, j) and
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
or
// Can reach a write using one or more steps
rnk = maxSsaRefRank(bb, v) and
exists(BasicBlock bb2 |
varBlockReaches(def, bb, bb2) and
next.definesAt(v, bb2, j) and
1 = ssaRefRank(bb2, j, v, SsaDef())
)
)
}
/**
* NB: If this predicate is exposed, it should be cached.
*
* Holds if the node at index `i` in `bb` is a last reference to SSA
* definition `def`.
*
* That is, the node can reach the end of the enclosing callable, or another
* SSA definition for the underlying source variable, without passing through
* another read.
*/
predicate lastRef(Definition def, BasicBlock bb, int i) {
lastRefRedef(def, bb, i, _)
or
exists(SourceVariable v | ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) |
// Can reach exit directly
bb instanceof ExitBasicBlock
or
// Can reach a block using one or more steps, where `def` is no longer live
exists(BasicBlock bb2 | varBlockReaches(def, bb, bb2) |
not defOccursInBlock(def, bb2, _) and
not ssaDefReachesEndOfBlock(bb2, def, _)
)
)
}
/** A static single assignment (SSA) definition. */
class Definition extends TDefinition {
/** Gets the source variable underlying this SSA definition. */
SourceVariable getSourceVariable() { this.definesAt(result, _, _) }
/**
* Holds is this SSA definition is live at the end of basic block `bb`.
* That is, this definition reaches the end of basic block `bb`, at which
* point it is still live, without crossing another SSA definition of the
* same source variable.
*/
final predicate isLiveAtEndOfBlock(BasicBlock bb) { ssaDefReachesEndOfBlock(bb, this, _) }
/**
* Holds if this SSA definition defines `v` at index `i` in basic block `bb`.
* Phi nodes are considered to be at index `-1`, while normal variable writes
@@ -552,20 +542,10 @@ class WriteDefinition extends Definition, TWriteDef {
/** A phi node. */
class PhiNode extends Definition, TPhiNode {
/** Gets an input of this phi node. */
Definition getAnInput() {
exists(BasicBlock bb, BasicBlock pred, SourceVariable v |
this.definesAt(v, bb, _) and
getABasicBlockPredecessor(bb) = pred and
ssaDefReachesEndOfBlock(pred, result, v)
)
}
Definition getAnInput() { this.hasInputFromBlock(result, _) }
/** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
predicate hasInputFromBlock(Definition inp, BasicBlock bb) {
inp = this.getAnInput() and
getABasicBlockPredecessor(this.getBasicBlock()) = bb and
ssaDefReachesEndOfBlock(bb, inp, _)
}
predicate hasInputFromBlock(Definition inp, BasicBlock bb) { phiHasInputFromBlock(this, inp, bb) }
override string toString() { result = "Phi" }
}
@@ -586,5 +566,5 @@ class UncertainWriteDefinition extends WriteDefinition {
* Gets the immediately preceding definition. Since this update is uncertain,
* the value from the preceding definition might still be valid.
*/
Definition getPriorDefinition() { ssaDefReachesUncertainDef(_, result, this) }
Definition getPriorDefinition() { uncertainWriteDefinitionInput(this, result) }
}

View File

@@ -290,10 +290,20 @@ private predicate hasChildPattern(ControlFlowElement pm, Expr child) {
or
exists(Expr mid |
hasChildPattern(pm, mid) and
mid instanceof @recursive_pattern_expr
|
child = mid.getChild(2).getAChildExpr() or
child = mid.getChild(3).getAChildExpr()
mid instanceof @property_pattern_expr and
child = mid.getAChildExpr()
)
or
exists(Expr mid |
hasChildPattern(pm, mid) and
mid instanceof @positional_pattern_expr and
child = mid.getAChildExpr()
)
or
exists(Expr mid |
hasChildPattern(pm, mid) and
mid instanceof @recursive_pattern_expr and
child = mid.getChild([2, 3])
)
or
exists(Expr mid |
@@ -301,6 +311,11 @@ private predicate hasChildPattern(ControlFlowElement pm, Expr child) {
mid instanceof @unary_pattern_expr and
child = mid.getChild(0)
)
or
exists(Expr mid | hasChildPattern(pm, mid) and mid instanceof @binary_pattern_expr |
child = mid.getChild(0) or
child = mid.getChild(1)
)
}
/**
@@ -457,7 +472,7 @@ class RecursivePatternExpr extends BindingPatternExpr, @recursive_pattern_expr {
}
/** A property pattern. For example, `{ Length: 5 }`. */
class PropertyPatternExpr extends Expr, @property_pattern_expr {
class PropertyPatternExpr extends PatternExpr, @property_pattern_expr {
override string toString() { result = "{ ... }" }
/** Gets the `n`th pattern. */
@@ -480,7 +495,7 @@ class LabeledPatternExpr extends PatternExpr {
}
/** A positional pattern. For example, `(int x, int y)`. */
class PositionalPatternExpr extends Expr, @positional_pattern_expr {
class PositionalPatternExpr extends PatternExpr, @positional_pattern_expr {
override string toString() { result = "( ... )" }
/** Gets the `n`th pattern. */
@@ -502,6 +517,32 @@ class NotPatternExpr extends UnaryPatternExpr, @not_pattern_expr {
override string getAPrimaryQlClass() { result = "NotPatternExpr" }
}
/** A binary pattern. For example, `1 or 2`. */
class BinaryPatternExpr extends PatternExpr, @binary_pattern_expr {
/** Gets a pattern. */
PatternExpr getAnOperand() { result = getLeftOperand() or result = getRightOperand() }
/** Gets the left pattern. */
PatternExpr getLeftOperand() { result = this.getChild(0) }
/** Gets the right pattern. */
PatternExpr getRightOperand() { result = this.getChild(1) }
}
/** A binary `or` pattern. For example, `1 or 2`. */
class OrPatternExpr extends BinaryPatternExpr, @or_pattern_expr {
override string toString() { result = "... or ..." }
override string getAPrimaryQlClass() { result = "OrPatternExpr" }
}
/** A binary `and` pattern. For example, `< 1 and > 2`. */
class AndPatternExpr extends BinaryPatternExpr, @and_pattern_expr {
override string toString() { result = "... and ..." }
override string getAPrimaryQlClass() { result = "AndPatternExpr" }
}
/**
* An expression or statement that matches the value of an expression against
* a pattern. Either an `is` expression or a `case` expression/statement.

View File

@@ -1032,6 +1032,8 @@ case @expr.kind of
| 124 = @le_pattern_expr
| 125 = @ge_pattern_expr
| 126 = @not_pattern_expr
| 127 = @and_pattern_expr
| 128 = @or_pattern_expr
| 129 = @function_pointer_invocation_expr
;
@@ -1040,6 +1042,7 @@ case @expr.kind of
@pattern_match = @case | @is_expr;
@unary_pattern_expr = @not_pattern_expr;
@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr;
@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr;
@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr;
@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr;

File diff suppressed because it is too large Load Diff

View File

@@ -240,7 +240,7 @@ arguments.cs:
# 72| 0: [TypeMention] Attribute
# 74| 4: [Field] x
# 74| -1: [TypeMention] int
# 75| 5: [IndexerProperty] y
# 75| 5: [Property] y
# 75| -1: [TypeMention] string
# 75| 3: [Getter] get_y
# 75| 4: [Setter] set_y

View File

@@ -150,7 +150,7 @@ attributes.cs:
# 62| 0: [TypeMention] Attribute
# 64| 4: [Field] x
# 64| -1: [TypeMention] int
# 65| 5: [IndexerProperty] y
# 65| 5: [Property] y
# 65| -1: [TypeMention] string
# 65| 3: [Getter] get_y
# 65| 4: [Setter] set_y

View File

@@ -983,6 +983,38 @@
| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:13:80:20 | ... => ... | 2 |
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ | 1 |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:20 | ... => ... | 2 |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:44:85:44 | 1 | 3 |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:39:85:53 | [false] ... is ... | 1 |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:39:85:53 | [true] ... is ... | 1 |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | exit M8 | 3 |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:44:85:53 | [match] ... or ... | 1 |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | 1 |
| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:49:85:53 | [match] not ... | 1 |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:49:85:53 | [no-match] not ... | 1 |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | 1 |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" | 1 |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" | 1 |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:44:87:44 | 1 | 3 |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:39:87:54 | [false] ... is ... | 1 |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:39:87:54 | [true] ... is ... | 1 |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | exit M9 | 3 |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:44:87:54 | [match] ... and ... | 1 |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | 1 |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:50:87:54 | [match] not ... | 1 |
| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:50:87:54 | [no-match] not ... | 1 |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | 1 |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" | 1 |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" | 1 |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:29:95:31 | access to constant A | 5 |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 | 2 |
| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:13:95:40 | [false] ... is ... | 1 |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:13:95:40 | [true] ... is ... | 1 |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | 1 |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | 1 |
| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:29:95:38 | [match] ... or ... | 1 |
| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:29:95:38 | [no-match] ... or ... | 1 |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | 1 |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:97:13:97:38 | call to method WriteLine | 4 |
| PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | exit M1 | 7 |
| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:18:12:21 | null | 5 |
| PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:10:10:10:11 | exit M2 | 2 |

View File

@@ -1890,6 +1890,63 @@ conditionBlock
| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:81:13:81:13 | _ | false |
| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:81:18:81:20 | "0" | false |
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" | true |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:53 | [false] ... is ... | false |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:44:85:53 | [no-match] ... or ... | false |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:49:85:53 | [match] not ... | false |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:49:85:53 | [no-match] not ... | false |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:53:85:53 | 2 | false |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:67:85:69 | "2" | false |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" | false |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | true |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:39:85:53 | [true] ... is ... | true |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:57:85:63 | "not 2" | true |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:39:85:53 | [false] ... is ... | false |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:67:85:69 | "2" | false |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:39:85:53 | [false] ... is ... | false |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | false |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:67:85:69 | "2" | false |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:39:85:53 | [false] ... is ... | true |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:44:85:53 | [no-match] ... or ... | true |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [match] not ... | false |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [no-match] not ... | true |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:67:85:69 | "2" | true |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:54 | [true] ... is ... | true |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:44:87:54 | [match] ... and ... | true |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:50:87:54 | [match] not ... | true |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:50:87:54 | [no-match] not ... | true |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:54:87:54 | 2 | true |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:58:87:60 | "1" | true |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" | false |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" | true |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:39:87:54 | [true] ... is ... | true |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:58:87:60 | "1" | true |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:39:87:54 | [false] ... is ... | false |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:64:87:70 | "not 1" | false |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:39:87:54 | [true] ... is ... | true |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:44:87:54 | [match] ... and ... | true |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:58:87:60 | "1" | true |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:39:87:54 | [true] ... is ... | false |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:44:87:54 | [match] ... and ... | false |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [match] not ... | false |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [no-match] not ... | true |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:58:87:60 | "1" | false |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:29:95:38 | [no-match] ... or ... | false |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:36:95:38 | access to constant B | false |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | exit M10 (normal) | false |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | exit M10 (normal) | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | false |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | false |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | false |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | false |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:96:9:98:9 | {...} | false |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:96:9:98:9 | {...} | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:96:9:98:9 | {...} | true |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [no-match] ... or ... | false |
| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:13:12:21 | [false] ... is ... | false |
| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:13:12:21 | [true] ... is ... | true |
| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:13:13:13:19 | return ...; | true |
@@ -2798,6 +2855,12 @@ conditionFlow
| Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:27:13:27:24 | case ...: | false |
| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:34:51:34 | access to parameter c | false |
| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:25:51:25 | access to parameter c | true |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" | false |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | true |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" | false |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" | true |
| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:93:17:93:19 | exit M10 (normal) | false |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} | true |
| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:14:9:14:29 | ...; | false |
| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:13:13:13:19 | return ...; | true |
| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:21:9:21:29 | ...; | false |

View File

@@ -3207,6 +3207,47 @@ dominance
| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:13:80:20 | ... => ... |
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:20 | ... => ... |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:39 | access to parameter i |
| Patterns.cs:85:26:85:27 | exit M8 (normal) | Patterns.cs:85:26:85:27 | exit M8 |
| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:44:85:44 | 1 |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | exit M8 (normal) |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:53 | [match] ... or ... |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:53:85:53 | 2 |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:39:85:53 | [true] ... is ... |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:39 | access to parameter i |
| Patterns.cs:87:26:87:27 | exit M9 (normal) | Patterns.cs:87:26:87:27 | exit M9 |
| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:44:87:44 | 1 |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | exit M9 (normal) |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:54 | [no-match] ... and ... |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:54:87:54 | 2 |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:39:87:54 | [false] ... is ... |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:94:5:99:5 | {...} |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 |
| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:95:9:98:9 | if (...) ... |
| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:95:13:95:16 | this access |
| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:29:95:31 | access to constant A |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:38 | [match] ... or ... |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:36:95:38 | access to constant B |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:97:13:97:39 | ...; |
| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:97:31:97:37 | "not C" |
| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:13:97:38 | call to method WriteLine |
| PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:6:5:8:5 | {...} |
| PostDominance.cs:5:10:5:11 | exit M1 (normal) | PostDominance.cs:5:10:5:11 | exit M1 |
| PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:7:9:7:29 | ...; |
@@ -7226,6 +7267,44 @@ postDominance
| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:18:80:20 | "1" |
| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:18:81:20 | "0" |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:13 | _ |
| Patterns.cs:85:26:85:27 | exit M8 | Patterns.cs:85:26:85:27 | exit M8 (normal) |
| Patterns.cs:85:26:85:27 | exit M8 (normal) | Patterns.cs:85:39:85:69 | ... ? ... : ... |
| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:26:85:27 | enter M8 |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:44:85:53 | [match] ... or ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:39:85:39 | access to parameter i |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:39:85:53 | [true] ... is ... |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:87:26:87:27 | exit M9 | Patterns.cs:87:26:87:27 | exit M9 (normal) |
| Patterns.cs:87:26:87:27 | exit M9 (normal) | Patterns.cs:87:39:87:70 | ... ? ... : ... |
| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:26:87:27 | enter M9 |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:39:87:39 | access to parameter i |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:39:87:54 | [false] ... is ... |
| Patterns.cs:93:17:93:19 | exit M10 | Patterns.cs:93:17:93:19 | exit M10 (normal) |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:13:95:40 | [false] ... is ... |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:97:13:97:38 | call to method WriteLine |
| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:93:17:93:19 | enter M10 |
| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:94:5:99:5 | {...} |
| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:9:98:9 | if (...) ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:38 | [match] ... or ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:13:95:16 | this access |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:97:31:97:37 | "not C" |
| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:96:9:98:9 | {...} |
| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:13:97:39 | ...; |
| PostDominance.cs:5:10:5:11 | exit M1 | PostDominance.cs:5:10:5:11 | exit M1 (normal) |
| PostDominance.cs:5:10:5:11 | exit M1 (normal) | PostDominance.cs:7:9:7:28 | call to method WriteLine |
| PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:5:10:5:11 | enter M1 |
@@ -11771,6 +11850,106 @@ blockDominance
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ |
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:18:81:20 | "0" |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:26:85:27 | enter M8 |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:53 | [true] ... is ... |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:69 | ... ? ... : ... |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:44:85:53 | [match] ... or ... |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:53:85:53 | 2 |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:39:85:53 | [true] ... is ... |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:69 | ... ? ... : ... |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:39:85:53 | [true] ... is ... |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:44:85:53 | [match] ... or ... |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:26:87:27 | enter M9 |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:54 | [false] ... is ... |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:70 | ... ? ... : ... |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:44:87:54 | [no-match] ... and ... |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:54:87:54 | 2 |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:39:87:54 | [false] ... is ... |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:70 | ... ? ... : ... |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:39:87:54 | [false] ... is ... |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | enter M10 |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | exit M10 (normal) |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:13:95:40 | [false] ... is ... |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:29:95:38 | [match] ... or ... |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:36:95:38 | access to constant B |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:96:9:98:9 | {...} |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 (normal) |
| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:13:95:40 | [false] ... is ... |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | exit M10 (normal) |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | exit M10 (normal) |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:96:9:98:9 | {...} |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:96:9:98:9 | {...} |
| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:29:95:38 | [match] ... or ... |
| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:96:9:98:9 | {...} |
| PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | enter M1 |
| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:10:10:10:11 | enter M2 |
| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:10:10:10:11 | exit M2 (normal) |
@@ -15135,6 +15314,101 @@ postBlockDominance
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:13 | _ |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:18:81:20 | "0" |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:26:85:27 | enter M8 |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:39:85:53 | [true] ... is ... |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:44:85:53 | [match] ... or ... |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | enter M8 |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:53 | [true] ... is ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:69 | ... ? ... : ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:44:85:53 | [match] ... or ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:53:85:53 | 2 |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:44:85:53 | [match] ... or ... |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:39:85:53 | [true] ... is ... |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:44:85:53 | [match] ... or ... |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:49:85:53 | [match] not ... |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:39:85:53 | [false] ... is ... |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:44:85:53 | [no-match] ... or ... |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:49:85:53 | [no-match] not ... |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:26:87:27 | enter M9 |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:39:87:54 | [false] ... is ... |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | enter M9 |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:54 | [false] ... is ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:70 | ... ? ... : ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:54:87:54 | 2 |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:39:87:54 | [true] ... is ... |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:44:87:54 | [match] ... and ... |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:50:87:54 | [match] not ... |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:39:87:54 | [false] ... is ... |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:44:87:54 | [no-match] ... and ... |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:50:87:54 | [no-match] not ... |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | enter M10 |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | enter M10 |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 (normal) |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:13:95:40 | [false] ... is ... |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:29:95:38 | [match] ... or ... |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:36:95:38 | access to constant B |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:96:9:98:9 | {...} |
| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:13:95:40 | [false] ... is ... |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | enter M10 |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | enter M10 |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:38 | [match] ... or ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:38 | [match] ... or ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:36:95:38 | access to constant B |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:36:95:38 | access to constant B |
| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:29:95:38 | [match] ... or ... |
| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:29:95:38 | [no-match] ... or ... |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:95:13:95:40 | [true] ... is ... |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:96:9:98:9 | {...} |
| PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | enter M1 |
| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:10:10:10:11 | enter M2 |
| PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:10:10:10:11 | enter M2 |

View File

@@ -3655,6 +3655,54 @@ nodeEnclosing
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:74:26:74:27 | M7 |
| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:74:26:74:27 | M7 |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:74:26:74:27 | M7 |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:26:85:27 | exit M8 | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:26:85:27 | exit M8 (normal) | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:26:87:27 | exit M9 | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:26:87:27 | exit M9 (normal) | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:93:17:93:19 | exit M10 | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:13:95:16 | this access | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:93:17:93:19 | M10 |
| PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | M1 |
| PostDominance.cs:5:10:5:11 | exit M1 | PostDominance.cs:5:10:5:11 | M1 |
| PostDominance.cs:5:10:5:11 | exit M1 (normal) | PostDominance.cs:5:10:5:11 | M1 |
@@ -5793,6 +5841,38 @@ blockEnclosing
| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:74:26:74:27 | M7 |
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:74:26:74:27 | M7 |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:74:26:74:27 | M7 |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:26:85:27 | M8 |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:26:87:27 | M9 |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:93:17:93:19 | M10 |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:93:17:93:19 | M10 |
| PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | M1 |
| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:10:10:10:11 | M2 |
| PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:10:10:10:11 | M2 |

View File

@@ -189,7 +189,6 @@
| AccessorCalls.cs:58:22:58:25 | this access | AccessorCalls.cs:58:22:58:25 | this access |
| AccessorCalls.cs:58:22:58:30 | access to property Prop | AccessorCalls.cs:58:22:58:25 | this access |
| AccessorCalls.cs:58:33:58:44 | (..., ...) | AccessorCalls.cs:58:37:58:40 | this access |
| AccessorCalls.cs:58:34:58:34 | 1 | AccessorCalls.cs:58:34:58:34 | 1 |
| AccessorCalls.cs:58:37:58:40 | this access | AccessorCalls.cs:58:37:58:40 | this access |
| AccessorCalls.cs:58:37:58:43 | access to indexer | AccessorCalls.cs:58:37:58:40 | this access |
| AccessorCalls.cs:58:42:58:42 | 0 | AccessorCalls.cs:58:42:58:42 | 0 |
@@ -660,8 +659,6 @@
| Assert.cs:128:9:128:36 | ...; | Assert.cs:128:9:128:36 | ...; |
| Assert.cs:128:27:128:27 | access to local variable s | Assert.cs:128:27:128:27 | access to local variable s |
| Assert.cs:128:27:128:34 | access to property Length | Assert.cs:128:27:128:27 | access to local variable s |
| Assert.cs:132:61:132:65 | false | Assert.cs:132:61:132:65 | false |
| Assert.cs:133:61:133:64 | true | Assert.cs:133:61:133:64 | true |
| Assert.cs:135:5:136:5 | {...} | Assert.cs:135:5:136:5 | {...} |
| Assert.cs:139:5:142:5 | {...} | Assert.cs:139:5:142:5 | {...} |
| Assert.cs:140:9:140:35 | call to method AssertTrueFalse | Assert.cs:140:9:140:35 | this access |
@@ -1660,9 +1657,7 @@
| Foreach.cs:25:5:28:5 | {...} | Foreach.cs:25:5:28:5 | {...} |
| Foreach.cs:26:9:27:11 | foreach (... ... in ...) ... | Foreach.cs:26:36:26:39 | access to parameter args |
| Foreach.cs:26:18:26:31 | (..., ...) | Foreach.cs:26:23:26:23 | String x |
| Foreach.cs:26:19:26:23 | 1 | Foreach.cs:26:19:26:23 | 1 |
| Foreach.cs:26:23:26:23 | String x | Foreach.cs:26:23:26:23 | String x |
| Foreach.cs:26:26:26:30 | 1 | Foreach.cs:26:26:26:30 | 1 |
| Foreach.cs:26:30:26:30 | Int32 y | Foreach.cs:26:30:26:30 | Int32 y |
| Foreach.cs:26:36:26:39 | access to parameter args | Foreach.cs:26:36:26:39 | access to parameter args |
| Foreach.cs:27:11:27:11 | ; | Foreach.cs:27:11:27:11 | ; |
@@ -2291,6 +2286,37 @@
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ |
| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:13:81:13 | _ |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:18:81:20 | "0" |
| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:39:85:39 | access to parameter i |
| Patterns.cs:85:39:85:53 | ... is ... | Patterns.cs:85:39:85:39 | access to parameter i |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:39 | access to parameter i |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:44 | 1 |
| Patterns.cs:85:44:85:53 | ... or ... | Patterns.cs:85:44:85:44 | 1 |
| Patterns.cs:85:49:85:53 | not ... | Patterns.cs:85:53:85:53 | 2 |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" |
| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:39:87:39 | access to parameter i |
| Patterns.cs:87:39:87:54 | ... is ... | Patterns.cs:87:39:87:39 | access to parameter i |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:39 | access to parameter i |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:44 | 1 |
| Patterns.cs:87:44:87:54 | ... and ... | Patterns.cs:87:44:87:44 | 1 |
| Patterns.cs:87:50:87:54 | not ... | Patterns.cs:87:54:87:54 | 2 |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" |
| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:94:5:99:5 | {...} |
| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:95:9:98:9 | if (...) ... |
| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:13:95:16 | this access |
| Patterns.cs:95:13:95:40 | ... is ... | Patterns.cs:95:13:95:16 | this access |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:31 | access to constant A |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:31 | access to constant A |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:31 | access to constant A |
| Patterns.cs:95:29:95:38 | ... or ... | Patterns.cs:95:29:95:31 | access to constant A |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:96:9:98:9 | {...} |
| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:97:31:97:37 | "not C" |
| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:97:13:97:39 | ...; |
| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:31:97:37 | "not C" |
| PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:6:5:8:5 | {...} |
| PostDominance.cs:7:9:7:28 | call to method WriteLine | PostDominance.cs:7:27:7:27 | access to parameter s |
| PostDominance.cs:7:9:7:29 | ...; | PostDominance.cs:7:9:7:29 | ...; |

View File

@@ -189,7 +189,6 @@
| AccessorCalls.cs:58:22:58:25 | this access | AccessorCalls.cs:58:22:58:25 | this access | normal |
| AccessorCalls.cs:58:22:58:30 | access to property Prop | AccessorCalls.cs:58:22:58:25 | this access | normal |
| AccessorCalls.cs:58:33:58:44 | (..., ...) | AccessorCalls.cs:58:33:58:44 | (..., ...) | normal |
| AccessorCalls.cs:58:34:58:34 | 1 | AccessorCalls.cs:58:34:58:34 | 1 | normal |
| AccessorCalls.cs:58:37:58:40 | this access | AccessorCalls.cs:58:37:58:40 | this access | normal |
| AccessorCalls.cs:58:37:58:43 | access to indexer | AccessorCalls.cs:58:42:58:42 | 0 | normal |
| AccessorCalls.cs:58:42:58:42 | 0 | AccessorCalls.cs:58:42:58:42 | 0 | normal |
@@ -788,8 +787,6 @@
| Assert.cs:128:9:128:36 | ...; | Assert.cs:128:9:128:35 | call to method WriteLine | normal |
| Assert.cs:128:27:128:27 | access to local variable s | Assert.cs:128:27:128:27 | access to local variable s | normal |
| Assert.cs:128:27:128:34 | access to property Length | Assert.cs:128:27:128:34 | access to property Length | normal |
| Assert.cs:132:61:132:65 | false | Assert.cs:132:61:132:65 | false | normal |
| Assert.cs:133:61:133:64 | true | Assert.cs:133:61:133:64 | true | normal |
| Assert.cs:135:5:136:5 | {...} | Assert.cs:135:5:136:5 | {...} | normal |
| Assert.cs:139:5:142:5 | {...} | Assert.cs:140:9:140:35 | call to method AssertTrueFalse | throw(Exception) |
| Assert.cs:139:5:142:5 | {...} | Assert.cs:141:9:141:15 | return ...; | return |
@@ -2298,9 +2295,7 @@
| Foreach.cs:25:5:28:5 | {...} | Foreach.cs:26:9:27:11 | foreach (... ... in ...) ... | empty |
| Foreach.cs:26:9:27:11 | foreach (... ... in ...) ... | Foreach.cs:26:9:27:11 | foreach (... ... in ...) ... | empty |
| Foreach.cs:26:18:26:31 | (..., ...) | Foreach.cs:26:18:26:31 | (..., ...) | normal |
| Foreach.cs:26:19:26:23 | 1 | Foreach.cs:26:19:26:23 | 1 | normal |
| Foreach.cs:26:23:26:23 | String x | Foreach.cs:26:23:26:23 | String x | normal |
| Foreach.cs:26:26:26:30 | 1 | Foreach.cs:26:26:26:30 | 1 | normal |
| Foreach.cs:26:30:26:30 | Int32 y | Foreach.cs:26:30:26:30 | Int32 y | normal |
| Foreach.cs:26:36:26:39 | access to parameter args | Foreach.cs:26:36:26:39 | access to parameter args | normal |
| Foreach.cs:27:11:27:11 | ; | Foreach.cs:27:11:27:11 | ; | normal |
@@ -2997,6 +2992,55 @@
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ | match |
| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:13:81:20 | ... => ... | normal |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:18:81:20 | "0" | normal |
| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:39:85:39 | access to parameter i | normal |
| Patterns.cs:85:39:85:53 | ... is ... | Patterns.cs:85:39:85:53 | ... is ... | false |
| Patterns.cs:85:39:85:53 | ... is ... | Patterns.cs:85:39:85:53 | ... is ... | true |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:69 | ... ? ... : ... | normal |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:44 | 1 | match |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:44 | 1 | no-match |
| Patterns.cs:85:44:85:53 | ... or ... | Patterns.cs:85:44:85:53 | ... or ... | match |
| Patterns.cs:85:44:85:53 | ... or ... | Patterns.cs:85:44:85:53 | ... or ... | no-match |
| Patterns.cs:85:49:85:53 | not ... | Patterns.cs:85:49:85:53 | not ... | match |
| Patterns.cs:85:49:85:53 | not ... | Patterns.cs:85:49:85:53 | not ... | no-match |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | match |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | no-match |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" | normal |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" | normal |
| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:39:87:39 | access to parameter i | normal |
| Patterns.cs:87:39:87:54 | ... is ... | Patterns.cs:87:39:87:54 | ... is ... | false |
| Patterns.cs:87:39:87:54 | ... is ... | Patterns.cs:87:39:87:54 | ... is ... | true |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:70 | ... ? ... : ... | normal |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:44 | 1 | match |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:44 | 1 | no-match |
| Patterns.cs:87:44:87:54 | ... and ... | Patterns.cs:87:44:87:54 | ... and ... | match |
| Patterns.cs:87:44:87:54 | ... and ... | Patterns.cs:87:44:87:54 | ... and ... | no-match |
| Patterns.cs:87:50:87:54 | not ... | Patterns.cs:87:50:87:54 | not ... | match |
| Patterns.cs:87:50:87:54 | not ... | Patterns.cs:87:50:87:54 | not ... | no-match |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | match |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | no-match |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" | normal |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" | normal |
| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:95:13:95:40 | ... is ... | false |
| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:97:13:97:38 | call to method WriteLine | normal |
| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:95:13:95:40 | ... is ... | false |
| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:97:13:97:38 | call to method WriteLine | normal |
| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:13:95:16 | this access | normal |
| Patterns.cs:95:13:95:40 | ... is ... | Patterns.cs:95:13:95:40 | ... is ... | false |
| Patterns.cs:95:13:95:40 | ... is ... | Patterns.cs:95:13:95:40 | ... is ... | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | match |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | match |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | no-match |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | no-match |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:31 | access to constant A | match |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:31 | access to constant A | no-match |
| Patterns.cs:95:29:95:38 | ... or ... | Patterns.cs:95:29:95:38 | ... or ... | match |
| Patterns.cs:95:29:95:38 | ... or ... | Patterns.cs:95:29:95:38 | ... or ... | no-match |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | match |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | no-match |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:97:13:97:38 | call to method WriteLine | normal |
| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:97:13:97:38 | call to method WriteLine | normal |
| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:97:13:97:38 | call to method WriteLine | normal |
| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:31:97:37 | "not C" | normal |
| PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:7:9:7:28 | call to method WriteLine | normal |
| PostDominance.cs:7:9:7:28 | call to method WriteLine | PostDominance.cs:7:9:7:28 | call to method WriteLine | normal |
| PostDominance.cs:7:9:7:29 | ...; | PostDominance.cs:7:9:7:28 | call to method WriteLine | normal |

View File

@@ -3688,6 +3688,59 @@
| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" | semmle.label | match |
| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:76:16:82:9 | ... switch { ... } | semmle.label | successor |
| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:20 | ... => ... | semmle.label | successor |
| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:39 | access to parameter i | semmle.label | successor |
| Patterns.cs:85:26:85:27 | exit M8 (normal) | Patterns.cs:85:26:85:27 | exit M8 | semmle.label | successor |
| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:44:85:44 | 1 | semmle.label | successor |
| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" | semmle.label | false |
| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | semmle.label | true |
| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | exit M8 (normal) | semmle.label | successor |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:53 | [match] ... or ... | semmle.label | match |
| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:53:85:53 | 2 | semmle.label | no-match |
| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:39:85:53 | [true] ... is ... | semmle.label | match |
| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:39:85:53 | [false] ... is ... | semmle.label | no-match |
| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:44:85:53 | [match] ... or ... | semmle.label | match |
| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | semmle.label | no-match |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [match] not ... | semmle.label | no-match |
| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [no-match] not ... | semmle.label | match |
| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:39:85:69 | ... ? ... : ... | semmle.label | successor |
| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:39:85:69 | ... ? ... : ... | semmle.label | successor |
| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:39 | access to parameter i | semmle.label | successor |
| Patterns.cs:87:26:87:27 | exit M9 (normal) | Patterns.cs:87:26:87:27 | exit M9 | semmle.label | successor |
| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:44:87:44 | 1 | semmle.label | successor |
| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" | semmle.label | false |
| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" | semmle.label | true |
| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | exit M9 (normal) | semmle.label | successor |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:54 | [no-match] ... and ... | semmle.label | no-match |
| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:54:87:54 | 2 | semmle.label | match |
| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:39:87:54 | [true] ... is ... | semmle.label | match |
| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:39:87:54 | [false] ... is ... | semmle.label | no-match |
| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:44:87:54 | [match] ... and ... | semmle.label | match |
| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | semmle.label | no-match |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [match] not ... | semmle.label | no-match |
| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [no-match] not ... | semmle.label | match |
| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:39:87:70 | ... ? ... : ... | semmle.label | successor |
| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:39:87:70 | ... ? ... : ... | semmle.label | successor |
| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:94:5:99:5 | {...} | semmle.label | successor |
| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 | semmle.label | successor |
| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:95:9:98:9 | if (...) ... | semmle.label | successor |
| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:95:13:95:16 | this access | semmle.label | successor |
| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:29:95:31 | access to constant A | semmle.label | successor |
| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:93:17:93:19 | exit M10 (normal) | semmle.label | false |
| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} | semmle.label | true |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | semmle.label | no-match |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | semmle.label | match |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | semmle.label | match |
| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | semmle.label | no-match |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:38 | [match] ... or ... | semmle.label | match |
| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:36:95:38 | access to constant B | semmle.label | no-match |
| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:21:95:40 | { ... } | semmle.label | match |
| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:21:95:40 | { ... } | semmle.label | no-match |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [match] ... or ... | semmle.label | match |
| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [no-match] ... or ... | semmle.label | no-match |
| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:97:13:97:39 | ...; | semmle.label | successor |
| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:93:17:93:19 | exit M10 (normal) | semmle.label | successor |
| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:97:31:97:37 | "not C" | semmle.label | successor |
| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:13:97:38 | call to method WriteLine | semmle.label | successor |
| PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:6:5:8:5 | {...} | semmle.label | successor |
| PostDominance.cs:5:10:5:11 | exit M1 (normal) | PostDominance.cs:5:10:5:11 | exit M1 | semmle.label | successor |
| PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:7:9:7:29 | ...; | semmle.label | successor |

View File

@@ -1226,6 +1226,9 @@ entryPoint
| Patterns.cs:56:26:56:27 | M5 | Patterns.cs:57:5:63:5 | {...} |
| Patterns.cs:65:26:65:27 | M6 | Patterns.cs:66:5:72:5 | {...} |
| Patterns.cs:74:26:74:27 | M7 | Patterns.cs:75:5:83:5 | {...} |
| Patterns.cs:85:26:85:27 | M8 | Patterns.cs:85:39:85:39 | access to parameter i |
| Patterns.cs:87:26:87:27 | M9 | Patterns.cs:87:39:87:39 | access to parameter i |
| Patterns.cs:93:17:93:19 | M10 | Patterns.cs:94:5:99:5 | {...} |
| PostDominance.cs:5:10:5:11 | M1 | PostDominance.cs:6:5:8:5 | {...} |
| PostDominance.cs:10:10:10:11 | M2 | PostDominance.cs:11:5:15:5 | {...} |
| PostDominance.cs:17:10:17:11 | M3 | PostDominance.cs:18:5:22:5 | {...} |

View File

@@ -81,4 +81,20 @@ class Patterns
_ => "0"
};
}
public static string M8(int i) => i is 1 or not 2 ? "not 2" : "2";
public static string M9(int i) => i is 1 and not 2 ? "1" : "not 1";
public E Prop { get; set; }
public enum E { A, B, C }
public void M10()
{
if (this is { Prop: E.A or E.B })
{
Console.WriteLine("not C");
}
}
}

View File

@@ -141,7 +141,7 @@ csharp6.cs:
# 57| -1: [TypeMention] Dictionary<Int32, String>
# 57| 1: [TypeMention] int
# 57| 2: [TypeMention] string
# 58| 6: [IndexerProperty] DictionaryProperty
# 58| 6: [Property] DictionaryProperty
# 58| -1: [TypeMention] Dictionary<Int32, String>
# 58| 1: [TypeMention] int
# 58| 2: [TypeMention] string

View File

@@ -74,10 +74,10 @@ AsyncStreams.cs:
# 42| 1: [TypeMention] bool
DefaultInterfaceMethods.cs:
# 3| [Interface] IPerson
# 5| 4: [IndexerProperty] Name
# 5| 4: [Property] Name
# 5| -1: [TypeMention] string
# 5| 3: [Getter] get_Name
# 7| 5: [IndexerProperty] Greeting
# 7| 5: [Property] Greeting
# 7| -1: [TypeMention] string
# 9| 3: [Getter] get_Greeting
# 9| 4: [StringLiteral] "Hello"
@@ -95,7 +95,7 @@ DefaultInterfaceMethods.cs:
# 13| 0: [PropertyCall] access to property Greeting
# 13| 1: [StringLiteral] " "
# 13| 1: [ParameterAccess] access to parameter name
# 15| 7: [IndexerProperty] GreetingString
# 15| 7: [Property] GreetingString
# 15| -1: [TypeMention] string
# 15| 3: [Getter] get_GreetingString
# 15| 4: [MethodCall] call to method Greet
@@ -105,11 +105,11 @@ DefaultInterfaceMethods.cs:
# 20| [Class] Person
#-----| 3: (Base types)
# 20| 1: [TypeMention] IPerson
# 22| 5: [IndexerProperty] Name
# 22| 5: [Property] Name
# 22| -1: [TypeMention] string
# 22| 3: [Getter] get_Name
# 22| 4: [StringLiteral] "Petra"
# 24| 6: [IndexerProperty] Greeting
# 24| 6: [Property] Greeting
# 24| -1: [TypeMention] IPerson
# 24| -1: [TypeMention] string
# 24| 3: [Getter] get_Greeting
@@ -141,11 +141,11 @@ NullableRefTypes.cs:
# 9| -1: [TypeMention] MyClass
# 10| 6: [Field] B
# 10| -1: [TypeMention] MyClass
# 13| 7: [IndexerProperty] C
# 13| 7: [Property] C
# 13| -1: [TypeMention] MyClass
# 13| 3: [Getter] get_C
# 13| 4: [NullLiteral] null
# 14| 8: [IndexerProperty] D
# 14| 8: [Property] D
# 14| -1: [TypeMention] MyClass
# 14| 3: [Getter] get_D
# 14| 4: [ThisAccess] this access
@@ -417,7 +417,7 @@ NullableRefTypes.cs:
# 110| 0: [NullLiteral] null
# 112| 12: [Field] Property
# 112| -1: [TypeMention] MyClass
# 113| 13: [IndexerProperty] RefProperty
# 113| 13: [Property] RefProperty
# 113| -1: [TypeMention] MyClass
# 113| 3: [Getter] get_RefProperty
# 113| 4: [RefExpr] ref ...
@@ -502,7 +502,7 @@ NullableRefTypes.cs:
# 154| [Class] DisabledNullability
# 156| 5: [Field] f1
# 156| -1: [TypeMention] MyClass
# 157| 6: [IndexerProperty] P
# 157| 6: [Property] P
# 157| -1: [TypeMention] MyClass
# 157| 3: [Getter] get_P
# 157| 4: [ObjectCreation] object creation of type MyClass

View File

@@ -26,8 +26,10 @@
| patterns.cs:13:18:13:40 | MyStruct s | patterns.cs:13:32:13:36 | Int32 x | semmle.label | successor |
| patterns.cs:13:18:13:40 | { ... } | patterns.cs:13:13:13:40 | [false] ... is ... | semmle.label | no-match |
| patterns.cs:13:18:13:40 | { ... } | patterns.cs:13:13:13:40 | [true] ... is ... | semmle.label | match |
| patterns.cs:13:27:13:38 | { ... } | patterns.cs:13:18:13:40 | { ... } | semmle.label | successor |
| patterns.cs:13:32:13:36 | Int32 x | patterns.cs:13:27:13:38 | { ... } | semmle.label | successor |
| patterns.cs:13:27:13:38 | { ... } | patterns.cs:13:18:13:40 | { ... } | semmle.label | match |
| patterns.cs:13:27:13:38 | { ... } | patterns.cs:13:18:13:40 | { ... } | semmle.label | no-match |
| patterns.cs:13:32:13:36 | Int32 x | patterns.cs:13:27:13:38 | { ... } | semmle.label | match |
| patterns.cs:13:32:13:36 | Int32 x | patterns.cs:13:27:13:38 | { ... } | semmle.label | no-match |
| patterns.cs:13:45:13:45 | access to local variable x | patterns.cs:13:47:13:47 | 4 | semmle.label | successor |
| patterns.cs:13:45:13:47 | ... < ... | patterns.cs:13:13:13:47 | [false] ... && ... | semmle.label | false |
| patterns.cs:13:45:13:47 | ... < ... | patterns.cs:13:13:13:47 | [true] ... && ... | semmle.label | true |
@@ -42,7 +44,8 @@
| patterns.cs:17:13:17:13 | access to local variable o | patterns.cs:17:18:17:21 | Object p | semmle.label | successor |
| patterns.cs:17:13:17:21 | [false] ... is ... | patterns.cs:22:9:24:9 | if (...) ... | semmle.label | false |
| patterns.cs:17:13:17:21 | [true] ... is ... | patterns.cs:18:9:19:9 | {...} | semmle.label | true |
| patterns.cs:17:18:17:19 | { ... } | patterns.cs:17:18:17:21 | { ... } | semmle.label | successor |
| patterns.cs:17:18:17:19 | { ... } | patterns.cs:17:18:17:21 | { ... } | semmle.label | match |
| patterns.cs:17:18:17:19 | { ... } | patterns.cs:17:18:17:21 | { ... } | semmle.label | no-match |
| patterns.cs:17:18:17:21 | Object p | patterns.cs:17:18:17:19 | { ... } | semmle.label | successor |
| patterns.cs:17:18:17:21 | { ... } | patterns.cs:17:13:17:21 | [false] ... is ... | semmle.label | no-match |
| patterns.cs:17:18:17:21 | { ... } | patterns.cs:17:13:17:21 | [true] ... is ... | semmle.label | match |
@@ -53,11 +56,16 @@
| patterns.cs:22:13:22:53 | [true] ... is ... | patterns.cs:23:9:24:9 | {...} | semmle.label | true |
| patterns.cs:22:18:22:53 | { ... } | patterns.cs:22:13:22:53 | [false] ... is ... | semmle.label | no-match |
| patterns.cs:22:18:22:53 | { ... } | patterns.cs:22:13:22:53 | [true] ... is ... | semmle.label | match |
| patterns.cs:22:27:22:53 | { ... } | patterns.cs:22:18:22:53 | { ... } | semmle.label | successor |
| patterns.cs:22:31:22:32 | 12 | patterns.cs:22:42:22:49 | Int32 subX | semmle.label | successor |
| patterns.cs:22:38:22:51 | { ... } | patterns.cs:22:27:22:53 | { ... } | semmle.label | successor |
| patterns.cs:22:38:22:51 | { ... } | patterns.cs:22:38:22:51 | { ... } | semmle.label | successor |
| patterns.cs:22:42:22:49 | Int32 subX | patterns.cs:22:38:22:51 | { ... } | semmle.label | successor |
| patterns.cs:22:27:22:53 | { ... } | patterns.cs:22:18:22:53 | { ... } | semmle.label | match |
| patterns.cs:22:27:22:53 | { ... } | patterns.cs:22:18:22:53 | { ... } | semmle.label | no-match |
| patterns.cs:22:31:22:32 | 12 | patterns.cs:22:42:22:49 | Int32 subX | semmle.label | match |
| patterns.cs:22:31:22:32 | 12 | patterns.cs:22:42:22:49 | Int32 subX | semmle.label | no-match |
| patterns.cs:22:38:22:51 | { ... } | patterns.cs:22:27:22:53 | { ... } | semmle.label | match |
| patterns.cs:22:38:22:51 | { ... } | patterns.cs:22:27:22:53 | { ... } | semmle.label | no-match |
| patterns.cs:22:38:22:51 | { ... } | patterns.cs:22:38:22:51 | { ... } | semmle.label | match |
| patterns.cs:22:38:22:51 | { ... } | patterns.cs:22:38:22:51 | { ... } | semmle.label | no-match |
| patterns.cs:22:42:22:49 | Int32 subX | patterns.cs:22:38:22:51 | { ... } | semmle.label | match |
| patterns.cs:22:42:22:49 | Int32 subX | patterns.cs:22:38:22:51 | { ... } | semmle.label | no-match |
| patterns.cs:23:9:24:9 | {...} | patterns.cs:27:9:29:9 | if (...) ... | semmle.label | successor |
| patterns.cs:27:9:29:9 | if (...) ... | patterns.cs:27:13:27:13 | access to local variable o | semmle.label | successor |
| patterns.cs:27:13:27:13 | access to local variable o | patterns.cs:27:31:27:32 | 12 | semmle.label | successor |
@@ -65,10 +73,14 @@
| patterns.cs:27:13:27:58 | [true] ... is ... | patterns.cs:28:9:29:9 | {...} | semmle.label | true |
| patterns.cs:27:18:27:58 | { ... } | patterns.cs:27:13:27:58 | [false] ... is ... | semmle.label | no-match |
| patterns.cs:27:18:27:58 | { ... } | patterns.cs:27:13:27:58 | [true] ... is ... | semmle.label | match |
| patterns.cs:27:27:27:58 | { ... } | patterns.cs:27:18:27:58 | { ... } | semmle.label | successor |
| patterns.cs:27:31:27:32 | 12 | patterns.cs:27:38:27:56 | MyStruct ms | semmle.label | successor |
| patterns.cs:27:27:27:58 | { ... } | patterns.cs:27:18:27:58 | { ... } | semmle.label | match |
| patterns.cs:27:27:27:58 | { ... } | patterns.cs:27:18:27:58 | { ... } | semmle.label | no-match |
| patterns.cs:27:31:27:32 | 12 | patterns.cs:27:38:27:56 | MyStruct ms | semmle.label | match |
| patterns.cs:27:31:27:32 | 12 | patterns.cs:27:38:27:56 | MyStruct ms | semmle.label | no-match |
| patterns.cs:27:38:27:56 | MyStruct ms | patterns.cs:27:51:27:51 | _ | semmle.label | successor |
| patterns.cs:27:38:27:56 | { ... } | patterns.cs:27:27:27:58 | { ... } | semmle.label | successor |
| patterns.cs:27:47:27:53 | { ... } | patterns.cs:27:38:27:56 | { ... } | semmle.label | successor |
| patterns.cs:27:51:27:51 | _ | patterns.cs:27:47:27:53 | { ... } | semmle.label | successor |
| patterns.cs:27:38:27:56 | { ... } | patterns.cs:27:27:27:58 | { ... } | semmle.label | match |
| patterns.cs:27:38:27:56 | { ... } | patterns.cs:27:27:27:58 | { ... } | semmle.label | no-match |
| patterns.cs:27:47:27:53 | { ... } | patterns.cs:27:38:27:56 | { ... } | semmle.label | match |
| patterns.cs:27:47:27:53 | { ... } | patterns.cs:27:38:27:56 | { ... } | semmle.label | no-match |
| patterns.cs:27:51:27:51 | _ | patterns.cs:27:47:27:53 | { ... } | semmle.label | match |
| patterns.cs:28:9:29:9 | {...} | patterns.cs:5:10:5:19 | exit IsPatterns (normal) | semmle.label | successor |

View File

@@ -31,21 +31,27 @@
| patterns.cs:108:24:112:9 | ... switch { ... } | patterns.cs:108:9:112:9 | ... = ... | semmle.label | successor |
| patterns.cs:108:25:108:26 | access to local variable x0 | patterns.cs:108:29:108:30 | access to local variable y0 | semmle.label | successor |
| patterns.cs:108:29:108:30 | access to local variable y0 | patterns.cs:108:24:108:31 | (..., ...) | semmle.label | successor |
| patterns.cs:110:13:110:17 | ( ... ) | patterns.cs:110:13:110:17 | { ... } | semmle.label | successor |
| patterns.cs:110:13:110:17 | ( ... ) | patterns.cs:110:13:110:17 | { ... } | semmle.label | match |
| patterns.cs:110:13:110:17 | ( ... ) | patterns.cs:110:13:110:17 | { ... } | semmle.label | no-match |
| patterns.cs:110:13:110:17 | { ... } | patterns.cs:110:23:110:23 | 1 | semmle.label | match |
| patterns.cs:110:13:110:17 | { ... } | patterns.cs:111:14:111:14 | 1 | semmle.label | no-match |
| patterns.cs:110:13:110:26 | ... => ... | patterns.cs:108:24:112:9 | ... switch { ... } | semmle.label | successor |
| patterns.cs:110:14:110:14 | 0 | patterns.cs:110:16:110:16 | 1 | semmle.label | successor |
| patterns.cs:110:16:110:16 | 1 | patterns.cs:110:13:110:17 | ( ... ) | semmle.label | successor |
| patterns.cs:110:14:110:14 | 0 | patterns.cs:110:16:110:16 | 1 | semmle.label | match |
| patterns.cs:110:14:110:14 | 0 | patterns.cs:110:16:110:16 | 1 | semmle.label | no-match |
| patterns.cs:110:16:110:16 | 1 | patterns.cs:110:13:110:17 | ( ... ) | semmle.label | match |
| patterns.cs:110:16:110:16 | 1 | patterns.cs:110:13:110:17 | ( ... ) | semmle.label | no-match |
| patterns.cs:110:22:110:26 | (..., ...) | patterns.cs:110:13:110:26 | ... => ... | semmle.label | successor |
| patterns.cs:110:23:110:23 | 1 | patterns.cs:110:25:110:25 | 0 | semmle.label | successor |
| patterns.cs:110:25:110:25 | 0 | patterns.cs:110:22:110:26 | (..., ...) | semmle.label | successor |
| patterns.cs:111:13:111:17 | ( ... ) | patterns.cs:111:13:111:17 | { ... } | semmle.label | successor |
| patterns.cs:111:13:111:17 | ( ... ) | patterns.cs:111:13:111:17 | { ... } | semmle.label | match |
| patterns.cs:111:13:111:17 | ( ... ) | patterns.cs:111:13:111:17 | { ... } | semmle.label | no-match |
| patterns.cs:111:13:111:17 | { ... } | patterns.cs:98:10:98:20 | exit Expressions (abnormal) | semmle.label | exception(InvalidOperationException) |
| patterns.cs:111:13:111:17 | { ... } | patterns.cs:111:23:111:23 | 0 | semmle.label | match |
| patterns.cs:111:13:111:26 | ... => ... | patterns.cs:108:24:112:9 | ... switch { ... } | semmle.label | successor |
| patterns.cs:111:14:111:14 | 1 | patterns.cs:111:16:111:16 | 0 | semmle.label | successor |
| patterns.cs:111:16:111:16 | 0 | patterns.cs:111:13:111:17 | ( ... ) | semmle.label | successor |
| patterns.cs:111:14:111:14 | 1 | patterns.cs:111:16:111:16 | 0 | semmle.label | match |
| patterns.cs:111:14:111:14 | 1 | patterns.cs:111:16:111:16 | 0 | semmle.label | no-match |
| patterns.cs:111:16:111:16 | 0 | patterns.cs:111:13:111:17 | ( ... ) | semmle.label | match |
| patterns.cs:111:16:111:16 | 0 | patterns.cs:111:13:111:17 | ( ... ) | semmle.label | no-match |
| patterns.cs:111:22:111:26 | (..., ...) | patterns.cs:111:13:111:26 | ... => ... | semmle.label | successor |
| patterns.cs:111:23:111:23 | 0 | patterns.cs:111:25:111:25 | 1 | semmle.label | successor |
| patterns.cs:111:25:111:25 | 1 | patterns.cs:111:22:111:26 | (..., ...) | semmle.label | successor |
@@ -56,30 +62,35 @@
| patterns.cs:115:20:120:9 | ... switch { ... } | patterns.cs:115:9:120:9 | ... = ... | semmle.label | successor |
| patterns.cs:115:21:115:22 | access to local variable x0 | patterns.cs:115:25:115:26 | access to local variable y0 | semmle.label | successor |
| patterns.cs:115:25:115:26 | access to local variable y0 | patterns.cs:115:20:115:27 | (..., ...) | semmle.label | successor |
| patterns.cs:117:13:117:22 | ( ... ) | patterns.cs:117:13:117:22 | { ... } | semmle.label | successor |
| patterns.cs:117:13:117:22 | ( ... ) | patterns.cs:117:13:117:22 | { ... } | semmle.label | match |
| patterns.cs:117:13:117:22 | ( ... ) | patterns.cs:117:13:117:22 | { ... } | semmle.label | no-match |
| patterns.cs:117:13:117:22 | { ... } | patterns.cs:117:28:117:29 | access to local variable y2 | semmle.label | match |
| patterns.cs:117:13:117:22 | { ... } | patterns.cs:118:14:118:19 | Int32 x2 | semmle.label | no-match |
| patterns.cs:117:13:117:33 | ... => ... | patterns.cs:115:20:120:9 | ... switch { ... } | semmle.label | successor |
| patterns.cs:117:14:117:14 | 0 | patterns.cs:117:16:117:21 | Int32 y2 | semmle.label | successor |
| patterns.cs:117:16:117:21 | Int32 y2 | patterns.cs:117:13:117:22 | ( ... ) | semmle.label | successor |
| patterns.cs:117:14:117:14 | 0 | patterns.cs:117:16:117:21 | Int32 y2 | semmle.label | match |
| patterns.cs:117:14:117:14 | 0 | patterns.cs:117:16:117:21 | Int32 y2 | semmle.label | no-match |
| patterns.cs:117:16:117:21 | Int32 y2 | patterns.cs:117:13:117:22 | ( ... ) | semmle.label | no-match |
| patterns.cs:117:27:117:33 | (..., ...) | patterns.cs:117:13:117:33 | ... => ... | semmle.label | successor |
| patterns.cs:117:28:117:29 | access to local variable y2 | patterns.cs:117:32:117:32 | 0 | semmle.label | successor |
| patterns.cs:117:32:117:32 | 0 | patterns.cs:117:27:117:33 | (..., ...) | semmle.label | successor |
| patterns.cs:118:13:118:23 | ( ... ) | patterns.cs:118:13:118:23 | { ... } | semmle.label | successor |
| patterns.cs:118:13:118:23 | ( ... ) | patterns.cs:118:13:118:23 | { ... } | semmle.label | match |
| patterns.cs:118:13:118:23 | ( ... ) | patterns.cs:118:13:118:23 | { ... } | semmle.label | no-match |
| patterns.cs:118:13:118:23 | { ... } | patterns.cs:118:29:118:29 | 0 | semmle.label | match |
| patterns.cs:118:13:118:23 | { ... } | patterns.cs:119:14:119:19 | Int32 x2 | semmle.label | no-match |
| patterns.cs:118:13:118:34 | ... => ... | patterns.cs:115:20:120:9 | ... switch { ... } | semmle.label | successor |
| patterns.cs:118:14:118:19 | Int32 x2 | patterns.cs:118:22:118:22 | 0 | semmle.label | successor |
| patterns.cs:118:22:118:22 | 0 | patterns.cs:118:13:118:23 | ( ... ) | semmle.label | successor |
| patterns.cs:118:14:118:19 | Int32 x2 | patterns.cs:118:22:118:22 | 0 | semmle.label | no-match |
| patterns.cs:118:22:118:22 | 0 | patterns.cs:118:13:118:23 | ( ... ) | semmle.label | match |
| patterns.cs:118:22:118:22 | 0 | patterns.cs:118:13:118:23 | ( ... ) | semmle.label | no-match |
| patterns.cs:118:28:118:34 | (..., ...) | patterns.cs:118:13:118:34 | ... => ... | semmle.label | successor |
| patterns.cs:118:29:118:29 | 0 | patterns.cs:118:32:118:33 | access to local variable x2 | semmle.label | successor |
| patterns.cs:118:32:118:33 | access to local variable x2 | patterns.cs:118:28:118:34 | (..., ...) | semmle.label | successor |
| patterns.cs:119:13:119:28 | ( ... ) | patterns.cs:119:13:119:28 | { ... } | semmle.label | successor |
| patterns.cs:119:13:119:28 | ( ... ) | patterns.cs:119:13:119:28 | { ... } | semmle.label | match |
| patterns.cs:119:13:119:28 | ( ... ) | patterns.cs:119:13:119:28 | { ... } | semmle.label | no-match |
| patterns.cs:119:13:119:28 | { ... } | patterns.cs:98:10:98:20 | exit Expressions (abnormal) | semmle.label | exception(InvalidOperationException) |
| patterns.cs:119:13:119:28 | { ... } | patterns.cs:119:34:119:34 | 0 | semmle.label | match |
| patterns.cs:119:13:119:38 | ... => ... | patterns.cs:115:20:120:9 | ... switch { ... } | semmle.label | successor |
| patterns.cs:119:14:119:19 | Int32 x2 | patterns.cs:119:22:119:27 | Int32 y2 | semmle.label | successor |
| patterns.cs:119:22:119:27 | Int32 y2 | patterns.cs:119:13:119:28 | ( ... ) | semmle.label | successor |
| patterns.cs:119:14:119:19 | Int32 x2 | patterns.cs:119:22:119:27 | Int32 y2 | semmle.label | no-match |
| patterns.cs:119:22:119:27 | Int32 y2 | patterns.cs:119:13:119:28 | ( ... ) | semmle.label | no-match |
| patterns.cs:119:33:119:38 | (..., ...) | patterns.cs:119:13:119:38 | ... => ... | semmle.label | successor |
| patterns.cs:119:34:119:34 | 0 | patterns.cs:119:37:119:37 | 0 | semmle.label | successor |
| patterns.cs:119:37:119:37 | 0 | patterns.cs:119:33:119:38 | (..., ...) | semmle.label | successor |
@@ -100,8 +111,9 @@
| patterns.cs:128:13:128:33 | { ... } | patterns.cs:128:40:128:40 | access to local variable x | semmle.label | match |
| patterns.cs:128:13:128:33 | { ... } | patterns.cs:129:13:129:33 | MyStruct ms | semmle.label | no-match |
| patterns.cs:128:13:128:49 | ... => ... | patterns.cs:126:17:132:9 | ... switch { ... } | semmle.label | successor |
| patterns.cs:128:22:128:33 | { ... } | patterns.cs:128:13:128:33 | { ... } | semmle.label | successor |
| patterns.cs:128:27:128:31 | Int32 x | patterns.cs:128:22:128:33 | { ... } | semmle.label | successor |
| patterns.cs:128:22:128:33 | { ... } | patterns.cs:128:13:128:33 | { ... } | semmle.label | match |
| patterns.cs:128:22:128:33 | { ... } | patterns.cs:128:13:128:33 | { ... } | semmle.label | no-match |
| patterns.cs:128:27:128:31 | Int32 x | patterns.cs:128:22:128:33 | { ... } | semmle.label | no-match |
| patterns.cs:128:40:128:40 | access to local variable x | patterns.cs:128:44:128:44 | 2 | semmle.label | successor |
| patterns.cs:128:40:128:44 | ... > ... | patterns.cs:128:49:128:49 | 0 | semmle.label | true |
| patterns.cs:128:40:128:44 | ... > ... | patterns.cs:129:13:129:33 | MyStruct ms | semmle.label | false |
@@ -111,15 +123,20 @@
| patterns.cs:129:13:129:33 | { ... } | patterns.cs:129:38:129:38 | 1 | semmle.label | match |
| patterns.cs:129:13:129:33 | { ... } | patterns.cs:130:14:130:14 | 1 | semmle.label | no-match |
| patterns.cs:129:13:129:38 | ... => ... | patterns.cs:126:17:132:9 | ... switch { ... } | semmle.label | successor |
| patterns.cs:129:22:129:30 | { ... } | patterns.cs:129:13:129:33 | { ... } | semmle.label | successor |
| patterns.cs:129:27:129:28 | 10 | patterns.cs:129:22:129:30 | { ... } | semmle.label | successor |
| patterns.cs:129:22:129:30 | { ... } | patterns.cs:129:13:129:33 | { ... } | semmle.label | match |
| patterns.cs:129:22:129:30 | { ... } | patterns.cs:129:13:129:33 | { ... } | semmle.label | no-match |
| patterns.cs:129:27:129:28 | 10 | patterns.cs:129:22:129:30 | { ... } | semmle.label | match |
| patterns.cs:129:27:129:28 | 10 | patterns.cs:129:22:129:30 | { ... } | semmle.label | no-match |
| patterns.cs:129:38:129:38 | 1 | patterns.cs:129:13:129:38 | ... => ... | semmle.label | successor |
| patterns.cs:130:13:130:18 | ( ... ) | patterns.cs:130:13:130:18 | { ... } | semmle.label | successor |
| patterns.cs:130:13:130:18 | ( ... ) | patterns.cs:130:13:130:18 | { ... } | semmle.label | match |
| patterns.cs:130:13:130:18 | ( ... ) | patterns.cs:130:13:130:18 | { ... } | semmle.label | no-match |
| patterns.cs:130:13:130:18 | { ... } | patterns.cs:130:23:130:23 | 2 | semmle.label | match |
| patterns.cs:130:13:130:18 | { ... } | patterns.cs:131:18:131:18 | Int32 x | semmle.label | no-match |
| patterns.cs:130:13:130:23 | ... => ... | patterns.cs:126:17:132:9 | ... switch { ... } | semmle.label | successor |
| patterns.cs:130:14:130:14 | 1 | patterns.cs:130:17:130:17 | 2 | semmle.label | successor |
| patterns.cs:130:17:130:17 | 2 | patterns.cs:130:13:130:18 | ( ... ) | semmle.label | successor |
| patterns.cs:130:14:130:14 | 1 | patterns.cs:130:17:130:17 | 2 | semmle.label | match |
| patterns.cs:130:14:130:14 | 1 | patterns.cs:130:17:130:17 | 2 | semmle.label | no-match |
| patterns.cs:130:17:130:17 | 2 | patterns.cs:130:13:130:18 | ( ... ) | semmle.label | match |
| patterns.cs:130:17:130:17 | 2 | patterns.cs:130:13:130:18 | ( ... ) | semmle.label | no-match |
| patterns.cs:130:23:130:23 | 2 | patterns.cs:130:13:130:23 | ... => ... | semmle.label | successor |
| patterns.cs:131:13:131:22 | (..., ...) | patterns.cs:123:10:123:21 | exit Expressions2 (abnormal) | semmle.label | exception(InvalidOperationException) |
| patterns.cs:131:13:131:22 | (..., ...) | patterns.cs:131:27:131:27 | 3 | semmle.label | match |
@@ -150,7 +167,8 @@
| patterns.cs:140:31:140:37 | [true] ... is ... | patterns.cs:140:42:140:42 | 4 | semmle.label | true |
| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:31:140:37 | [false] ... is ... | semmle.label | no-match |
| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:31:140:37 | [true] ... is ... | semmle.label | match |
| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:36:140:37 | { ... } | semmle.label | successor |
| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:36:140:37 | { ... } | semmle.label | match |
| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:36:140:37 | { ... } | semmle.label | no-match |
| patterns.cs:140:42:140:42 | 4 | patterns.cs:140:17:140:42 | ... => ... | semmle.label | successor |
| patterns.cs:141:17:141:22 | access to type String | patterns.cs:141:29:141:29 | 5 | semmle.label | match |
| patterns.cs:141:17:141:22 | access to type String | patterns.cs:142:31:142:32 | 10 | semmle.label | no-match |
@@ -159,8 +177,10 @@
| patterns.cs:142:17:142:36 | { ... } | patterns.cs:142:41:142:41 | 6 | semmle.label | match |
| patterns.cs:142:17:142:36 | { ... } | patterns.cs:145:9:148:9 | [exception: InvalidOperationException] catch (...) {...} | semmle.label | exception(InvalidOperationException) |
| patterns.cs:142:17:142:41 | ... => ... | patterns.cs:136:17:143:13 | ... switch { ... } | semmle.label | successor |
| patterns.cs:142:26:142:34 | { ... } | patterns.cs:142:17:142:36 | { ... } | semmle.label | successor |
| patterns.cs:142:31:142:32 | 10 | patterns.cs:142:26:142:34 | { ... } | semmle.label | successor |
| patterns.cs:142:26:142:34 | { ... } | patterns.cs:142:17:142:36 | { ... } | semmle.label | match |
| patterns.cs:142:26:142:34 | { ... } | patterns.cs:142:17:142:36 | { ... } | semmle.label | no-match |
| patterns.cs:142:31:142:32 | 10 | patterns.cs:142:26:142:34 | { ... } | semmle.label | match |
| patterns.cs:142:31:142:32 | 10 | patterns.cs:142:26:142:34 | { ... } | semmle.label | no-match |
| patterns.cs:142:41:142:41 | 6 | patterns.cs:142:17:142:41 | ... => ... | semmle.label | successor |
| patterns.cs:145:9:148:9 | [exception: ArgumentException] catch (...) {...} | patterns.cs:123:10:123:21 | exit Expressions2 (abnormal) | semmle.label | exception(ArgumentException) |
| patterns.cs:145:9:148:9 | [exception: Exception] catch (...) {...} | patterns.cs:123:10:123:21 | exit Expressions2 (abnormal) | semmle.label | exception(Exception) |

View File

@@ -38,8 +38,9 @@
| patterns.cs:48:13:48:50 | case ...: | patterns.cs:48:32:48:36 | Int32 x | semmle.label | successor |
| patterns.cs:48:18:48:38 | { ... } | patterns.cs:48:45:48:45 | access to local variable x | semmle.label | match |
| patterns.cs:48:18:48:38 | { ... } | patterns.cs:51:13:51:39 | case ...: | semmle.label | no-match |
| patterns.cs:48:27:48:38 | { ... } | patterns.cs:48:18:48:38 | { ... } | semmle.label | successor |
| patterns.cs:48:32:48:36 | Int32 x | patterns.cs:48:27:48:38 | { ... } | semmle.label | successor |
| patterns.cs:48:27:48:38 | { ... } | patterns.cs:48:18:48:38 | { ... } | semmle.label | match |
| patterns.cs:48:27:48:38 | { ... } | patterns.cs:48:18:48:38 | { ... } | semmle.label | no-match |
| patterns.cs:48:32:48:36 | Int32 x | patterns.cs:48:27:48:38 | { ... } | semmle.label | no-match |
| patterns.cs:48:45:48:45 | access to local variable x | patterns.cs:48:49:48:49 | 2 | semmle.label | successor |
| patterns.cs:48:45:48:49 | ... > ... | patterns.cs:49:17:49:37 | ...; | semmle.label | true |
| patterns.cs:48:45:48:49 | ... > ... | patterns.cs:51:13:51:39 | case ...: | semmle.label | false |
@@ -52,17 +53,20 @@
| patterns.cs:51:18:51:38 | MyStruct ms | patterns.cs:51:32:51:33 | 10 | semmle.label | successor |
| patterns.cs:51:18:51:38 | { ... } | patterns.cs:52:17:52:56 | ...; | semmle.label | match |
| patterns.cs:51:18:51:38 | { ... } | patterns.cs:54:13:54:43 | case ...: | semmle.label | no-match |
| patterns.cs:51:27:51:35 | { ... } | patterns.cs:51:18:51:38 | { ... } | semmle.label | successor |
| patterns.cs:51:32:51:33 | 10 | patterns.cs:51:27:51:35 | { ... } | semmle.label | successor |
| patterns.cs:51:27:51:35 | { ... } | patterns.cs:51:18:51:38 | { ... } | semmle.label | match |
| patterns.cs:51:27:51:35 | { ... } | patterns.cs:51:18:51:38 | { ... } | semmle.label | no-match |
| patterns.cs:51:32:51:33 | 10 | patterns.cs:51:27:51:35 | { ... } | semmle.label | match |
| patterns.cs:51:32:51:33 | 10 | patterns.cs:51:27:51:35 | { ... } | semmle.label | no-match |
| patterns.cs:52:17:52:55 | call to method WriteLine | patterns.cs:53:17:53:22 | break; | semmle.label | successor |
| patterns.cs:52:17:52:56 | ...; | patterns.cs:52:35:52:54 | "Hit the breakpoint" | semmle.label | successor |
| patterns.cs:52:35:52:54 | "Hit the breakpoint" | patterns.cs:52:17:52:55 | call to method WriteLine | semmle.label | successor |
| patterns.cs:53:17:53:22 | break; | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | break |
| patterns.cs:54:13:54:43 | case ...: | patterns.cs:54:23:54:28 | Int32 x2 | semmle.label | successor |
| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:18:54:30 | { ... } | semmle.label | successor |
| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:18:54:30 | { ... } | semmle.label | match |
| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:18:54:30 | { ... } | semmle.label | no-match |
| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:37:54:38 | access to local variable x2 | semmle.label | match |
| patterns.cs:54:18:54:30 | { ... } | patterns.cs:57:13:57:24 | case ...: | semmle.label | no-match |
| patterns.cs:54:23:54:28 | Int32 x2 | patterns.cs:54:18:54:30 | { ... } | semmle.label | successor |
| patterns.cs:54:23:54:28 | Int32 x2 | patterns.cs:54:18:54:30 | { ... } | semmle.label | no-match |
| patterns.cs:54:37:54:38 | access to local variable x2 | patterns.cs:54:42:54:42 | 2 | semmle.label | successor |
| patterns.cs:54:37:54:42 | ... > ... | patterns.cs:55:17:55:38 | ...; | semmle.label | true |
| patterns.cs:54:37:54:42 | ... > ... | patterns.cs:57:13:57:24 | case ...: | semmle.label | false |
@@ -72,11 +76,14 @@
| patterns.cs:55:35:55:36 | access to local variable x2 | patterns.cs:55:17:55:37 | call to method WriteLine | semmle.label | successor |
| patterns.cs:56:17:56:22 | break; | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | break |
| patterns.cs:57:13:57:24 | case ...: | patterns.cs:57:19:57:19 | 1 | semmle.label | successor |
| patterns.cs:57:18:57:23 | ( ... ) | patterns.cs:57:18:57:23 | { ... } | semmle.label | successor |
| patterns.cs:57:18:57:23 | ( ... ) | patterns.cs:57:18:57:23 | { ... } | semmle.label | match |
| patterns.cs:57:18:57:23 | ( ... ) | patterns.cs:57:18:57:23 | { ... } | semmle.label | no-match |
| patterns.cs:57:18:57:23 | { ... } | patterns.cs:58:17:58:22 | break; | semmle.label | match |
| patterns.cs:57:18:57:23 | { ... } | patterns.cs:59:13:59:28 | case ...: | semmle.label | no-match |
| patterns.cs:57:19:57:19 | 1 | patterns.cs:57:22:57:22 | 2 | semmle.label | successor |
| patterns.cs:57:22:57:22 | 2 | patterns.cs:57:18:57:23 | ( ... ) | semmle.label | successor |
| patterns.cs:57:19:57:19 | 1 | patterns.cs:57:22:57:22 | 2 | semmle.label | match |
| patterns.cs:57:19:57:19 | 1 | patterns.cs:57:22:57:22 | 2 | semmle.label | no-match |
| patterns.cs:57:22:57:22 | 2 | patterns.cs:57:18:57:23 | ( ... ) | semmle.label | match |
| patterns.cs:57:22:57:22 | 2 | patterns.cs:57:18:57:23 | ( ... ) | semmle.label | no-match |
| patterns.cs:58:17:58:22 | break; | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | break |
| patterns.cs:59:13:59:28 | case ...: | patterns.cs:59:23:59:23 | Int32 x | semmle.label | successor |
| patterns.cs:59:18:59:27 | (..., ...) | patterns.cs:60:17:60:22 | break; | semmle.label | match |
@@ -91,8 +98,9 @@
| patterns.cs:67:13:67:50 | case ...: | patterns.cs:67:32:67:36 | Int32 x | semmle.label | successor |
| patterns.cs:67:18:67:38 | { ... } | patterns.cs:67:45:67:45 | access to local variable x | semmle.label | match |
| patterns.cs:67:18:67:38 | { ... } | patterns.cs:70:13:70:51 | case ...: | semmle.label | no-match |
| patterns.cs:67:27:67:38 | { ... } | patterns.cs:67:18:67:38 | { ... } | semmle.label | successor |
| patterns.cs:67:32:67:36 | Int32 x | patterns.cs:67:27:67:38 | { ... } | semmle.label | successor |
| patterns.cs:67:27:67:38 | { ... } | patterns.cs:67:18:67:38 | { ... } | semmle.label | match |
| patterns.cs:67:27:67:38 | { ... } | patterns.cs:67:18:67:38 | { ... } | semmle.label | no-match |
| patterns.cs:67:32:67:36 | Int32 x | patterns.cs:67:27:67:38 | { ... } | semmle.label | no-match |
| patterns.cs:67:45:67:45 | access to local variable x | patterns.cs:67:49:67:49 | 2 | semmle.label | successor |
| patterns.cs:67:45:67:49 | ... > ... | patterns.cs:68:17:68:37 | ...; | semmle.label | true |
| patterns.cs:67:45:67:49 | ... > ... | patterns.cs:70:13:70:51 | case ...: | semmle.label | false |
@@ -105,8 +113,10 @@
| patterns.cs:70:18:70:38 | MyStruct ms | patterns.cs:70:32:70:33 | 10 | semmle.label | successor |
| patterns.cs:70:18:70:38 | { ... } | patterns.cs:70:45:70:45 | access to local variable s | semmle.label | match |
| patterns.cs:70:18:70:38 | { ... } | patterns.cs:76:9:84:9 | switch (...) {...} | semmle.label | no-match |
| patterns.cs:70:27:70:35 | { ... } | patterns.cs:70:18:70:38 | { ... } | semmle.label | successor |
| patterns.cs:70:32:70:33 | 10 | patterns.cs:70:27:70:35 | { ... } | semmle.label | successor |
| patterns.cs:70:27:70:35 | { ... } | patterns.cs:70:18:70:38 | { ... } | semmle.label | match |
| patterns.cs:70:27:70:35 | { ... } | patterns.cs:70:18:70:38 | { ... } | semmle.label | no-match |
| patterns.cs:70:32:70:33 | 10 | patterns.cs:70:27:70:35 | { ... } | semmle.label | match |
| patterns.cs:70:32:70:33 | 10 | patterns.cs:70:27:70:35 | { ... } | semmle.label | no-match |
| patterns.cs:70:45:70:45 | access to local variable s | patterns.cs:70:45:70:47 | access to field X | semmle.label | successor |
| patterns.cs:70:45:70:47 | access to field X | patterns.cs:70:50:70:50 | 0 | semmle.label | successor |
| patterns.cs:70:45:70:50 | ... == ... | patterns.cs:71:17:71:56 | ...; | semmle.label | true |
@@ -119,11 +129,14 @@
| patterns.cs:76:9:84:9 | switch (...) {...} | patterns.cs:76:17:76:28 | object creation of type Object | semmle.label | successor |
| patterns.cs:76:17:76:28 | object creation of type Object | patterns.cs:78:13:78:43 | case ...: | semmle.label | successor |
| patterns.cs:78:13:78:43 | case ...: | patterns.cs:78:19:78:23 | Int32 x | semmle.label | successor |
| patterns.cs:78:18:78:33 | ( ... ) | patterns.cs:78:18:78:33 | { ... } | semmle.label | successor |
| patterns.cs:78:18:78:33 | ( ... ) | patterns.cs:78:18:78:33 | { ... } | semmle.label | match |
| patterns.cs:78:18:78:33 | ( ... ) | patterns.cs:78:18:78:33 | { ... } | semmle.label | no-match |
| patterns.cs:78:18:78:33 | { ... } | patterns.cs:78:40:78:40 | access to local variable x | semmle.label | match |
| patterns.cs:78:18:78:33 | { ... } | patterns.cs:80:13:80:20 | case ...: | semmle.label | no-match |
| patterns.cs:78:19:78:23 | Int32 x | patterns.cs:78:26:78:32 | Single y | semmle.label | successor |
| patterns.cs:78:26:78:32 | Single y | patterns.cs:78:18:78:33 | ( ... ) | semmle.label | successor |
| patterns.cs:78:19:78:23 | Int32 x | patterns.cs:78:26:78:32 | Single y | semmle.label | match |
| patterns.cs:78:19:78:23 | Int32 x | patterns.cs:78:26:78:32 | Single y | semmle.label | no-match |
| patterns.cs:78:26:78:32 | Single y | patterns.cs:78:18:78:33 | ( ... ) | semmle.label | match |
| patterns.cs:78:26:78:32 | Single y | patterns.cs:78:18:78:33 | ( ... ) | semmle.label | no-match |
| patterns.cs:78:40:78:40 | (...) ... | patterns.cs:78:42:78:42 | access to local variable y | semmle.label | successor |
| patterns.cs:78:40:78:40 | access to local variable x | patterns.cs:78:40:78:40 | (...) ... | semmle.label | successor |
| patterns.cs:78:40:78:42 | ... < ... | patterns.cs:79:17:79:22 | break; | semmle.label | true |
@@ -131,12 +144,14 @@
| patterns.cs:78:42:78:42 | access to local variable y | patterns.cs:78:40:78:42 | ... < ... | semmle.label | successor |
| patterns.cs:79:17:79:22 | break; | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | break |
| patterns.cs:80:13:80:20 | case ...: | patterns.cs:80:18:80:19 | ( ... ) | semmle.label | successor |
| patterns.cs:80:18:80:19 | ( ... ) | patterns.cs:80:18:80:19 | { ... } | semmle.label | successor |
| patterns.cs:80:18:80:19 | ( ... ) | patterns.cs:80:18:80:19 | { ... } | semmle.label | match |
| patterns.cs:80:18:80:19 | ( ... ) | patterns.cs:80:18:80:19 | { ... } | semmle.label | no-match |
| patterns.cs:80:18:80:19 | { ... } | patterns.cs:81:17:81:22 | break; | semmle.label | match |
| patterns.cs:80:18:80:19 | { ... } | patterns.cs:82:13:82:20 | case ...: | semmle.label | no-match |
| patterns.cs:81:17:81:22 | break; | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | break |
| patterns.cs:82:13:82:20 | case ...: | patterns.cs:82:18:82:19 | { ... } | semmle.label | successor |
| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | { ... } | semmle.label | successor |
| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | { ... } | semmle.label | match |
| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | { ... } | semmle.label | no-match |
| patterns.cs:82:18:82:19 | { ... } | patterns.cs:83:17:83:22 | break; | semmle.label | match |
| patterns.cs:82:18:82:19 | { ... } | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | no-match |
| patterns.cs:83:17:83:22 | break; | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | break |
@@ -145,27 +160,34 @@
| patterns.cs:86:16:86:16 | 1 | patterns.cs:86:18:86:18 | 2 | semmle.label | successor |
| patterns.cs:86:18:86:18 | 2 | patterns.cs:86:15:86:19 | (..., ...) | semmle.label | successor |
| patterns.cs:88:13:88:24 | case ...: | patterns.cs:88:19:88:19 | 1 | semmle.label | successor |
| patterns.cs:88:18:88:23 | ( ... ) | patterns.cs:88:18:88:23 | { ... } | semmle.label | successor |
| patterns.cs:88:18:88:23 | ( ... ) | patterns.cs:88:18:88:23 | { ... } | semmle.label | match |
| patterns.cs:88:18:88:23 | ( ... ) | patterns.cs:88:18:88:23 | { ... } | semmle.label | no-match |
| patterns.cs:88:18:88:23 | { ... } | patterns.cs:88:26:88:31 | break; | semmle.label | match |
| patterns.cs:88:18:88:23 | { ... } | patterns.cs:91:9:95:9 | switch (...) {...} | semmle.label | no-match |
| patterns.cs:88:19:88:19 | 1 | patterns.cs:88:22:88:22 | 2 | semmle.label | successor |
| patterns.cs:88:22:88:22 | 2 | patterns.cs:88:18:88:23 | ( ... ) | semmle.label | successor |
| patterns.cs:88:19:88:19 | 1 | patterns.cs:88:22:88:22 | 2 | semmle.label | match |
| patterns.cs:88:19:88:19 | 1 | patterns.cs:88:22:88:22 | 2 | semmle.label | no-match |
| patterns.cs:88:22:88:22 | 2 | patterns.cs:88:18:88:23 | ( ... ) | semmle.label | match |
| patterns.cs:88:22:88:22 | 2 | patterns.cs:88:18:88:23 | ( ... ) | semmle.label | no-match |
| patterns.cs:88:26:88:31 | break; | patterns.cs:91:9:95:9 | switch (...) {...} | semmle.label | break |
| patterns.cs:91:9:95:9 | switch (...) {...} | patterns.cs:91:17:91:17 | 1 | semmle.label | successor |
| patterns.cs:91:16:91:20 | (..., ...) | patterns.cs:93:13:93:28 | case ...: | semmle.label | successor |
| patterns.cs:91:17:91:17 | 1 | patterns.cs:91:19:91:19 | 2 | semmle.label | successor |
| patterns.cs:91:19:91:19 | 2 | patterns.cs:91:16:91:20 | (..., ...) | semmle.label | successor |
| patterns.cs:93:13:93:28 | case ...: | patterns.cs:93:19:93:19 | 1 | semmle.label | successor |
| patterns.cs:93:18:93:27 | ( ... ) | patterns.cs:93:18:93:27 | { ... } | semmle.label | successor |
| patterns.cs:93:18:93:27 | ( ... ) | patterns.cs:93:18:93:27 | { ... } | semmle.label | match |
| patterns.cs:93:18:93:27 | ( ... ) | patterns.cs:93:18:93:27 | { ... } | semmle.label | no-match |
| patterns.cs:93:18:93:27 | { ... } | patterns.cs:93:30:93:35 | break; | semmle.label | match |
| patterns.cs:93:18:93:27 | { ... } | patterns.cs:94:13:94:24 | case ...: | semmle.label | no-match |
| patterns.cs:93:19:93:19 | 1 | patterns.cs:93:22:93:26 | Int32 x | semmle.label | successor |
| patterns.cs:93:22:93:26 | Int32 x | patterns.cs:93:18:93:27 | ( ... ) | semmle.label | successor |
| patterns.cs:93:19:93:19 | 1 | patterns.cs:93:22:93:26 | Int32 x | semmle.label | match |
| patterns.cs:93:19:93:19 | 1 | patterns.cs:93:22:93:26 | Int32 x | semmle.label | no-match |
| patterns.cs:93:22:93:26 | Int32 x | patterns.cs:93:18:93:27 | ( ... ) | semmle.label | no-match |
| patterns.cs:93:30:93:35 | break; | patterns.cs:32:10:32:25 | exit SwitchStatements (normal) | semmle.label | break |
| patterns.cs:94:13:94:24 | case ...: | patterns.cs:94:19:94:19 | 2 | semmle.label | successor |
| patterns.cs:94:18:94:23 | ( ... ) | patterns.cs:94:18:94:23 | { ... } | semmle.label | successor |
| patterns.cs:94:18:94:23 | ( ... ) | patterns.cs:94:18:94:23 | { ... } | semmle.label | match |
| patterns.cs:94:18:94:23 | ( ... ) | patterns.cs:94:18:94:23 | { ... } | semmle.label | no-match |
| patterns.cs:94:18:94:23 | { ... } | patterns.cs:32:10:32:25 | exit SwitchStatements (normal) | semmle.label | no-match |
| patterns.cs:94:18:94:23 | { ... } | patterns.cs:94:26:94:31 | break; | semmle.label | match |
| patterns.cs:94:19:94:19 | 2 | patterns.cs:94:22:94:22 | _ | semmle.label | successor |
| patterns.cs:94:22:94:22 | _ | patterns.cs:94:18:94:23 | ( ... ) | semmle.label | successor |
| patterns.cs:94:19:94:19 | 2 | patterns.cs:94:22:94:22 | _ | semmle.label | match |
| patterns.cs:94:19:94:19 | 2 | patterns.cs:94:22:94:22 | _ | semmle.label | no-match |
| patterns.cs:94:22:94:22 | _ | patterns.cs:94:18:94:23 | ( ... ) | semmle.label | match |
| patterns.cs:94:26:94:31 | break; | patterns.cs:32:10:32:25 | exit SwitchStatements (normal) | semmle.label | break |

View File

@@ -0,0 +1,22 @@
using System;
public class BinaryPattern
{
public int P1 { get; set; }
public static bool M1(char c) =>
c is 'a' or 'b';
public static bool M2(object c) =>
c is object o and BinaryPattern { P1: 1 } u;
public static bool M3(object c) =>
c is object o and BinaryPattern u;
public static string M4(int i)
{
return i switch
{
1 or 2 => "1 or 2",
_ => "other"
};
}
}

View File

@@ -54,6 +54,69 @@ AnonymousObjectCreation.cs:
# 25| 1: [TypeMention] int
# 25| 0: [LocalVariableAccess] access to local variable list
# 25| 1: [ObjectCreation] object creation of type List<Int32>
BinaryPattern.cs:
# 3| [Class] BinaryPattern
# 5| 5: [Property] P1
# 5| -1: [TypeMention] int
# 5| 3: [Getter] get_P1
# 5| 4: [Setter] set_P1
#-----| 2: (Parameters)
# 5| 0: [Parameter] value
# 7| 6: [Method] M1
# 7| -1: [TypeMention] bool
#-----| 2: (Parameters)
# 7| 0: [Parameter] c
# 7| -1: [TypeMention] char
# 8| 4: [IsExpr] ... is ...
# 8| 0: [ParameterAccess] access to parameter c
# 8| 1: [OrPatternExpr] ... or ...
# 8| 0: [CharLiteral,ConstantPatternExpr] a
# 8| 1: [CharLiteral,ConstantPatternExpr] b
# 9| 7: [Method] M2
# 9| -1: [TypeMention] bool
#-----| 2: (Parameters)
# 9| 0: [Parameter] c
# 9| -1: [TypeMention] object
# 10| 4: [IsExpr] ... is ...
# 10| 0: [ParameterAccess] access to parameter c
# 10| 1: [AndPatternExpr] ... and ...
# 10| 0: [VariablePatternExpr] Object o
# 10| 0: [TypeMention] object
# 10| 1: [RecursivePatternExpr] { ... }
# 10| 0: [LocalVariableDeclExpr] BinaryPattern u
# 10| 1: [TypeAccess] access to type BinaryPattern
# 10| 0: [TypeMention] BinaryPattern
# 10| 3: [PropertyPatternExpr] { ... }
# 10| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 1
# 11| 8: [Method] M3
# 11| -1: [TypeMention] bool
#-----| 2: (Parameters)
# 11| 0: [Parameter] c
# 11| -1: [TypeMention] object
# 12| 4: [IsExpr] ... is ...
# 12| 0: [ParameterAccess] access to parameter c
# 12| 1: [AndPatternExpr] ... and ...
# 12| 0: [VariablePatternExpr] Object o
# 12| 0: [TypeMention] object
# 12| 1: [VariablePatternExpr] BinaryPattern u
# 12| 0: [TypeMention] BinaryPattern
# 14| 9: [Method] M4
# 14| -1: [TypeMention] string
#-----| 2: (Parameters)
# 14| 0: [Parameter] i
# 14| -1: [TypeMention] int
# 15| 4: [BlockStmt] {...}
# 16| 0: [ReturnStmt] return ...;
# 16| 0: [SwitchExpr] ... switch { ... }
# 16| -1: [ParameterAccess] access to parameter i
# 18| 0: [SwitchCaseExpr] ... => ...
# 18| 0: [OrPatternExpr] ... or ...
# 18| 0: [ConstantPatternExpr,IntLiteral] 1
# 18| 1: [ConstantPatternExpr,IntLiteral] 2
# 18| 2: [StringLiteral] "1 or 2"
# 19| 1: [SwitchCaseExpr] ... => ...
# 19| 0: [DiscardPatternExpr] _
# 19| 2: [StringLiteral] "other"
Discard.cs:
# 3| [Class] Discard
# 5| 5: [Method] M1

View File

@@ -0,0 +1,4 @@
| BinaryPattern.cs:8:14:8:23 | ... or ... | BinaryPattern.cs:8:14:8:16 | a | BinaryPattern.cs:8:21:8:23 | b |
| BinaryPattern.cs:10:14:10:51 | ... and ... | BinaryPattern.cs:10:14:10:21 | Object o | BinaryPattern.cs:10:27:10:51 | { ... } |
| BinaryPattern.cs:12:14:12:41 | ... and ... | BinaryPattern.cs:12:14:12:21 | Object o | BinaryPattern.cs:12:27:12:41 | BinaryPattern u |
| BinaryPattern.cs:18:13:18:18 | ... or ... | BinaryPattern.cs:18:13:18:13 | 1 | BinaryPattern.cs:18:18:18:18 | 2 |

View File

@@ -0,0 +1,4 @@
import csharp
from BinaryPatternExpr pattern
select pattern, pattern.getLeftOperand(), pattern.getRightOperand()

View File

@@ -1,4 +1,5 @@
| AnonymousObjectCreation.cs:9:29:9:31 | set_Prop1 | set |
| BinaryPattern.cs:5:26:5:28 | set_P1 | set |
| InitOnlyProperty.cs:12:42:12:45 | set_Prop0 | init |
| InitOnlyProperty.cs:13:37:13:40 | set_Prop1 | init |
| InitOnlyProperty.cs:14:37:14:39 | set_Prop2 | set |

View File

@@ -1,3 +1,6 @@
| BinaryPattern.cs:10:14:10:21 | Object o | Object |
| BinaryPattern.cs:12:14:12:21 | Object o | Object |
| BinaryPattern.cs:12:27:12:41 | BinaryPattern u | BinaryPattern |
| ParenthesizedPattern.cs:25:13:25:15 | T t | T |
| ParenthesizedPattern.cs:26:14:26:22 | Object o1 | Object |
| ParenthesizedPattern.cs:27:14:27:19 | access to type String | String |

View File

@@ -199,8 +199,6 @@
| SignAnalysis.cs:377:21:377:22 | &... | positive |
| SignAnalysis.cs:378:18:378:19 | access to local variable dp | positive |
| SignAnalysis.cs:381:38:381:38 | access to local variable x | strictlyNegative |
| SignAnalysis.cs:385:50:385:99 | access to constant Explicit | strictlyPositive |
| SignAnalysis.cs:385:109:385:110 | 15 | strictlyPositive |
| SignAnalysis.cs:390:13:390:32 | Int32 x = ... | strictlyPositive |
| SignAnalysis.cs:390:17:390:32 | sizeof(..) | strictlyPositive |
| SignAnalysis.cs:391:34:391:34 | access to local variable x | strictlyPositive |

View File

@@ -599,7 +599,7 @@ expressions.cs:
# 64| 0: [PropertyCall] access to property Length
# 64| -1: [ParameterAccess] access to parameter s
# 64| 1: [ParameterAccess] access to parameter x
# 67| 14: [IndexerProperty] Name
# 67| 14: [Property] Name
# 67| -1: [TypeMention] string
# 69| 3: [Getter] get_Name
# 69| 4: [BlockStmt] {...}
@@ -1504,7 +1504,7 @@ expressions.cs:
# 375| 1: [ObjectCreation] object creation of type List<String>
# 375| 0: [TypeMention] List<String>
# 375| 1: [TypeMention] string
# 377| 7: [IndexerProperty] Name
# 377| 7: [Property] Name
# 377| -1: [TypeMention] string
# 377| 3: [Getter] get_Name
# 377| 4: [BlockStmt] {...}
@@ -1518,7 +1518,7 @@ expressions.cs:
# 377| 0: [AssignExpr] ... = ...
# 377| 0: [FieldAccess] access to field name
# 377| 1: [ParameterAccess] access to parameter value
# 378| 8: [IndexerProperty] PhoneNumbers
# 378| 8: [Property] PhoneNumbers
# 378| -1: [TypeMention] List<String>
# 378| 1: [TypeMention] string
# 378| 3: [Getter] get_PhoneNumbers

View File

@@ -289,7 +289,7 @@ generics.cs:
# 33| 9: [Method] staticFoo
# 33| -1: [TypeMention] Void
# 33| 4: [BlockStmt] {...}
# 35| 10: [IndexerProperty] Name
# 35| 10: [Property] Name
# 35| -1: [TypeMention] string
# 35| 3: [Getter] get_Name
# 35| 4: [BlockStmt] {...}

View File

@@ -34,7 +34,7 @@ Members.cs:
# 14| 4: [BlockStmt] {...}
# 16| 7: [Field] Field
# 16| -1: [TypeMention] string
# 18| 8: [IndexerProperty] Prop
# 18| 8: [Property] Prop
# 18| -1: [TypeMention] string
# 18| 3: [Getter] get_Prop
# 18| 4: [Setter] set_Prop
@@ -68,7 +68,7 @@ Members.cs:
# 26| 4: [BlockStmt] {...}
# 28| 8: [Field] Field
# 28| -1: [TypeMention] string
# 30| 9: [IndexerProperty] Prop
# 30| 9: [Property] Prop
# 30| -1: [TypeMention] string
# 30| 3: [Getter] get_Prop
# 30| 4: [Setter] set_Prop
@@ -110,7 +110,7 @@ Members.cs:
# 40| 4: [BlockStmt] {...}
# 41| 7: [Field] Field
# 41| -1: [TypeMention] string
# 42| 8: [IndexerProperty] Prop
# 42| 8: [Property] Prop
# 42| -1: [TypeMention] string
# 42| 3: [Getter] get_Prop
# 42| 4: [Setter] set_Prop
@@ -144,7 +144,7 @@ Members.cs:
# 47| 4: [BlockStmt] {...}
# 48| 8: [Field] Field
# 48| -1: [TypeMention] string
# 49| 9: [IndexerProperty] Prop
# 49| 9: [Property] Prop
# 49| -1: [TypeMention] string
# 49| 3: [Getter] get_Prop
# 49| 4: [Setter] set_Prop
@@ -173,7 +173,7 @@ Members.cs:
#-----| 2: (Parameters)
# 57| 0: [Parameter] i
# 57| 1: [Parameter] value
# 58| 6: [IndexerProperty] Prop
# 58| 6: [Property] Prop
# 58| -1: [TypeMention] string
# 58| 3: [Getter] get_Prop
# 58| 4: [Setter] set_Prop
@@ -202,7 +202,7 @@ Members.cs:
#-----| 2: (Parameters)
# 65| 0: [Parameter] i
# 65| 1: [Parameter] value
# 66| 6: [IndexerProperty] Prop
# 66| 6: [Property] Prop
# 66| -1: [TypeMention] string
# 66| 3: [Getter] get_Prop
# 66| 4: [Setter] set_Prop

View File

@@ -3,7 +3,7 @@ properties.cs:
# 7| 1: [Class] Button
# 10| 5: [Field] caption
# 10| -1: [TypeMention] string
# 12| 6: [IndexerProperty] Caption
# 12| 6: [Property] Caption
# 12| -1: [TypeMention] string
# 15| 3: [Getter] get_Caption
# 15| 4: [BlockStmt] {...}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add 'and_pattern_expr' and 'or_pattern_expr' to the list of 'expr' types.
compatibility: backwards

View File

@@ -470,7 +470,7 @@ A QLDoc comment is a *qldoc comment start*, followed by a *qldoc comment body*,
The "content" of a QLDoc comment is the comment body of the comment, omitting the initial ``/**``, the trailing ``*/``, and the leading whitespace followed by ``*`` on each internal line.
For more information about how the content is interpreted, see see "`QLDoc <#qldoc>`__" below.
For more information about how the content is interpreted, see "`QLDoc <#qldoc>`__" below.
Keywords
~~~~~~~~

View File

@@ -112,6 +112,17 @@ module CodeInjection {
}
}
/**
* A body element from a script tag inside React code.
*/
class ReactScriptTag extends Sink {
ReactScriptTag() {
exists(JSXElement element | element.getName() = "script" |
this = element.getBodyElement(_).flow()
)
}
}
/**
* An event handler attribute as a code injection sink.
*/

View File

@@ -650,6 +650,47 @@ nodes
| v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location |
| v-html.vue:6:42:6:58 | document.location |
| various-concat-obfuscations.js:2:6:2:39 | tainted |
| various-concat-obfuscations.js:2:16:2:39 | documen ... .search |
| various-concat-obfuscations.js:2:16:2:39 | documen ... .search |
| various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" |
| various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" |
| various-concat-obfuscations.js:4:14:4:20 | tainted |
| various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` |
| various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` |
| various-concat-obfuscations.js:5:12:5:18 | tainted |
| various-concat-obfuscations.js:6:4:6:26 | "<div>" ... ainted) |
| various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") |
| various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") |
| various-concat-obfuscations.js:6:19:6:25 | tainted |
| various-concat-obfuscations.js:7:4:7:31 | ["<div> ... /div>"] |
| various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() |
| various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() |
| various-concat-obfuscations.js:7:14:7:20 | tainted |
| various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" |
| various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" |
| various-concat-obfuscations.js:9:19:9:25 | tainted |
| various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` |
| various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` |
| various-concat-obfuscations.js:10:16:10:22 | tainted |
| various-concat-obfuscations.js:11:4:11:31 | "<div i ... ainted) |
| various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") |
| various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") |
| various-concat-obfuscations.js:11:24:11:30 | tainted |
| various-concat-obfuscations.js:12:4:12:34 | ["<div ... "\\"/>"] |
| various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() |
| various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() |
| various-concat-obfuscations.js:12:19:12:25 | tainted |
| various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:20:17:20:40 | documen ... .search |
| various-concat-obfuscations.js:20:17:20:40 | documen ... .search |
| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs |
| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:21:17:21:40 | documen ... .search |
| various-concat-obfuscations.js:21:17:21:40 | documen ... .search |
| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs |
| winjs.js:2:7:2:53 | tainted |
| winjs.js:2:17:2:33 | document.location |
| winjs.js:2:17:2:33 | document.location |
@@ -1218,6 +1259,44 @@ edges
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:6:19:6:25 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:7:14:7:20 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:9:19:9:25 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:10:16:10:22 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:11:24:11:30 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:12:19:12:25 | tainted |
| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted |
| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted |
| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" |
| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" |
| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` |
| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` |
| various-concat-obfuscations.js:6:4:6:26 | "<div>" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") |
| various-concat-obfuscations.js:6:4:6:26 | "<div>" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") |
| various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "<div>" ... ainted) |
| various-concat-obfuscations.js:7:4:7:31 | ["<div> ... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() |
| various-concat-obfuscations.js:7:4:7:31 | ["<div> ... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() |
| various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["<div> ... /div>"] |
| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" |
| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" |
| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` |
| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` |
| various-concat-obfuscations.js:11:4:11:31 | "<div i ... ainted) | various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") |
| various-concat-obfuscations.js:11:4:11:31 | "<div i ... ainted) | various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") |
| various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "<div i ... ainted) |
| various-concat-obfuscations.js:12:4:12:34 | ["<div ... "\\"/>"] | various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() |
| various-concat-obfuscations.js:12:4:12:34 | ["<div ... "\\"/>"] | various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() |
| various-concat-obfuscations.js:12:19:12:25 | tainted | various-concat-obfuscations.js:12:4:12:34 | ["<div ... "\\"/>"] |
| various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs |
| various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs |
| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs |
| various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs |
| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
| winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted |
| winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted |
| winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted |
@@ -1374,5 +1453,15 @@ edges
| tst.js:424:18:424:51 | window. ... '#')[1] | tst.js:424:18:424:32 | window.location | tst.js:424:18:424:51 | window. ... '#')[1] | Cross-site scripting vulnerability due to $@. | tst.js:424:18:424:32 | window.location | user-provided value |
| typeahead.js:25:18:25:20 | val | typeahead.js:20:22:20:38 | document.location | typeahead.js:25:18:25:20 | val | Cross-site scripting vulnerability due to $@. | typeahead.js:20:22:20:38 | document.location | user-provided value |
| v-html.vue:2:8:2:23 | v-html=tainted | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | Cross-site scripting vulnerability due to $@. | v-html.vue:6:42:6:58 | document.location | user-provided value |
| various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:20:17:20:40 | documen ... .search | user-provided value |
| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:21:17:21:40 | documen ... .search | user-provided value |
| winjs.js:3:43:3:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:3:43:3:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value |
| winjs.js:4:43:4:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:4:43:4:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value |

View File

@@ -661,6 +661,47 @@ nodes
| v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location |
| v-html.vue:6:42:6:58 | document.location |
| various-concat-obfuscations.js:2:6:2:39 | tainted |
| various-concat-obfuscations.js:2:16:2:39 | documen ... .search |
| various-concat-obfuscations.js:2:16:2:39 | documen ... .search |
| various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" |
| various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" |
| various-concat-obfuscations.js:4:14:4:20 | tainted |
| various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` |
| various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` |
| various-concat-obfuscations.js:5:12:5:18 | tainted |
| various-concat-obfuscations.js:6:4:6:26 | "<div>" ... ainted) |
| various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") |
| various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") |
| various-concat-obfuscations.js:6:19:6:25 | tainted |
| various-concat-obfuscations.js:7:4:7:31 | ["<div> ... /div>"] |
| various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() |
| various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() |
| various-concat-obfuscations.js:7:14:7:20 | tainted |
| various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" |
| various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" |
| various-concat-obfuscations.js:9:19:9:25 | tainted |
| various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` |
| various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` |
| various-concat-obfuscations.js:10:16:10:22 | tainted |
| various-concat-obfuscations.js:11:4:11:31 | "<div i ... ainted) |
| various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") |
| various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") |
| various-concat-obfuscations.js:11:24:11:30 | tainted |
| various-concat-obfuscations.js:12:4:12:34 | ["<div ... "\\"/>"] |
| various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() |
| various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() |
| various-concat-obfuscations.js:12:19:12:25 | tainted |
| various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:20:17:20:40 | documen ... .search |
| various-concat-obfuscations.js:20:17:20:40 | documen ... .search |
| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs |
| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:21:17:21:40 | documen ... .search |
| various-concat-obfuscations.js:21:17:21:40 | documen ... .search |
| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs |
| winjs.js:2:7:2:53 | tainted |
| winjs.js:2:17:2:33 | document.location |
| winjs.js:2:17:2:33 | document.location |
@@ -1239,6 +1280,44 @@ edges
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:4:14:4:20 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:5:12:5:18 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:6:19:6:25 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:7:14:7:20 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:9:19:9:25 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:10:16:10:22 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:11:24:11:30 | tainted |
| various-concat-obfuscations.js:2:6:2:39 | tainted | various-concat-obfuscations.js:12:19:12:25 | tainted |
| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted |
| various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:2:6:2:39 | tainted |
| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" |
| various-concat-obfuscations.js:4:14:4:20 | tainted | various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" |
| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` |
| various-concat-obfuscations.js:5:12:5:18 | tainted | various-concat-obfuscations.js:5:4:5:26 | `<div>$ ... </div>` |
| various-concat-obfuscations.js:6:4:6:26 | "<div>" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") |
| various-concat-obfuscations.js:6:4:6:26 | "<div>" ... ainted) | various-concat-obfuscations.js:6:4:6:43 | "<div>" ... /div>") |
| various-concat-obfuscations.js:6:19:6:25 | tainted | various-concat-obfuscations.js:6:4:6:26 | "<div>" ... ainted) |
| various-concat-obfuscations.js:7:4:7:31 | ["<div> ... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() |
| various-concat-obfuscations.js:7:4:7:31 | ["<div> ... /div>"] | various-concat-obfuscations.js:7:4:7:38 | ["<div> ... .join() |
| various-concat-obfuscations.js:7:14:7:20 | tainted | various-concat-obfuscations.js:7:4:7:31 | ["<div> ... /div>"] |
| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" |
| various-concat-obfuscations.js:9:19:9:25 | tainted | various-concat-obfuscations.js:9:4:9:34 | "<div i ... "\\"/>" |
| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` |
| various-concat-obfuscations.js:10:16:10:22 | tainted | various-concat-obfuscations.js:10:4:10:27 | `<div i ... ed}"/>` |
| various-concat-obfuscations.js:11:4:11:31 | "<div i ... ainted) | various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") |
| various-concat-obfuscations.js:11:4:11:31 | "<div i ... ainted) | various-concat-obfuscations.js:11:4:11:44 | "<div i ... t("/>") |
| various-concat-obfuscations.js:11:24:11:30 | tainted | various-concat-obfuscations.js:11:4:11:31 | "<div i ... ainted) |
| various-concat-obfuscations.js:12:4:12:34 | ["<div ... "\\"/>"] | various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() |
| various-concat-obfuscations.js:12:4:12:34 | ["<div ... "\\"/>"] | various-concat-obfuscations.js:12:4:12:41 | ["<div ... .join() |
| various-concat-obfuscations.js:12:19:12:25 | tainted | various-concat-obfuscations.js:12:4:12:34 | ["<div ... "\\"/>"] |
| various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs |
| various-concat-obfuscations.js:20:17:20:40 | documen ... .search | various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs |
| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:20:17:20:46 | documen ... h.attrs | various-concat-obfuscations.js:20:4:20:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs |
| various-concat-obfuscations.js:21:17:21:40 | documen ... .search | various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs |
| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
| winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted |
| winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted |
| winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted |

View File

@@ -0,0 +1,22 @@
function test() {
let tainted = document.location.search;
$("<div>" + tainted + "</div>"); // NOT OK
$(`<div>${tainted}</div>`); // NOT OK
$("<div>".concat(tainted).concat("</div>")); // NOT OK
$(["<div>", tainted, "</div>"].join()); // NOT OK
$("<div id=\"" + tainted + "\"/>"); // NOT OK
$(`<div id="${tainted}"/>`); // NOT OK
$("<div id=\"".concat(tainted).concat("/>")); // NOT OK
$(["<div id=\"", tainted, "\"/>"].join()); // NOT OK
function indirection1(attrs) {
return '<div align="' + (attrs.defaultattr || 'left') + '">' + content + '</div>';
}
function indirection2(attrs) {
return '<div align="'.concat(attrs.defaultattr || 'left').concat('">'.concat(content)).concat('</div>');
}
$(indirection1(document.location.search.attrs)); // NOT OK
$(indirection2(document.location.search.attrs)); // NOT OK
};

View File

@@ -118,6 +118,10 @@ nodes
| react-native.js:8:32:8:38 | tainted |
| react-native.js:10:23:10:29 | tainted |
| react-native.js:10:23:10:29 | tainted |
| react.js:10:56:10:72 | document.location |
| react.js:10:56:10:72 | document.location |
| react.js:10:56:10:77 | documen ... on.hash |
| react.js:10:56:10:77 | documen ... on.hash |
| template-sinks.js:12:9:12:31 | tainted |
| template-sinks.js:12:19:12:31 | req.query.foo |
| template-sinks.js:12:19:12:31 | req.query.foo |
@@ -275,6 +279,10 @@ edges
| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted |
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
| react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash |
| react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash |
| react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash |
| react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash |
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:14:17:14:23 | tainted |
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:14:17:14:23 | tainted |
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:15:16:15:22 | tainted |
@@ -352,6 +360,7 @@ edges
| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | $@ flows to here and is interpreted as code. | module.js:9:16:9:29 | req.query.code | User-provided value |
| react-native.js:8:32:8:38 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:32:8:38 | tainted | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
| react-native.js:10:23:10:29 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:10:23:10:29 | tainted | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
| react.js:10:56:10:77 | documen ... on.hash | react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash | $@ flows to here and is interpreted as code. | react.js:10:56:10:72 | document.location | User-provided value |
| template-sinks.js:14:17:14:23 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:14:17:14:23 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
| template-sinks.js:15:16:15:22 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:15:16:15:22 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |
| template-sinks.js:16:18:16:24 | tainted | template-sinks.js:12:19:12:31 | req.query.foo | template-sinks.js:16:18:16:24 | tainted | $@ flows to here and is interpreted as a template, which may contain code. | template-sinks.js:12:19:12:31 | req.query.foo | User-provided value |

View File

@@ -122,6 +122,10 @@ nodes
| react-native.js:8:32:8:38 | tainted |
| react-native.js:10:23:10:29 | tainted |
| react-native.js:10:23:10:29 | tainted |
| react.js:10:56:10:72 | document.location |
| react.js:10:56:10:72 | document.location |
| react.js:10:56:10:77 | documen ... on.hash |
| react.js:10:56:10:77 | documen ... on.hash |
| template-sinks.js:12:9:12:31 | tainted |
| template-sinks.js:12:19:12:31 | req.query.foo |
| template-sinks.js:12:19:12:31 | req.query.foo |
@@ -283,6 +287,10 @@ edges
| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted |
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
| react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash |
| react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash |
| react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash |
| react.js:10:56:10:72 | document.location | react.js:10:56:10:77 | documen ... on.hash |
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:14:17:14:23 | tainted |
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:14:17:14:23 | tainted |
| template-sinks.js:12:9:12:31 | tainted | template-sinks.js:15:16:15:22 | tainted |

View File

@@ -0,0 +1,17 @@
import React from "react";
import {Helmet} from "react-helmet";
class Application extends React.Component {
render () {
return (
<div className="application">
<Helmet>
<title>My unsafe</title>
<script type="application/javascript">{document.location.hash}</script>
</Helmet>
</div>
);
}
};
export default Application

View File

@@ -3,6 +3,10 @@ nodes
| electron.js:4:12:4:22 | window.name |
| electron.js:7:20:7:29 | getTaint() |
| electron.js:7:20:7:29 | getTaint() |
| react.js:10:60:10:76 | document.location |
| react.js:10:60:10:76 | document.location |
| react.js:10:60:10:81 | documen ... on.hash |
| react.js:10:60:10:81 | documen ... on.hash |
| sanitizer.js:2:9:2:25 | url |
| sanitizer.js:2:15:2:25 | window.name |
| sanitizer.js:2:15:2:25 | window.name |
@@ -189,6 +193,10 @@ edges
| electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() |
| electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() |
| electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() |
| react.js:10:60:10:76 | document.location | react.js:10:60:10:81 | documen ... on.hash |
| react.js:10:60:10:76 | document.location | react.js:10:60:10:81 | documen ... on.hash |
| react.js:10:60:10:76 | document.location | react.js:10:60:10:81 | documen ... on.hash |
| react.js:10:60:10:76 | document.location | react.js:10:60:10:81 | documen ... on.hash |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:4:27:4:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:4:27:4:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:16:27:16:29 | url |
@@ -358,6 +366,7 @@ edges
| typed.ts:28:24:28:34 | redirectUri | typed.ts:29:33:29:43 | redirectUri |
#select
| electron.js:7:20:7:29 | getTaint() | electron.js:4:12:4:22 | window.name | electron.js:7:20:7:29 | getTaint() | Untrusted URL redirection due to $@. | electron.js:4:12:4:22 | window.name | user-provided value |
| react.js:10:60:10:81 | documen ... on.hash | react.js:10:60:10:76 | document.location | react.js:10:60:10:81 | documen ... on.hash | Untrusted URL redirection due to $@. | react.js:10:60:10:76 | document.location | user-provided value |
| sanitizer.js:4:27:4:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:4:27:4:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:16:27:16:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:16:27:16:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:19:27:19:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:19:27:19:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |

View File

@@ -0,0 +1,17 @@
import React from "react";
import {Helmet} from "react-helmet";
class Application extends React.Component {
render () {
return (
<div className="application">
<Helmet>
<title>My unsafe app</title>
<script type="application/javascript" src={document.location.hash}/>
</Helmet>
</div>
);
}
};
export default Application

View File

@@ -143,7 +143,7 @@ class EssaNode extends Node, TEssaNode {
override Scope getScope() { result = var.getScope() }
override Location getLocation() { result = var.getDefinition().getLocation() }
override Location getLocation() { result = var.getLocation() }
}
/** A data-flow node corresponding to a control-flow node. */

View File

@@ -61,6 +61,13 @@ class EssaVariable extends TEssaDefinition {
* defined by `from ... import *` and the like.
*/
predicate isMetaVariable() { this.getName() = "$" }
/**
* Gets the location of this variable.
*
* Yields the location of the corresponding definition of this variable.
*/
Location getLocation() { result = this.getDefinition().getLocation() }
}
/*

View File

@@ -35,7 +35,7 @@ private module Django {
* WARNING: Only holds for a few predefined attributes.
*/
private DataFlow::Node django_attr(DataFlow::TypeTracker t, string attr_name) {
attr_name in ["db", "urls", "http", "conf", "shortcuts"] and
attr_name in ["db", "urls", "http", "conf", "views", "shortcuts"] and
(
t.start() and
result = DataFlow::importNode("django" + "." + attr_name)
@@ -1577,7 +1577,9 @@ private module Django {
"View", "TemplateView", "RedirectView", "ArchiveIndexView", "YearArchiveView",
"MonthArchiveView", "WeekArchiveView", "DayArchiveView", "TodayArchiveView",
"DateDetailView", "DetailView", "FormView", "CreateView", "UpdateView", "DeleteView",
"ListView", "GenericViewError"
"ListView", "GenericViewError",
// modules
"base", "dates", "detail", "edit", "list"
] and
(
t.start() and
@@ -1613,6 +1615,254 @@ private module Django {
result = generic_attr(DataFlow::TypeTracker::end(), attr_name)
}
// -------------------------------------------------------------------------
// django.views.generic.base
// -------------------------------------------------------------------------
/** Gets a reference to the `django.views.generic.base` module. */
DataFlow::Node base() { result = generic_attr("base") }
/** Provides models for the `django.views.generic.base` module */
module base {
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.base` module.
* WARNING: Only holds for a few predefined attributes.
*/
private DataFlow::Node base_attr(DataFlow::TypeTracker t, string attr_name) {
attr_name in ["RedirectView", "TemplateView", "View"] and
(
t.start() and
result = DataFlow::importNode("django.views.generic.base" + "." + attr_name)
or
t.startInAttr(attr_name) and
result = base()
)
or
// Due to bad performance when using normal setup with `base_attr(t2, attr_name).track(t2, t)`
// we have inlined that code and forced a join
exists(DataFlow::TypeTracker t2 |
exists(DataFlow::StepSummary summary |
base_attr_first_join(t2, attr_name, result, summary) and
t = t2.append(summary)
)
)
}
pragma[nomagic]
private predicate base_attr_first_join(
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res,
DataFlow::StepSummary summary
) {
DataFlow::StepSummary::step(base_attr(t2, attr_name), res, summary)
}
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.base` module.
* WARNING: Only holds for a few predefined attributes.
*/
DataFlow::Node base_attr(string attr_name) {
result = base_attr(DataFlow::TypeTracker::end(), attr_name)
}
}
// -------------------------------------------------------------------------
// django.views.generic.dates
// -------------------------------------------------------------------------
/** Gets a reference to the `django.views.generic.dates` module. */
DataFlow::Node dates() { result = generic_attr("dates") }
/** Provides models for the `django.views.generic.dates` module */
module dates {
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.dates` module.
* WARNING: Only holds for a few predefined attributes.
*/
private DataFlow::Node dates_attr(DataFlow::TypeTracker t, string attr_name) {
attr_name in [
"ArchiveIndexView", "DateDetailView", "DayArchiveView", "MonthArchiveView",
"TodayArchiveView", "WeekArchiveView", "YearArchiveView"
] and
(
t.start() and
result = DataFlow::importNode("django.views.generic.dates" + "." + attr_name)
or
t.startInAttr(attr_name) and
result = dates()
)
or
// Due to bad performance when using normal setup with `dates_attr(t2, attr_name).track(t2, t)`
// we have inlined that code and forced a join
exists(DataFlow::TypeTracker t2 |
exists(DataFlow::StepSummary summary |
dates_attr_first_join(t2, attr_name, result, summary) and
t = t2.append(summary)
)
)
}
pragma[nomagic]
private predicate dates_attr_first_join(
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res,
DataFlow::StepSummary summary
) {
DataFlow::StepSummary::step(dates_attr(t2, attr_name), res, summary)
}
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.dates` module.
* WARNING: Only holds for a few predefined attributes.
*/
DataFlow::Node dates_attr(string attr_name) {
result = dates_attr(DataFlow::TypeTracker::end(), attr_name)
}
}
// -------------------------------------------------------------------------
// django.views.generic.detail
// -------------------------------------------------------------------------
/** Gets a reference to the `django.views.generic.detail` module. */
DataFlow::Node detail() { result = generic_attr("detail") }
/** Provides models for the `django.views.generic.detail` module */
module detail {
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.detail` module.
* WARNING: Only holds for a few predefined attributes.
*/
private DataFlow::Node detail_attr(DataFlow::TypeTracker t, string attr_name) {
attr_name in ["DetailView"] and
(
t.start() and
result = DataFlow::importNode("django.views.generic.detail" + "." + attr_name)
or
t.startInAttr(attr_name) and
result = detail()
)
or
// Due to bad performance when using normal setup with `detail_attr(t2, attr_name).track(t2, t)`
// we have inlined that code and forced a join
exists(DataFlow::TypeTracker t2 |
exists(DataFlow::StepSummary summary |
detail_attr_first_join(t2, attr_name, result, summary) and
t = t2.append(summary)
)
)
}
pragma[nomagic]
private predicate detail_attr_first_join(
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res,
DataFlow::StepSummary summary
) {
DataFlow::StepSummary::step(detail_attr(t2, attr_name), res, summary)
}
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.detail` module.
* WARNING: Only holds for a few predefined attributes.
*/
DataFlow::Node detail_attr(string attr_name) {
result = detail_attr(DataFlow::TypeTracker::end(), attr_name)
}
}
// -------------------------------------------------------------------------
// django.views.generic.edit
// -------------------------------------------------------------------------
/** Gets a reference to the `django.views.generic.edit` module. */
DataFlow::Node edit() { result = generic_attr("edit") }
/** Provides models for the `django.views.generic.edit` module */
module edit {
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.edit` module.
* WARNING: Only holds for a few predefined attributes.
*/
private DataFlow::Node edit_attr(DataFlow::TypeTracker t, string attr_name) {
attr_name in ["CreateView", "DeleteView", "FormView", "UpdateView"] and
(
t.start() and
result = DataFlow::importNode("django.views.generic.edit" + "." + attr_name)
or
t.startInAttr(attr_name) and
result = edit()
)
or
// Due to bad performance when using normal setup with `edit_attr(t2, attr_name).track(t2, t)`
// we have inlined that code and forced a join
exists(DataFlow::TypeTracker t2 |
exists(DataFlow::StepSummary summary |
edit_attr_first_join(t2, attr_name, result, summary) and
t = t2.append(summary)
)
)
}
pragma[nomagic]
private predicate edit_attr_first_join(
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res,
DataFlow::StepSummary summary
) {
DataFlow::StepSummary::step(edit_attr(t2, attr_name), res, summary)
}
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.edit` module.
* WARNING: Only holds for a few predefined attributes.
*/
DataFlow::Node edit_attr(string attr_name) {
result = edit_attr(DataFlow::TypeTracker::end(), attr_name)
}
}
// -------------------------------------------------------------------------
// django.views.generic.list
// -------------------------------------------------------------------------
/** Gets a reference to the `django.views.generic.list` module. */
DataFlow::Node list() { result = generic_attr("list") }
/** Provides models for the `django.views.generic.list` module */
module list {
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.list` module.
* WARNING: Only holds for a few predefined attributes.
*/
private DataFlow::Node list_attr(DataFlow::TypeTracker t, string attr_name) {
attr_name in ["ListView"] and
(
t.start() and
result = DataFlow::importNode("django.views.generic.list" + "." + attr_name)
or
t.startInAttr(attr_name) and
result = list()
)
or
// Due to bad performance when using normal setup with `list_attr(t2, attr_name).track(t2, t)`
// we have inlined that code and forced a join
exists(DataFlow::TypeTracker t2 |
exists(DataFlow::StepSummary summary |
list_attr_first_join(t2, attr_name, result, summary) and
t = t2.append(summary)
)
)
}
pragma[nomagic]
private predicate list_attr_first_join(
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res,
DataFlow::StepSummary summary
) {
DataFlow::StepSummary::step(list_attr(t2, attr_name), res, summary)
}
/**
* Gets a reference to the attribute `attr_name` of the `django.views.generic.list` module.
* WARNING: Only holds for a few predefined attributes.
*/
DataFlow::Node list_attr(string attr_name) {
result = list_attr(DataFlow::TypeTracker::end(), attr_name)
}
}
/**
* Provides models for the `django.views.generic.View` class and subclasses.
*
@@ -1634,9 +1884,27 @@ private module Django {
"DeleteView", "ListView"
])
or
// `django.views.View` alias
// aliases
t.start() and
result = views_attr("View")
(
// django.views.View
result = views_attr("View")
or
// django.views.generic.base.*
result = base::base_attr(_)
or
// django.views.generic.dates.*
result = dates::dates_attr(_)
or
// django.views.generic.detail.*
result = detail::detail_attr(_)
or
// django.views.generic.edit.*
result = edit::edit_attr(_)
or
// django.views.generic.list.*
result = list::list_attr(_)
)
or
// subclasses in project code
result.asExpr().(ClassExpr).getABase() = subclassRef(t.continue()).asExpr()

View File

@@ -32,7 +32,7 @@ private class ExpatCreateParser extends TaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof ExpatParser }
string toString() { result = "expat.create.parser" }
override string toString() { result = "expat.create.parser" }
}
private FunctionObject xmlFromString() {

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

View File

@@ -0,0 +1,18 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow

View File

@@ -0,0 +1 @@
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency

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