mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
Merge branch 'main' into port-url-redirect-query
This commit is contained in:
@@ -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 }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,3 +25,4 @@ private import implementations.StdString
|
||||
private import implementations.Swap
|
||||
private import implementations.GetDelim
|
||||
private import implementations.SmartPointer
|
||||
private import implementations.Sscanf
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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
|
||||
|
||||
72
cpp/ql/src/semmle/code/cpp/models/implementations/Sscanf.qll
Normal file
72
cpp/ql/src/semmle/code/cpp/models/implementations/Sscanf.qll
Normal 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()
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
3
csharp/change-notes/2021-01-27-Add-binary-pattern.md
Normal file
3
csharp/change-notes/2021-01-27-Add-binary-pattern.md
Normal file
@@ -0,0 +1,3 @@
|
||||
lgtm,codescanning
|
||||
* The `BinaryPatternExpr` class has been added to support C# 9 `and` and `or`
|
||||
patterns.
|
||||
@@ -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.")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,6 +566,4 @@ class IndexerProperty extends Property {
|
||||
// ```
|
||||
result.getIndexer() = i
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "IndexerProperty" }
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 | ...; |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 | {...} |
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
22
csharp/ql/test/library-tests/csharp9/BinaryPattern.cs
Normal file
22
csharp/ql/test/library-tests/csharp9/BinaryPattern.cs
Normal 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"
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
4
csharp/ql/test/library-tests/csharp9/binaryPattern.ql
Normal file
4
csharp/ql/test/library-tests/csharp9/binaryPattern.ql
Normal file
@@ -0,0 +1,4 @@
|
||||
import csharp
|
||||
|
||||
from BinaryPatternExpr pattern
|
||||
select pattern, pattern.getLeftOperand(), pattern.getRightOperand()
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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] {...}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add 'and_pattern_expr' and 'or_pattern_expr' to the list of 'expr' types.
|
||||
compatibility: backwards
|
||||
@@ -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
|
||||
~~~~~~~~
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
17
javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/react.js
vendored
Normal file
17
javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/react.js
vendored
Normal 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
|
||||
@@ -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 |
|
||||
|
||||
17
javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/react.js
vendored
Normal file
17
javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/react.js
vendored
Normal 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
|
||||
@@ -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. */
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -0,0 +1 @@
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -0,0 +1,18 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
missingToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
@@ -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
Reference in New Issue
Block a user