Merge remote-tracking branch 'upstream/main' into SimpleRangeAnalysis-guard-overflow

This commit is contained in:
Jonas Jensen
2020-10-12 14:29:09 +02:00
367 changed files with 30787 additions and 4321 deletions

View File

@@ -7,3 +7,5 @@ paths-ignore:
- '/cpp/'
- '/java/'
- '/python/'
- '/javascript/ql/test'
- '/javascript/extractor/tests'

View File

@@ -3,6 +3,8 @@
## General improvements
* Support for the following frameworks and libraries has been improved:
- [AWS Serverless](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
- [Alibaba Serverless](https://www.alibabacloud.com/help/doc-detail/156876.htm)
- [bluebird](https://www.npmjs.com/package/bluebird)
- [express](https://www.npmjs.com/package/express)
- [fast-json-stable-stringify](https://www.npmjs.com/package/fast-json-stable-stringify)

View File

@@ -62,6 +62,14 @@
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
],
"Bound Java/C#": [
"java/ql/src/semmle/code/java/dataflow/Bound.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/Bound.qll"
],
"ModulusAnalysis Java/C#": [
"java/ql/src/semmle/code/java/dataflow/ModulusAnalysis.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/ModulusAnalysis.qll"
],
"C++ SubBasicBlocks": [
"cpp/ql/src/semmle/code/cpp/controlflow/SubBasicBlocks.qll",
"cpp/ql/src/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll"

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Autobuild.Cpp</AssemblyName>
<RootNamespace>Semmle.Autobuild.Cpp</RootNamespace>
<ApplicationIcon />

View File

@@ -0,0 +1,14 @@
lgtm,codescanning
* The `SimpleRangeAnalysis` library has gained support for several language
constructs it did not support previously. These improvements primarily affect
the queries `cpp/constant-comparison`, `cpp/comparison-with-wider-type`, and
`cpp/integer-multiplication-cast-to-long`. The newly supported language
features are:
* Multiplication of unsigned numbers.
* Multiplication by a constant.
* Reference-typed function parameters.
* Comparing a variable not equal to an endpoint of its range, thus narrowing the range by one.
* Using `if (x)` or `if (!x)` or similar to test for equality to zero.
* The `SimpleRangeAnalysis` library can now be extended with custom rules. See
examples in
`cpp/ql/src/experimental/semmle/code/cpp/rangeanalysis/extensions/`.

View File

@@ -23,10 +23,7 @@ import semmle.code.cpp.security.TaintTracking
* ```
*/
predicate sourceSized(FunctionCall fc, Expr src) {
exists(string name |
(name = "strncpy" or name = "strncat" or name = "memcpy" or name = "memmove") and
fc.getTarget().hasGlobalOrStdName(name)
) and
fc.getTarget().hasGlobalOrStdName(["strncpy", "strncat", "memcpy", "memmove"]) and
exists(Expr dest, Expr size, Variable v |
fc.getArgument(0) = dest and
fc.getArgument(1) = src and

View File

@@ -15,12 +15,7 @@
import cpp
class Allocation extends FunctionCall {
Allocation() {
exists(string name |
this.getTarget().hasGlobalOrStdName(name) and
(name = "malloc" or name = "calloc" or name = "realloc")
)
}
Allocation() { this.getTarget().hasGlobalOrStdName(["malloc", "calloc", "realloc"]) }
private string getName() { this.getTarget().hasGlobalOrStdName(result) }

View File

@@ -13,14 +13,7 @@
import cpp
class ForbiddenFunction extends Function {
ForbiddenFunction() {
exists(string name | name = this.getName() |
name = "setjmp" or
name = "longjmp" or
name = "sigsetjmp" or
name = "siglongjmp"
)
}
ForbiddenFunction() { this.getName() = ["setjmp", "longjmp", "sigsetjmp", "siglongjmp"] }
}
from FunctionCall call

View File

@@ -40,9 +40,7 @@ class DateStructModifiedFieldAccess extends LeapYearFieldAccess {
*/
class SafeTimeGatheringFunction extends Function {
SafeTimeGatheringFunction() {
this.getQualifiedName() = "GetFileTime" or
this.getQualifiedName() = "GetSystemTime" or
this.getQualifiedName() = "NtQuerySystemTime"
this.getQualifiedName() = ["GetFileTime", "GetSystemTime", "NtQuerySystemTime"]
}
}
@@ -51,15 +49,11 @@ class SafeTimeGatheringFunction extends Function {
*/
class TimeConversionFunction extends Function {
TimeConversionFunction() {
this.getQualifiedName() = "FileTimeToSystemTime" or
this.getQualifiedName() = "SystemTimeToFileTime" or
this.getQualifiedName() = "SystemTimeToTzSpecificLocalTime" or
this.getQualifiedName() = "SystemTimeToTzSpecificLocalTimeEx" or
this.getQualifiedName() = "TzSpecificLocalTimeToSystemTime" or
this.getQualifiedName() = "TzSpecificLocalTimeToSystemTimeEx" or
this.getQualifiedName() = "RtlLocalTimeToSystemTime" or
this.getQualifiedName() = "RtlTimeToSecondsSince1970" or
this.getQualifiedName() = "_mkgmtime"
this.getQualifiedName() =
["FileTimeToSystemTime", "SystemTimeToFileTime", "SystemTimeToTzSpecificLocalTime",
"SystemTimeToTzSpecificLocalTimeEx", "TzSpecificLocalTimeToSystemTime",
"TzSpecificLocalTimeToSystemTimeEx", "RtlLocalTimeToSystemTime",
"RtlTimeToSecondsSince1970", "_mkgmtime"]
}
}

View File

@@ -10,13 +10,8 @@ import cpp
*/
class SALMacro extends Macro {
SALMacro() {
exists(string filename | filename = this.getFile().getBaseName() |
filename = "sal.h" or
filename = "specstrings_strict.h" or
filename = "specstrings.h" or
filename = "w32p.h" or
filename = "minwindef.h"
) and
this.getFile().getBaseName() =
["sal.h", "specstrings_strict.h", "specstrings.h", "w32p.h", "minwindef.h"] and
(
// Dialect for Windows 8 and above
this.getName().matches("\\_%\\_")
@@ -58,10 +53,7 @@ class SALAnnotation extends MacroInvocation {
*/
class SALCheckReturn extends SALAnnotation {
SALCheckReturn() {
exists(SALMacro m | m = this.getMacro() |
m.getName() = "_Check_return_" or
m.getName() = "_Must_inspect_result_"
)
this.getMacro().(SALMacro).getName() = ["_Check_return_", "_Must_inspect_result_"]
}
}

View File

@@ -56,7 +56,7 @@ class VarargsFunction extends Function {
}
string normalTerminator(int cnt) {
(result = "0" or result = "-1") and
result = ["0", "-1"] and
cnt = trailingArgValueCount(result) and
2 * cnt > totalCount() and
not exists(FunctionCall fc, int index |

View File

@@ -66,10 +66,7 @@ class IFStream extends Type {
*/
class CinVariable extends NamespaceVariable {
CinVariable() {
(
getName() = "cin" or
getName() = "wcin"
) and
getName() = ["cin", "wcin"] and
getNamespace().getName() = "std"
}
}

View File

@@ -14,12 +14,7 @@ import cpp
predicate potentiallyDangerousFunction(Function f, string message) {
exists(string name | f.hasGlobalName(name) |
(
name = "gmtime" or
name = "localtime" or
name = "ctime" or
name = "asctime"
) and
name = ["gmtime", "localtime", "ctime", "asctime"] and
message = "Call to " + name + " is potentially dangerous"
)
}

View File

@@ -19,12 +19,7 @@ predicate worldWritableCreation(FileCreationExpr fc, int mode) {
}
predicate setWorldWritable(FunctionCall fc, int mode) {
exists(string name | fc.getTarget().getName() = name |
name = "chmod" or
name = "fchmod" or
name = "_chmod" or
name = "_wchmod"
) and
fc.getTarget().getName() = ["chmod", "fchmod", "_chmod", "_wchmod"] and
mode = fc.getArgument(1).getValue().toInt() and
sets(mode, s_iwoth())
}

View File

@@ -31,11 +31,7 @@ predicate sets(int mask, int fields) { mask.bitAnd(fields) != 0 }
* one of the `umask` family of functions.
*/
private int umask(FunctionCall fc) {
exists(string name | name = fc.getTarget().getName() |
name = "umask" or
name = "_umask" or
name = "_umask_s"
) and
fc.getTarget().getName() = ["umask", "_umask", "_umask_s"] and
result = fc.getArgument(0).getValue().toInt()
}
@@ -89,11 +85,7 @@ abstract class FileCreationExpr extends FunctionCall {
class OpenCreationExpr extends FileCreationExpr {
OpenCreationExpr() {
exists(string name | name = this.getTarget().getName() |
name = "open" or
name = "_open" or
name = "_wopen"
) and
this.getTarget().getName() = ["open", "_open", "_wopen"] and
sets(this.getArgument(1).getValue().toInt(), o_creat())
}
@@ -134,14 +126,9 @@ private int fopenMode() {
class FopenCreationExpr extends FileCreationExpr {
FopenCreationExpr() {
exists(string name | name = this.getTarget().getName() |
name = "fopen" or
name = "_wfopen" or
name = "fsopen" or
name = "_wfsopen"
) and
this.getTarget().getName() = ["fopen", "_wfopen", "fsopen", "_wfsopen"] and
exists(string mode |
(mode = "w" or mode = "a") and
mode = ["w", "a"] and
this.getArgument(1).getValue().matches(mode + "%")
)
}

View File

@@ -2,3 +2,4 @@ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
//
// Import each extension we want to enable
import extensions.SubtractSelf
import extensions.ConstantBitwiseAndExprRange

View File

@@ -0,0 +1,90 @@
private import cpp
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
/**
* Holds if `e` is a constant or if it is a variable with a constant value
*/
float evaluateConstantExpr(Expr e) {
result = e.getValue().toFloat()
or
exists(SsaDefinition defn, StackVariable sv |
defn.getAUse(sv) = e and
result = defn.getDefiningValue(sv).getValue().toFloat()
)
}
/**
* The current implementation for `BitwiseAndExpr` only handles cases where both operands are
* either unsigned or non-negative constants. This class not only covers these cases, but also
* adds support for `&` expressions between a signed integer with a non-negative range and a
* non-negative constant. It also adds support for `&=` for the same set of cases as `&`.
*/
private class ConstantBitwiseAndExprRange extends SimpleRangeAnalysisExpr {
ConstantBitwiseAndExprRange() {
exists(Expr l, Expr r |
l = this.(BitwiseAndExpr).getLeftOperand() and
r = this.(BitwiseAndExpr).getRightOperand()
or
l = this.(AssignAndExpr).getLValue() and
r = this.(AssignAndExpr).getRValue()
|
// No operands can be negative constants
not (evaluateConstantExpr(l) < 0 or evaluateConstantExpr(r) < 0) and
// At least one operand must be a non-negative constant
(evaluateConstantExpr(l) >= 0 or evaluateConstantExpr(r) >= 0)
)
}
Expr getLeftOperand() {
result = this.(BitwiseAndExpr).getLeftOperand() or
result = this.(AssignAndExpr).getLValue()
}
Expr getRightOperand() {
result = this.(BitwiseAndExpr).getRightOperand() or
result = this.(AssignAndExpr).getRValue()
}
override float getLowerBounds() {
// If an operand can have negative values, the lower bound is unconstrained.
// Otherwise, the lower bound is zero.
exists(float lLower, float rLower |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
(
(lLower < 0 or rLower < 0) and
result = exprMinVal(this)
or
// This technically results in two lowerBounds when an operand range is negative, but
// that's fine since `exprMinVal(x) <= 0`. We can't use an if statement here without
// non-monotonic recursion issues
result = 0
)
)
}
override float getUpperBounds() {
// If an operand can have negative values, the upper bound is unconstrained.
// Otherwise, the upper bound is the minimum of the upper bounds of the operands
exists(float lLower, float lUpper, float rLower, float rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
(
(lLower < 0 or rLower < 0) and
result = exprMaxVal(this)
or
// This technically results in two upperBounds when an operand range is negative, but
// that's fine since `exprMaxVal(b) >= result`. We can't use an if statement here without
// non-monotonic recursion issues
result = rUpper.minimum(lUpper)
)
)
}
override predicate dependsOnChild(Expr child) {
child = getLeftOperand() or child = getRightOperand()
}
}

View File

@@ -18,6 +18,6 @@ import cpp
from File f
where
(f.getExtension().toLowerCase() = "h" or f.getExtension().toLowerCase() = "hpp") and
f.getExtension().toLowerCase() = ["h", "hpp"] and
f.getExtension() != "h"
select f, "AV Rule 53: Header files will always have a file name extension of .h."

View File

@@ -21,8 +21,8 @@ import cpp
*/
class WarningLateTemplateSpecialization extends CompilerWarning {
WarningLateTemplateSpecialization() {
this.getTag() = "partial_spec_after_instantiation" or
this.getTag() = "partial_spec_after_instantiation_ambiguous"
this.getTag() =
["partial_spec_after_instantiation", "partial_spec_after_instantiation_ambiguous"]
}
}

View File

@@ -29,7 +29,7 @@ private predicate readsEnvironment(Expr read, string sourceDescription) {
exists(FunctionCall call, string name |
read = call and
call.getTarget().hasGlobalOrStdName(name) and
(name = "getenv" or name = "secure_getenv" or name = "_wgetenv") and
name = ["getenv", "secure_getenv", "_wgetenv"] and
sourceDescription = name
)
}

View File

@@ -9,10 +9,7 @@ import semmle.code.cpp.models.interfaces.FormattingFunction
import semmle.code.cpp.models.implementations.Printf
class PrintfFormatAttribute extends FormatAttribute {
PrintfFormatAttribute() {
getArchetype() = "printf" or
getArchetype() = "__printf__"
}
PrintfFormatAttribute() { getArchetype() = ["printf", "__printf__"] }
}
/**
@@ -601,12 +598,12 @@ class FormatLiteral extends Literal {
or
len = "l" and result = this.getLongType()
or
(len = "ll" or len = "L" or len = "q") and
len = ["ll", "L", "q"] and
result instanceof LongLongType
or
len = "j" and result = this.getIntmax_t()
or
(len = "z" or len = "Z") and
len = ["z", "Z"] and
(result = this.getSize_t() or result = this.getSsize_t())
or
len = "t" and result = this.getPtrdiff_t()
@@ -639,12 +636,12 @@ class FormatLiteral extends Literal {
or
len = "l" and result = this.getLongType()
or
(len = "ll" or len = "L" or len = "q") and
len = ["ll", "L", "q"] and
result instanceof LongLongType
or
len = "j" and result = this.getIntmax_t()
or
(len = "z" or len = "Z") and
len = ["z", "Z"] and
(result = this.getSize_t() or result = this.getSsize_t())
or
len = "t" and result = this.getPtrdiff_t()
@@ -670,9 +667,7 @@ class FormatLiteral extends Literal {
FloatingPointType getFloatingPointConversion(int n) {
exists(string len |
len = this.getLength(n) and
if len = "L" or len = "ll"
then result instanceof LongDoubleType
else result instanceof DoubleType
if len = ["L", "ll"] then result instanceof LongDoubleType else result instanceof DoubleType
)
}
@@ -689,7 +684,7 @@ class FormatLiteral extends Literal {
or
len = "l" and base = this.getLongType()
or
(len = "ll" or len = "L") and
len = ["ll", "L"] and
base instanceof LongLongType
or
len = "q" and base instanceof LongLongType
@@ -736,12 +731,12 @@ class FormatLiteral extends Literal {
exists(string len, string conv |
this.parseConvSpec(n, _, _, _, _, _, len, conv) and
(
(conv = "c" or conv = "C") and
conv = ["c", "C"] and
len = "h" and
result instanceof PlainCharType
or
(conv = "c" or conv = "C") and
(len = "l" or len = "w") and
conv = ["c", "C"] and
len = ["l", "w"] and
result = getWideCharType()
or
conv = "c" and
@@ -781,12 +776,12 @@ class FormatLiteral extends Literal {
exists(string len, string conv |
this.parseConvSpec(n, _, _, _, _, _, len, conv) and
(
(conv = "s" or conv = "S") and
conv = ["s", "S"] and
len = "h" and
result.(PointerType).getBaseType() instanceof PlainCharType
or
(conv = "s" or conv = "S") and
(len = "l" or len = "w") and
conv = ["s", "S"] and
len = ["l", "w"] and
result.(PointerType).getBaseType() = getWideCharType()
or
conv = "s" and
@@ -823,10 +818,7 @@ class FormatLiteral extends Literal {
private Type getConversionType9(int n) {
this.getConversionChar(n) = "Z" and
(
this.getLength(n) = "l" or
this.getLength(n) = "w"
) and
this.getLength(n) = ["l", "w"] and
exists(Type t |
t.getName() = "UNICODE_STRING" and
result.(PointerType).getBaseType() = t
@@ -979,10 +971,7 @@ class FormatLiteral extends Literal {
len = (afterdot.maximum(1) + 6).maximum(1 + 1 + dot + afterdot + 1 + 1 + 3)
) // (e.g. "-1.59203e-319")
or
(
this.getConversionChar(n).toLowerCase() = "d" or
this.getConversionChar(n).toLowerCase() = "i"
) and
this.getConversionChar(n).toLowerCase() = ["d", "i"] and
// e.g. -2^31 = "-2147483648"
exists(int sizeBits |
sizeBits =

View File

@@ -8,14 +8,13 @@ import cpp
*/
class StrcatFunction extends Function {
StrcatFunction() {
exists(string name | name = getName() |
name = "strcat" or // strcat(dst, src)
name = "strncat" or // strncat(dst, src, max_amount)
name = "wcscat" or // wcscat(dst, src)
name = "_mbscat" or // _mbscat(dst, src)
name = "wcsncat" or // wcsncat(dst, src, max_amount)
name = "_mbsncat" or // _mbsncat(dst, src, max_amount)
name = "_mbsncat_l" // _mbsncat_l(dst, src, max_amount, locale)
)
getName() =
["strcat", // strcat(dst, src)
"strncat", // strncat(dst, src, max_amount)
"wcscat", // wcscat(dst, src)
"_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)
}
}

View File

@@ -167,4 +167,9 @@ module Consistency {
not isImmutableOrUnobservable(n) and
msg = "ArgumentNode is missing PostUpdateNode."
}
query predicate postWithInFlow(PostUpdateNode n, string msg) {
simpleLocalFlowStep(_, n) and
msg = "PostUpdateNode should not be the target of local flow."
}
}

View File

@@ -167,4 +167,9 @@ module Consistency {
not isImmutableOrUnobservable(n) and
msg = "ArgumentNode is missing PostUpdateNode."
}
query predicate postWithInFlow(PostUpdateNode n, string msg) {
simpleLocalFlowStep(_, n) and
msg = "PostUpdateNode should not be the target of local flow."
}
}

View File

@@ -5,37 +5,60 @@ private import DataFlowDispatch
/**
* A data flow node that occurs as the argument of a call and is passed as-is
* to the callable. Instance arguments (`this` pointer) are also included.
* to the callable. Instance arguments (`this` pointer) and read side effects
* on parameters are also included.
*/
class ArgumentNode extends InstructionNode {
ArgumentNode() {
exists(CallInstruction call |
instr = call.getAnArgument()
or
instr.(ReadSideEffectInstruction).getPrimaryInstruction() = call
)
}
abstract class ArgumentNode extends OperandNode {
/**
* Holds if this argument occurs at the given position in the given call.
* The instance argument is considered to have index `-1`.
*/
predicate argumentOf(DataFlowCall call, int pos) {
instr = call.getPositionalArgument(pos)
or
instr = call.getThisArgument() and pos = -1
or
exists(ReadSideEffectInstruction read |
read = instr and
read.getPrimaryInstruction() = call and
pos = getArgumentPosOfSideEffect(read.getIndex())
)
}
abstract predicate argumentOf(DataFlowCall call, int pos);
/** Gets the call in which this node is an argument. */
DataFlowCall getCall() { this.argumentOf(result, _) }
}
/**
* A data flow node that occurs as the argument to a call, or an
* implicit `this` pointer argument.
*/
private class PrimaryArgumentNode extends ArgumentNode {
override ArgumentOperand op;
PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) }
override predicate argumentOf(DataFlowCall call, int pos) {
op = call.getPositionalArgumentOperand(pos)
or
op = call.getThisArgumentOperand() and pos = -1
}
override string toString() {
result = "Argument " + op.(PositionalArgumentOperand).getIndex()
or
op instanceof ThisArgumentOperand and result = "This argument"
}
}
/**
* A data flow node representing the read side effect of a call on a
* specific parameter.
*/
private class SideEffectArgumentNode extends ArgumentNode {
override SideEffectOperand op;
ReadSideEffectInstruction read;
SideEffectArgumentNode() { op = read.getSideEffectOperand() }
override predicate argumentOf(DataFlowCall call, int pos) {
read.getPrimaryInstruction() = call and
pos = getArgumentPosOfSideEffect(read.getIndex())
}
override string toString() { result = "Argument " + read.getIndex() + " indirection" }
}
private newtype TReturnKind =
TNormalReturnKind() or
TIndirectReturnKind(ParameterIndex index)

View File

@@ -505,18 +505,6 @@ class DefinitionByReferenceNode extends InstructionNode {
}
}
/**
* A node representing the memory pointed to by a function argument.
*
* This class exists only in order to override `toString`, which would
* otherwise be the default implementation inherited from `InstructionNode`.
*/
private class ArgumentIndirectionNode extends InstructionNode {
override ReadSideEffectInstruction instr;
override string toString() { result = "Argument " + instr.getIndex() + " indirection" }
}
/**
* A `Node` corresponding to a variable in the program, as opposed to the
* value of that variable at some particular point. This can be used for
@@ -680,10 +668,6 @@ private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo
or
iTo.(PhiInstruction).getAnInputOperand() = opFrom
or
// A read side effect is almost never exact since we don't know exactly how
// much memory the callee will read.
iTo.(ReadSideEffectInstruction).getSideEffectOperand() = opFrom
or
// Treat all conversions as flow, even conversions between different numeric types.
iTo.(ConvertInstruction).getUnaryOperand() = opFrom
or

View File

@@ -17,6 +17,7 @@ private import implementations.Strftime
private import implementations.StdContainer
private import implementations.StdPair
private import implementations.StdMap
private import implementations.StdSet
private import implementations.StdString
private import implementations.Swap
private import implementations.GetDelim

View File

@@ -16,11 +16,10 @@ import semmle.code.cpp.models.interfaces.FlowSource
class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
SideEffectFunction, RemoteFlowFunction {
GetsFunction() {
exists(string name | hasGlobalOrStdName(name) |
name = "gets" or // gets(str)
name = "fgets" or // fgets(str, num, stream)
name = "fgetws" // fgetws(wstr, num, stream)
)
// gets(str)
// fgets(str, num, stream)
// fgetws(wstr, num, stream)
hasGlobalOrStdName(["gets", "fgets", "fgetws"])
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {

View File

@@ -4,16 +4,13 @@ import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.SideEffect
/**
* The standard function templates `std::move` and `std::identity`
* The standard function templates `std::move` and `std::forward`.
*/
class IdentityFunction extends DataFlowFunction, SideEffectFunction, AliasFunction {
IdentityFunction() {
this.getNamespace().getParentNamespace() instanceof GlobalNamespace and
this.getNamespace().getName() = "std" and
(
this.getName() = "move" or
this.getName() = "forward"
)
this.getName() = ["move", "forward"]
}
override predicate hasOnlySpecificReadSideEffects() { any() }

View File

@@ -280,7 +280,9 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, Iterato
*/
class BeginOrEndFunction extends MemberFunction, TaintFunction {
BeginOrEndFunction() {
this.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) and
this
.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend",
"before_begin", "cbefore_begin"]) and
this.getType().getUnspecifiedType() instanceof Iterator
}

View File

@@ -170,26 +170,6 @@ class StdSequenceContainerAssign extends TaintFunction {
}
}
/**
* The standard container `begin` and `end` functions and their
* variants.
*/
class StdSequenceContainerBeginEnd extends TaintFunction {
StdSequenceContainerBeginEnd() {
this
.hasQualifiedName("std", ["array", "vector", "deque", "list"],
["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) or
this
.hasQualifiedName("std", "forward_list",
["before_begin", "begin", "end", "cbefore_begin", "cbegin", "cend"])
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
}
}
/**
* The standard container `swap` functions.
*/

View File

@@ -5,6 +5,33 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.implementations.Iterator
/**
* Additional model for map constructors using iterator inputs.
*/
class StdMapConstructor extends Constructor, TaintFunction {
StdMapConstructor() {
this.hasQualifiedName("std", "map", "map") or
this.hasQualifiedName("std", "unordered_map", "unordered_map")
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() {
getParameter(result).getUnspecifiedType() instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of an iterator type to the qualifier
input.isParameterDeref(getAnIteratorParameterIndex()) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
output.isQualifierObject()
)
}
}
/**
* The standard map `insert` and `insert_or_assign` functions.
*/

View File

@@ -0,0 +1,92 @@
/**
* Provides models for C++ containers `std::set` and `std::unordered_set`.
*/
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.implementations.Iterator
/**
* Additional model for set constructors using iterator inputs.
*/
class StdSetConstructor extends Constructor, TaintFunction {
StdSetConstructor() {
this.hasQualifiedName("std", "set", "set") or
this.hasQualifiedName("std", "unordered_set", "unordered_set")
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() {
getParameter(result).getUnspecifiedType() instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of an iterator type to the qualifier
input.isParameterDeref(getAnIteratorParameterIndex()) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
output.isQualifierObject()
)
}
}
/**
* The standard set `insert` and `insert_or_assign` functions.
*/
class StdSetInsert extends TaintFunction {
StdSetInsert() { this.hasQualifiedName("std", ["set", "unordered_set"], "insert") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from last parameter to qualifier and return value
// (where the return value is a pair, this should really flow just to the first part of it)
input.isParameterDeref(getNumberOfParameters() - 1) and
(
output.isQualifierObject() or
output.isReturnValue()
)
}
}
/**
* The standard set `swap` functions.
*/
class StdSetSwap extends TaintFunction {
StdSetSwap() { this.hasQualifiedName("std", ["set", "unordered_set"], "swap") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// container1.swap(container2)
input.isQualifierObject() and
output.isParameterDeref(0)
or
input.isParameterDeref(0) and
output.isQualifierObject()
}
}
/**
* The standard set `find` function.
*/
class StdSetFind extends TaintFunction {
StdSetFind() { this.hasQualifiedName("std", ["set", "unordered_set"], "find") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
}
}
/**
* The standard set `erase` function.
*/
class StdSetErase extends TaintFunction {
StdSetErase() { this.hasQualifiedName("std", ["set", "unordered_set"], "erase") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to iterator return value
getType().getUnderlyingType() instanceof Iterator and
input.isQualifierObject() and
output.isReturnValue()
}
}

View File

@@ -13,43 +13,24 @@ import semmle.code.cpp.models.interfaces.SideEffect
*/
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction {
StrcpyFunction() {
exists(string name | name = getName() |
// strcpy(dst, src)
name = "strcpy"
or
// wcscpy(dst, src)
name = "wcscpy"
or
// _mbscpy(dst, src)
name = "_mbscpy"
or
(
name = "strcpy_s" or // strcpy_s(dst, max_amount, src)
name = "wcscpy_s" or // wcscpy_s(dst, max_amount, src)
name = "_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
or
// strncpy(dst, src, max_amount)
name = "strncpy"
or
// _strncpy_l(dst, src, max_amount, locale)
name = "_strncpy_l"
or
// wcsncpy(dst, src, max_amount)
name = "wcsncpy"
or
// _wcsncpy_l(dst, src, max_amount, locale)
name = "_wcsncpy_l"
or
// _mbsncpy(dst, src, max_amount)
name = "_mbsncpy"
or
// _mbsncpy_l(dst, src, max_amount, locale)
name = "_mbsncpy_l"
)
getName() =
["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)
"_wcsncpy_l", // _wcsncpy_l(dst, src, max_amount, locale)
"_mbsncpy", // _mbsncpy(dst, src, max_amount)
"_mbsncpy_l"] // _mbsncpy_l(dst, src, max_amount, locale)
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)
// exclude the 2-parameter template versions
// that find the size of a fixed size destination buffer.
getNumberOfParameters() = 3
}
/**

View File

@@ -460,6 +460,39 @@ private predicate isRecursiveDef(RangeSsaDefinition def, StackVariable v) {
defDependsOnDefTransitively(def, v, def, v)
}
/**
* Holds if the bounds of `e` depend on a recursive definition, meaning that
* `e` is likely to have many candidate bounds during the main recursion.
*/
private predicate isRecursiveExpr(Expr e) {
exists(RangeSsaDefinition def, StackVariable v | exprDependsOnDef(e, def, v) |
isRecursiveDef(def, v)
)
}
/**
* Holds if `binop` is a binary operation that's likely to be assigned a
* quadratic (or more) number of candidate bounds during the analysis. This can
* happen when two conditions are satisfied:
* 1. It is likely there are many more candidate bounds for `binop` than for
* its operands. For example, the number of candidate bounds for `x + y`,
* denoted here nbounds(`x + y`), will be O(nbounds(`x`) * nbounds(`y`)).
* In contrast, nbounds(`b ? x : y`) is only O(nbounds(`x`) + nbounds(`y`)).
* 2. Both operands of `binop` are recursively determined and are therefore
* likely to have a large number of candidate bounds.
*/
private predicate isRecursiveBinary(BinaryOperation binop) {
(
binop instanceof UnsignedMulExpr
or
binop instanceof AddExpr
or
binop instanceof SubExpr
) and
isRecursiveExpr(binop.getLeftOperand()) and
isRecursiveExpr(binop.getRightOperand())
}
/**
* We distinguish 3 kinds of RangeSsaDefinition:
*
@@ -581,7 +614,16 @@ private float getTruncatedLowerBounds(Expr expr) {
// overflow, so we replace invalid bounds with exprMinVal.
exists(float newLB | newLB = normalizeFloatUp(getLowerBoundsImpl(expr)) |
if exprMinVal(expr) <= newLB and newLB <= exprMaxVal(expr)
then result = newLB
then
// Apply widening where we might get a combinatorial explosion.
if isRecursiveBinary(expr)
then
result =
max(float widenLB |
widenLB = wideningLowerBounds(expr.getUnspecifiedType()) and
not widenLB > newLB
)
else result = newLB
else result = exprMinVal(expr)
)
or
@@ -628,7 +670,16 @@ private float getTruncatedUpperBounds(Expr expr) {
// `exprMaxVal`.
exists(float newUB | newUB = normalizeFloatUp(getUpperBoundsImpl(expr)) |
if exprMinVal(expr) <= newUB and newUB <= exprMaxVal(expr)
then result = newUB
then
// Apply widening where we might get a combinatorial explosion.
if isRecursiveBinary(expr)
then
result =
min(float widenUB |
widenUB = wideningUpperBounds(expr.getUnspecifiedType()) and
not widenUB < newUB
)
else result = newUB
else result = exprMaxVal(expr)
)
or

View File

@@ -354,11 +354,10 @@ class SnprintfBW extends BufferWriteCall {
*/
class GetsBW extends BufferWriteCall {
GetsBW() {
exists(TopLevelFunction fn, string name | fn = getTarget() and name = fn.getName() |
name = "gets" or // gets(dst)
name = "fgets" or // fgets(dst, max_amount, src_stream)
name = "fgetws" // fgetws(dst, max_amount, src_stream)
)
getTarget().(TopLevelFunction).getName() =
["gets", // gets(dst)
"fgets", // fgets(dst, max_amount, src_stream)
"fgetws"] // fgetws(dst, max_amount, src_stream)
}
/**

View File

@@ -123,9 +123,7 @@ class WriteFunctionCall extends ChainedOutputCall {
private predicate fileStreamChain(ChainedOutputCall out, Expr source, Expr dest) {
source = out.getSource() and
dest = out.getEndDest() and
exists(string nme | nme = "basic_ofstream" or nme = "basic_fstream" |
dest.getUnderlyingType().(Class).getSimpleName() = nme
)
dest.getUnderlyingType().(Class).getSimpleName() = ["basic_ofstream", "basic_fstream"]
}
/**
@@ -139,15 +137,7 @@ private predicate fileWrite(Call write, Expr source, Expr dest) {
// named functions
name = "fwrite" and s = 0 and d = 3
or
(
name = "fputs" or
name = "fputws" or
name = "fputc" or
name = "fputwc" or
name = "putc" or
name = "putwc" or
name = "putw"
) and
name = ["fputs", "fputws", "fputc", "fputwc", "putc", "putwc", "putw"] and
s = 0 and
d = 1
)

View File

@@ -48,10 +48,7 @@ private predicate outputFile(Expr e) {
name = e.(VariableAccess).getTarget().(GlobalVariable).toString() or
name = e.findRootCause().(Macro).getName()
) and
(
name = "stdout" or
name = "stderr"
)
name = ["stdout", "stderr"]
)
}

View File

@@ -252,11 +252,10 @@ private predicate insideFunctionValueMoveTo(Element src, Element dest) {
copyValueBetweenArguments(c.getTarget(), sourceArg, destArg) and
// Only consider copies from `printf`-like functions if the format is a string
(
exists(FormattingFunctionCall ffc, FormatLiteral format, string argFormat |
exists(FormattingFunctionCall ffc, FormatLiteral format |
ffc = c and
format = ffc.getFormat() and
format.getConversionChar(sourceArg - ffc.getTarget().getNumberOfParameters()) = argFormat and
(argFormat = "s" or argFormat = "S")
format.getConversionChar(sourceArg - ffc.getTarget().getNumberOfParameters()) = ["s", "S"]
)
or
not exists(FormatLiteral fl | fl = c.(FormattingFunctionCall).getFormat())
@@ -273,12 +272,12 @@ private predicate insideFunctionValueMoveTo(Element src, Element dest) {
dest = c
)
or
exists(FormattingFunctionCall formattingSend, int arg, FormatLiteral format, string argFormat |
exists(FormattingFunctionCall formattingSend, int arg, FormatLiteral format |
dest = formattingSend and
formattingSend.getArgument(arg) = src and
format = formattingSend.getFormat() and
format.getConversionChar(arg - formattingSend.getTarget().getNumberOfParameters()) = argFormat and
(argFormat = "s" or argFormat = "S" or argFormat = "@")
format.getConversionChar(arg - formattingSend.getTarget().getNumberOfParameters()) =
["s", "S", "@"]
)
or
// Expressions computed from tainted data are also tainted

View File

@@ -65,15 +65,8 @@ class UMLElement extends XMLElement {
*/
class UMLType extends UMLElement {
UMLType() {
exists(string type |
this.getName() = "packagedElement" and
this.getAttribute("type").getValue() = type and
(
type = "uml:Class" or
type = "uml:Interface" or
type = "uml:PrimitiveType"
)
)
this.getName() = "packagedElement" and
this.getAttribute("type").getValue() = ["uml:Class", "uml:Interface", "uml:PrimitiveType"]
}
/**

View File

@@ -0,0 +1,59 @@
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned uint32_t;
typedef signed long long int64_t;
void test_assign_operator(uint8_t x) {
x &= 7; // [0 .. 7]
}
void test_non_negative_const(uint8_t x) {
uint8_t unsigned_const = 7;
// Non-negative range operand and non-negative constant. The operands are promoted
// to signed ints.
x & 0; // [0 .. 0]
x & 7; // [0 .. 7]
x & unsigned_const; // [0 .. 7]
// This tests what happens when both arguments are promoted to `unsigned int` instead
// of `int`, and when the constant is larger than the max bound
x & 0xFFFFFFFF; // [0 .. 255]
}
void test_non_const(uint8_t a, uint8_t b, uint32_t c, uint32_t d) {
if (b <= 100) {
// `a` and `b` are promoted to signed ints, meaning neither the range analysis library
// nor this extension handle it
a & b; // [-2147483648 .. 2147483647]
}
if (d <= 100) {
// Handled by the range analysis library
c & d; // [0 .. 100]
}
}
void test_negative_operand(uint8_t x, int8_t y) {
uint8_t unsigned_const = 7;
int8_t signed_const = -7;
// The right operand can be negative
x & -7; // [-2147483648 .. 2147483647]
x & signed_const; // [-2147483648 .. 2147483647]
x & y; // [-2147483648 .. 2147483647]
// The left operand can be negative
y & 7; // [-2147483648 .. 2147483647]
y & unsigned_const; // [-2147483648 .. 2147483647]
y & 0xFFFFFFFF; // [0 .. 4294967295]
(int64_t)y & 0xFFFFFFFF; // [-9223372036854776000 .. 9223372036854776000]
y & x; // [-2147483648 .. 2147483647]
// Both can be negative
y & -7; // [-2147483648 .. 2147483647]
y & signed_const; // [-2147483648 .. 2147483647]
signed_const & -7; // [-2147483648 .. 2147483647]
signed_const & y; // [-2147483648 .. 2147483647]
-7 & y; // [-2147483648 .. 2147483647]
-7 & signed_const; // [-2147483648 .. 2147483647]
}

View File

@@ -0,0 +1,21 @@
| bitwiseand.cpp:7:3:7:8 | ... &= ... | 0.0 | 7.0 |
| bitwiseand.cpp:15:3:15:7 | ... & ... | 0.0 | 0.0 |
| bitwiseand.cpp:16:3:16:7 | ... & ... | 0.0 | 7.0 |
| bitwiseand.cpp:17:3:17:20 | ... & ... | 0.0 | 7.0 |
| bitwiseand.cpp:21:3:21:16 | ... & ... | 0.0 | 255.0 |
| bitwiseand.cpp:28:5:28:9 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:32:5:32:9 | ... & ... | 0.0 | 100.0 |
| bitwiseand.cpp:41:3:41:8 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:42:3:42:18 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:43:3:43:7 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:46:3:46:7 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:47:3:47:20 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:48:3:48:16 | ... & ... | 0.0 | 4.294967295E9 |
| bitwiseand.cpp:49:3:49:25 | ... & ... | -9.223372036854776E18 | 9.223372036854776E18 |
| bitwiseand.cpp:50:3:50:7 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:53:3:53:8 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:54:3:54:18 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:55:3:55:19 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:56:3:56:18 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:57:3:57:8 | ... & ... | -2.147483648E9 | 2.147483647E9 |
| bitwiseand.cpp:58:3:58:19 | ... & ... | -2.147483648E9 | 2.147483647E9 |

View File

@@ -0,0 +1,8 @@
import experimental.semmle.code.cpp.rangeanalysis.ExtendedRangeAnalysis
from Operation expr, float lower, float upper
where
(expr instanceof BitwiseAndExpr or expr instanceof AssignAndExpr) and
lower = lowerBound(expr) and
upper = upperBound(expr)
select expr, lower, upper

View File

@@ -21,3 +21,69 @@ argHasPostUpdate
| lambdas.cpp:38:2:38:2 | d | ArgumentNode is missing PostUpdateNode. |
| lambdas.cpp:45:2:45:2 | e | ArgumentNode is missing PostUpdateNode. |
| test.cpp:67:29:67:35 | source1 | ArgumentNode is missing PostUpdateNode. |
postWithInFlow
| BarrierGuard.cpp:49:6:49:6 | x [post update] | PostUpdateNode should not be the target of local flow. |
| BarrierGuard.cpp:60:7:60:7 | x [post update] | PostUpdateNode should not be the target of local flow. |
| clang.cpp:22:9:22:20 | sourceArray1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| clang.cpp:28:22:28:23 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| clang.cpp:50:3:50:12 | stackArray [inner post update] | PostUpdateNode should not be the target of local flow. |
| clang.cpp:50:3:50:15 | access to array [post update] | PostUpdateNode should not be the target of local flow. |
| dispatch.cpp:60:3:60:14 | globalBottom [post update] | PostUpdateNode should not be the target of local flow. |
| dispatch.cpp:61:3:61:14 | globalMiddle [post update] | PostUpdateNode should not be the target of local flow. |
| dispatch.cpp:78:24:78:37 | call to allocateBottom [inner post update] | PostUpdateNode should not be the target of local flow. |
| dispatch.cpp:148:5:148:5 | f [post update] | PostUpdateNode should not be the target of local flow. |
| dispatch.cpp:168:8:168:8 | f [post update] | PostUpdateNode should not be the target of local flow. |
| example.c:24:9:24:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
| example.c:24:20:24:20 | y [post update] | PostUpdateNode should not be the target of local flow. |
| example.c:26:9:26:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
| example.c:26:19:26:24 | coords [inner post update] | PostUpdateNode should not be the target of local flow. |
| example.c:28:23:28:25 | pos [inner post update] | PostUpdateNode should not be the target of local flow. |
| globals.cpp:13:5:13:19 | flowTestGlobal1 [post update] | PostUpdateNode should not be the target of local flow. |
| globals.cpp:23:5:23:19 | flowTestGlobal2 [post update] | PostUpdateNode should not be the target of local flow. |
| lambdas.cpp:23:3:23:14 | v [post update] | PostUpdateNode should not be the target of local flow. |
| lambdas.cpp:43:3:43:3 | c [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:11:5:11:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:11:5:11:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:20:5:20:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:22:7:22:9 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:24:7:24:9 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:29:5:29:7 | out [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:31:7:31:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:39:7:39:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:44:5:44:7 | out [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:46:7:46:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:48:7:48:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:75:9:75:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:83:9:83:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:87:11:87:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:89:11:89:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:94:9:94:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:96:11:96:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:104:11:104:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:109:9:109:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:113:11:113:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
| ref.cpp:115:11:115:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:91:3:91:9 | source1 [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:115:3:115:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:115:4:115:6 | out [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:120:3:120:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:120:4:120:6 | out [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:125:3:125:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:125:4:125:6 | out [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:333:5:333:13 | globalVar [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:347:5:347:13 | globalVar [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:359:5:359:9 | field [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:373:5:373:9 | field [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:384:10:384:13 | ref arg & ... | PostUpdateNode should not be the target of local flow. |
| test.cpp:384:11:384:13 | tmp [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:391:10:391:13 | ref arg & ... | PostUpdateNode should not be the target of local flow. |
| test.cpp:391:11:391:13 | tmp [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:400:10:400:13 | ref arg & ... | PostUpdateNode should not be the target of local flow. |
| test.cpp:400:11:400:13 | tmp [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:407:10:407:13 | ref arg & ... | PostUpdateNode should not be the target of local flow. |
| test.cpp:407:11:407:13 | tmp [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:423:21:423:25 | local [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:436:19:436:23 | local [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:465:3:465:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:465:4:465:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:470:22:470:22 | x [inner post update] | PostUpdateNode should not be the target of local flow. |

View File

@@ -30,3 +30,56 @@ uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
| BarrierGuard.cpp:49:3:49:17 | Chi | PostUpdateNode should not be the target of local flow. |
| BarrierGuard.cpp:60:3:60:18 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:28:3:28:34 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:34:22:34:27 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:34:32:34:37 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:39:32:39:37 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:39:42:39:47 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:43:35:43:40 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:43:51:43:51 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:49:25:49:30 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:49:35:49:40 | Chi | PostUpdateNode should not be the target of local flow. |
| clang.cpp:50:3:50:26 | Chi | PostUpdateNode should not be the target of local flow. |
| example.c:17:19:17:22 | Chi | PostUpdateNode should not be the target of local flow. |
| example.c:17:21:17:21 | Chi | PostUpdateNode should not be the target of local flow. |
| example.c:24:2:24:30 | Chi | PostUpdateNode should not be the target of local flow. |
| example.c:24:13:24:30 | Chi | PostUpdateNode should not be the target of local flow. |
| example.c:26:2:26:25 | Chi | PostUpdateNode should not be the target of local flow. |
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
| lambdas.cpp:13:12:13:12 | Chi | PostUpdateNode should not be the target of local flow. |
| lambdas.cpp:13:15:13:15 | Chi | PostUpdateNode should not be the target of local flow. |
| lambdas.cpp:28:10:31:2 | Chi | PostUpdateNode should not be the target of local flow. |
| lambdas.cpp:28:10:31:2 | Chi | PostUpdateNode should not be the target of local flow. |
| lambdas.cpp:43:3:43:14 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:11:5:11:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:20:5:20:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:22:7:22:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:24:7:24:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:29:5:29:18 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:31:7:31:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:39:7:39:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:44:5:44:18 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:46:7:46:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:48:7:48:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:75:5:75:17 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:83:5:83:17 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:87:7:87:17 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:89:7:89:17 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:94:5:94:22 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:96:7:96:17 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:104:7:104:17 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:109:5:109:22 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:113:7:113:17 | Chi | PostUpdateNode should not be the target of local flow. |
| ref.cpp:115:7:115:17 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:91:3:91:18 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:115:3:115:17 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:120:3:120:10 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:125:3:125:11 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:359:5:359:20 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:373:5:373:20 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:465:3:465:15 | Chi | PostUpdateNode should not be the target of local flow. |

View File

@@ -39,3 +39,111 @@ argHasPostUpdate
| by_reference.cpp:51:8:51:8 | s | ArgumentNode is missing PostUpdateNode. |
| by_reference.cpp:57:8:57:8 | s | ArgumentNode is missing PostUpdateNode. |
| by_reference.cpp:63:8:63:8 | s | ArgumentNode is missing PostUpdateNode. |
postWithInFlow
| A.cpp:25:13:25:13 | c [post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:27:28:27:28 | c [post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:42:11:42:12 | cc [inner post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:43:11:43:12 | ct [inner post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:100:9:100:9 | a [post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:142:10:142:10 | c [post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:143:13:143:13 | b [post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:183:7:183:10 | head [post update] | PostUpdateNode should not be the target of local flow. |
| A.cpp:184:13:184:16 | next [post update] | PostUpdateNode should not be the target of local flow. |
| B.cpp:35:13:35:17 | elem1 [post update] | PostUpdateNode should not be the target of local flow. |
| B.cpp:36:13:36:17 | elem2 [post update] | PostUpdateNode should not be the target of local flow. |
| B.cpp:46:13:46:16 | box1 [post update] | PostUpdateNode should not be the target of local flow. |
| C.cpp:24:11:24:12 | s3 [post update] | PostUpdateNode should not be the target of local flow. |
| D.cpp:9:21:9:24 | elem [post update] | PostUpdateNode should not be the target of local flow. |
| D.cpp:11:29:11:32 | elem [post update] | PostUpdateNode should not be the target of local flow. |
| D.cpp:16:21:16:23 | box [post update] | PostUpdateNode should not be the target of local flow. |
| D.cpp:18:29:18:31 | box [post update] | PostUpdateNode should not be the target of local flow. |
| D.cpp:30:13:30:16 | elem [post update] | PostUpdateNode should not be the target of local flow. |
| D.cpp:44:19:44:22 | elem [post update] | PostUpdateNode should not be the target of local flow. |
| D.cpp:57:5:57:12 | boxfield [post update] | PostUpdateNode should not be the target of local flow. |
| D.cpp:58:20:58:23 | elem [post update] | PostUpdateNode should not be the target of local flow. |
| E.cpp:33:19:33:19 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:9:6:9:7 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:13:5:13:6 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:17:5:17:6 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:25:18:25:19 | s1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:37:8:37:9 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:42:6:42:7 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:49:9:49:10 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:54:6:54:7 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:60:6:60:7 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:72:5:72:6 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:79:6:79:7 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:86:5:86:6 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:92:7:92:8 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:98:5:98:6 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:106:3:106:5 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:106:4:106:5 | pa [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:111:18:111:19 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:126:15:126:16 | xs [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:136:16:136:17 | xs [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:147:16:147:16 | s [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:147:21:147:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:175:21:175:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:181:21:181:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:187:21:187:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:194:21:194:22 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:200:23:200:24 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:205:23:205:24 | m1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:6:3:6:5 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:6:3:6:8 | access to array [post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:15:3:15:10 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:15:5:15:7 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:36:12:36:14 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:36:19:36:22 | data [post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:37:17:37:19 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:38:17:38:19 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:42:15:42:17 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:42:22:42:25 | data [post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:43:20:43:22 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:44:20:44:22 | arr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:48:15:48:17 | ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:48:22:48:25 | data [post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:49:20:49:22 | ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:50:20:50:22 | ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:12:8:12:8 | a [post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:16:11:16:11 | a [post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:68:18:68:18 | s [inner post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:84:10:84:10 | a [post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:88:9:88:9 | a [post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:92:3:92:5 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:92:4:92:5 | pa [inner post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:96:3:96:4 | pa [post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:102:28:102:39 | inner_nested [inner post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:104:22:104:22 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:106:30:106:41 | inner_nested [inner post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:108:24:108:24 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| complex.cpp:11:22:11:23 | a_ [post update] | PostUpdateNode should not be the target of local flow. |
| complex.cpp:12:22:12:23 | b_ [post update] | PostUpdateNode should not be the target of local flow. |
| constructors.cpp:20:24:20:25 | a_ [post update] | PostUpdateNode should not be the target of local flow. |
| constructors.cpp:21:24:21:25 | b_ [post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:9:36:9:36 | a [post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:12:56:12:56 | a [post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:13:57:13:57 | a [post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:22:23:22:23 | a [post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:42:25:42:25 | a [post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:47:7:47:11 | outer [inner post update] | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:47:27:47:27 | a [post update] | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:49:13:49:15 | bar [inner post update] | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:49:20:49:22 | baz [post update] | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:53:13:53:15 | bar [inner post update] | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:53:35:53:43 | bufferLen [post update] | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:54:20:54:22 | bar [inner post update] | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:60:16:60:18 | ref arg dst | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:61:25:61:27 | bar [inner post update] | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:65:25:65:27 | bar [inner post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:20:24:20:25 | a_ [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:21:24:21:25 | b_ [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:65:7:65:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:83:12:83:13 | f1 [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:92:7:92:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
| struct_init.c:24:11:24:12 | ab [inner post update] | PostUpdateNode should not be the target of local flow. |
| struct_init.c:36:17:36:24 | nestedAB [inner post update] | PostUpdateNode should not be the target of local flow. |

View File

@@ -22,3 +22,129 @@ uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
| A.cpp:25:7:25:17 | Chi | PostUpdateNode should not be the target of local flow. |
| A.cpp:27:22:27:32 | Chi | PostUpdateNode should not be the target of local flow. |
| A.cpp:98:12:98:18 | Chi | PostUpdateNode should not be the target of local flow. |
| A.cpp:100:5:100:13 | Chi | PostUpdateNode should not be the target of local flow. |
| A.cpp:142:7:142:20 | Chi | PostUpdateNode should not be the target of local flow. |
| A.cpp:143:7:143:31 | Chi | PostUpdateNode should not be the target of local flow. |
| A.cpp:183:7:183:20 | Chi | PostUpdateNode should not be the target of local flow. |
| A.cpp:184:7:184:23 | Chi | PostUpdateNode should not be the target of local flow. |
| B.cpp:6:15:6:24 | Chi | PostUpdateNode should not be the target of local flow. |
| B.cpp:15:15:15:27 | Chi | PostUpdateNode should not be the target of local flow. |
| B.cpp:35:7:35:22 | Chi | PostUpdateNode should not be the target of local flow. |
| B.cpp:36:7:36:22 | Chi | PostUpdateNode should not be the target of local flow. |
| B.cpp:46:7:46:21 | Chi | PostUpdateNode should not be the target of local flow. |
| C.cpp:22:12:22:21 | Chi | PostUpdateNode should not be the target of local flow. |
| C.cpp:22:12:22:21 | Chi | PostUpdateNode should not be the target of local flow. |
| C.cpp:24:5:24:25 | Chi | PostUpdateNode should not be the target of local flow. |
| C.cpp:24:16:24:25 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:9:21:9:28 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:11:29:11:36 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:16:21:16:27 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:18:29:18:35 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:28:15:28:24 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:35:15:35:24 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:42:15:42:24 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:49:15:49:24 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:56:15:56:24 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:57:5:57:42 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:9:3:9:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:13:3:13:21 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:17:3:17:21 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:21:12:21:12 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:21:15:21:15 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:22:12:22:12 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:22:15:22:15 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:23:12:23:12 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:23:15:23:15 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:35:12:35:12 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:35:15:35:15 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:37:3:37:24 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:40:12:40:12 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:40:15:40:15 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:42:3:42:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:47:12:47:12 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:47:15:47:15 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:49:3:49:25 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:52:12:52:12 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:52:15:52:15 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:54:3:54:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:59:12:59:12 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:59:15:59:15 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:60:3:60:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:70:19:70:19 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:70:22:70:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:72:3:72:21 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:77:19:77:19 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:77:22:77:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:79:3:79:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:84:19:84:19 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:84:22:84:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:86:3:86:21 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:91:19:91:19 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:91:22:91:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:92:3:92:23 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:98:3:98:21 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:106:3:106:20 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:111:15:111:19 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:147:15:147:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:175:15:175:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:181:15:181:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:187:15:187:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:194:15:194:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:200:15:200:24 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:205:15:205:24 | Chi | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:5:18:5:23 | Chi | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:5:21:5:21 | Chi | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:6:3:6:23 | Chi | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:14:18:14:23 | Chi | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:14:21:14:21 | Chi | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:15:3:15:25 | Chi | PostUpdateNode should not be the target of local flow. |
| arrays.cpp:36:3:36:37 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:12:5:12:16 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:16:5:16:19 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:84:3:84:25 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:88:3:88:24 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:92:3:92:20 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:96:3:96:19 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:102:21:102:39 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:104:15:104:22 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:106:21:106:41 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:108:15:108:24 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:122:21:122:38 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:124:15:124:21 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:126:21:126:40 | Chi | PostUpdateNode should not be the target of local flow. |
| by_reference.cpp:128:15:128:23 | Chi | PostUpdateNode should not be the target of local flow. |
| complex.cpp:11:22:11:27 | Chi | PostUpdateNode should not be the target of local flow. |
| complex.cpp:12:22:12:27 | Chi | PostUpdateNode should not be the target of local flow. |
| complex.cpp:14:26:14:26 | Chi | PostUpdateNode should not be the target of local flow. |
| complex.cpp:14:33:14:33 | Chi | PostUpdateNode should not be the target of local flow. |
| constructors.cpp:20:24:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
| constructors.cpp:21:24:21:29 | Chi | PostUpdateNode should not be the target of local flow. |
| constructors.cpp:23:28:23:28 | Chi | PostUpdateNode should not be the target of local flow. |
| constructors.cpp:23:35:23:35 | Chi | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:9:30:9:44 | Chi | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:12:49:12:64 | Chi | PostUpdateNode should not be the target of local flow. |
| qualifiers.cpp:13:51:13:65 | Chi | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:39:12:39:95 | Chi | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:49:9:49:64 | Chi | PostUpdateNode should not be the target of local flow. |
| simple.cpp:20:24:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
| simple.cpp:21:24:21:29 | Chi | PostUpdateNode should not be the target of local flow. |
| simple.cpp:23:28:23:28 | Chi | PostUpdateNode should not be the target of local flow. |
| simple.cpp:23:35:23:35 | Chi | PostUpdateNode should not be the target of local flow. |
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should not be the target of local flow. |
| simple.cpp:83:9:83:28 | Chi | PostUpdateNode should not be the target of local flow. |
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should not be the target of local flow. |
| struct_init.c:20:20:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:20:34:20:34 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:27:7:27:16 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:27:21:27:21 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:28:5:28:7 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:36:10:36:24 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:40:20:40:29 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:40:34:40:34 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:42:7:42:16 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:42:21:42:21 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:43:5:43:7 | Chi | PostUpdateNode should not be the target of local flow. |

View File

@@ -1,15 +1,12 @@
edges
| A.cpp:55:5:55:5 | set output argument [c] | A.cpp:56:10:56:10 | Argument -1 indirection [c] |
| A.cpp:55:5:55:5 | set output argument [c] | A.cpp:56:13:56:15 | call to get |
| A.cpp:55:12:55:19 | (C *)... | A.cpp:55:5:55:5 | set output argument [c] |
| A.cpp:55:12:55:19 | new | A.cpp:55:12:55:19 | (C *)... |
| A.cpp:56:10:56:10 | Argument -1 indirection [c] | A.cpp:56:13:56:15 | call to get |
| A.cpp:57:10:57:25 | Argument -1 indirection [c] | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:11:57:24 | B output argument [c] | A.cpp:57:10:57:25 | Argument -1 indirection [c] |
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | set output argument [c] |
| A.cpp:57:11:57:24 | B output argument [c] | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | B output argument [c] |
| A.cpp:98:12:98:18 | new | A.cpp:100:5:100:13 | Store |
| A.cpp:100:5:100:13 | Chi [a] | A.cpp:101:8:101:9 | Argument 0 indirection [a] |
| A.cpp:100:5:100:13 | Chi [a] | A.cpp:103:14:103:14 | *c [a] |
| A.cpp:100:5:100:13 | Store | A.cpp:100:5:100:13 | Chi [a] |
| A.cpp:101:8:101:9 | Argument 0 indirection [a] | A.cpp:103:14:103:14 | *c [a] |
| A.cpp:103:14:103:14 | *c [a] | A.cpp:107:16:107:16 | a |
| A.cpp:126:5:126:5 | Chi [c] | A.cpp:131:8:131:8 | f7 output argument [c] |
| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:126:5:126:5 | Chi [c] |
@@ -22,16 +19,13 @@ edges
| A.cpp:143:7:143:31 | Chi [b] | A.cpp:151:12:151:24 | D output argument [b] |
| A.cpp:143:7:143:31 | Store | A.cpp:143:7:143:31 | Chi [b] |
| A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | Store |
| A.cpp:150:12:150:18 | new | A.cpp:151:18:151:18 | b |
| A.cpp:150:12:150:18 | new | A.cpp:151:12:151:24 | D output argument [b] |
| A.cpp:151:12:151:24 | Chi [b] | A.cpp:152:13:152:13 | b |
| A.cpp:151:12:151:24 | D output argument [b] | A.cpp:151:12:151:24 | Chi [b] |
| A.cpp:151:18:151:18 | Chi [c] | A.cpp:154:13:154:13 | c |
| A.cpp:151:18:151:18 | D output argument [c] | A.cpp:151:18:151:18 | Chi [c] |
| A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | D output argument [b] |
| C.cpp:18:12:18:18 | C output argument [s1] | C.cpp:19:5:19:5 | Argument -1 indirection [s1] |
| C.cpp:18:12:18:18 | C output argument [s3] | C.cpp:19:5:19:5 | Argument -1 indirection [s3] |
| C.cpp:19:5:19:5 | Argument -1 indirection [s1] | C.cpp:27:8:27:11 | *#this [s1] |
| C.cpp:19:5:19:5 | Argument -1 indirection [s3] | C.cpp:27:8:27:11 | *#this [s3] |
| C.cpp:18:12:18:18 | C output argument [s1] | C.cpp:27:8:27:11 | *#this [s1] |
| C.cpp:18:12:18:18 | C output argument [s3] | C.cpp:27:8:27:11 | *#this [s3] |
| C.cpp:22:12:22:21 | Chi [s1] | C.cpp:24:5:24:25 | Chi [s1] |
| C.cpp:22:12:22:21 | Store | C.cpp:22:12:22:21 | Chi [s1] |
| C.cpp:22:12:22:21 | new | C.cpp:22:12:22:21 | Store |
@@ -102,18 +96,14 @@ edges
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array |
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:37:24:37:27 | data |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | by_reference.cpp:51:8:51:8 | Argument -1 indirection [a] |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] |
| by_reference.cpp:51:8:51:8 | Argument -1 indirection [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] | by_reference.cpp:57:8:57:8 | Argument -1 indirection [a] |
| by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] |
| by_reference.cpp:57:8:57:8 | Argument -1 indirection [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] | by_reference.cpp:63:8:63:8 | Argument -1 indirection [a] |
| by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] |
| by_reference.cpp:63:8:63:8 | Argument -1 indirection [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | by_reference.cpp:69:22:69:23 | Argument 0 indirection [a] |
| by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] |
| by_reference.cpp:69:22:69:23 | Argument 0 indirection [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] |
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] |
| by_reference.cpp:84:3:84:25 | Store | by_reference.cpp:84:3:84:25 | Chi [a] |
@@ -150,104 +140,75 @@ edges
| by_reference.cpp:128:15:128:23 | Chi | by_reference.cpp:128:15:128:23 | Chi [a] |
| by_reference.cpp:128:15:128:23 | Chi [a] | by_reference.cpp:136:16:136:16 | a |
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] | by_reference.cpp:128:15:128:23 | Chi |
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:51:16:51:16 | Argument -1 indirection [a_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:51:16:51:16 | Argument -1 indirection [b_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:52:16:52:16 | Argument -1 indirection [b_] |
| complex.cpp:51:16:51:16 | Argument -1 indirection [a_] | complex.cpp:51:18:51:18 | call to a |
| complex.cpp:51:16:51:16 | Argument -1 indirection [b_] | complex.cpp:51:16:51:16 | a output argument [b_] |
| complex.cpp:51:16:51:16 | a output argument [b_] | complex.cpp:52:16:52:16 | Argument -1 indirection [b_] |
| complex.cpp:52:16:52:16 | Argument -1 indirection [b_] | complex.cpp:52:18:52:18 | call to b |
| complex.cpp:62:12:62:12 | setA output argument [a_] | complex.cpp:68:7:68:8 | Argument 0 indirection [a_] |
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:51:18:51:18 | call to a |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:51:16:51:16 | a output argument [b_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:52:18:52:18 | call to b |
| complex.cpp:51:16:51:16 | a output argument [b_] | complex.cpp:52:18:52:18 | call to b |
| complex.cpp:62:12:62:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:62:12:62:12 | setA output argument [a_] |
| complex.cpp:63:12:63:12 | setB output argument [b_] | complex.cpp:71:7:71:8 | Argument 0 indirection [b_] |
| complex.cpp:63:12:63:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:63:12:63:12 | setB output argument [b_] |
| complex.cpp:64:12:64:12 | setA output argument [a_] | complex.cpp:65:12:65:12 | Argument -1 indirection [a_] |
| complex.cpp:64:12:64:12 | setA output argument [a_] | complex.cpp:74:7:74:8 | Argument 0 indirection [a_] |
| complex.cpp:64:12:64:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:64:12:64:12 | setA output argument [a_] | complex.cpp:65:12:65:12 | setB output argument [a_] |
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:64:12:64:12 | setA output argument [a_] |
| complex.cpp:65:12:65:12 | Argument -1 indirection [a_] | complex.cpp:65:12:65:12 | setB output argument [a_] |
| complex.cpp:65:12:65:12 | setB output argument [a_] | complex.cpp:74:7:74:8 | Argument 0 indirection [a_] |
| complex.cpp:65:12:65:12 | setB output argument [b_] | complex.cpp:74:7:74:8 | Argument 0 indirection [b_] |
| complex.cpp:65:12:65:12 | setB output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:65:12:65:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:65:12:65:12 | setB output argument [b_] |
| complex.cpp:68:7:68:8 | Argument 0 indirection [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:71:7:71:8 | Argument 0 indirection [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| complex.cpp:74:7:74:8 | Argument 0 indirection [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:74:7:74:8 | Argument 0 indirection [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| constructors.cpp:26:15:26:15 | *f [a_] | constructors.cpp:28:10:28:10 | Argument -1 indirection [a_] |
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:28:10:28:10 | Argument -1 indirection [b_] |
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:29:10:29:10 | Argument -1 indirection [b_] |
| constructors.cpp:28:10:28:10 | Argument -1 indirection [a_] | constructors.cpp:28:12:28:12 | call to a |
| constructors.cpp:28:10:28:10 | Argument -1 indirection [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] |
| constructors.cpp:28:10:28:10 | a output argument [b_] | constructors.cpp:29:10:29:10 | Argument -1 indirection [b_] |
| constructors.cpp:29:10:29:10 | Argument -1 indirection [b_] | constructors.cpp:29:12:29:12 | call to b |
| constructors.cpp:26:15:26:15 | *f [a_] | constructors.cpp:28:12:28:12 | call to a |
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] |
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:29:12:29:12 | call to b |
| constructors.cpp:28:10:28:10 | a output argument [b_] | constructors.cpp:29:12:29:12 | call to b |
| constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:34:11:34:26 | Foo output argument [a_] |
| constructors.cpp:34:11:34:26 | Foo output argument [a_] | constructors.cpp:40:9:40:9 | Argument 0 indirection [a_] |
| constructors.cpp:35:11:35:26 | Foo output argument [b_] | constructors.cpp:43:9:43:9 | Argument 0 indirection [b_] |
| constructors.cpp:34:11:34:26 | Foo output argument [a_] | constructors.cpp:26:15:26:15 | *f [a_] |
| constructors.cpp:35:11:35:26 | Foo output argument [b_] | constructors.cpp:26:15:26:15 | *f [b_] |
| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:35:11:35:26 | Foo output argument [b_] |
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:36:11:36:37 | Foo output argument [a_] |
| constructors.cpp:36:11:36:37 | Foo output argument [a_] | constructors.cpp:46:9:46:9 | Argument 0 indirection [a_] |
| constructors.cpp:36:11:36:37 | Foo output argument [b_] | constructors.cpp:46:9:46:9 | Argument 0 indirection [b_] |
| constructors.cpp:36:11:36:37 | Foo output argument [a_] | constructors.cpp:26:15:26:15 | *f [a_] |
| constructors.cpp:36:11:36:37 | Foo output argument [b_] | constructors.cpp:26:15:26:15 | *f [b_] |
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:36:11:36:37 | Foo output argument [b_] |
| constructors.cpp:40:9:40:9 | Argument 0 indirection [a_] | constructors.cpp:26:15:26:15 | *f [a_] |
| constructors.cpp:43:9:43:9 | Argument 0 indirection [b_] | constructors.cpp:26:15:26:15 | *f [b_] |
| constructors.cpp:46:9:46:9 | Argument 0 indirection [a_] | constructors.cpp:26:15:26:15 | *f [a_] |
| constructors.cpp:46:9:46:9 | Argument 0 indirection [b_] | constructors.cpp:26:15:26:15 | *f [b_] |
| simple.cpp:26:15:26:15 | *f [a_] | simple.cpp:28:10:28:10 | Argument -1 indirection [a_] |
| simple.cpp:26:15:26:15 | *f [b_] | simple.cpp:28:10:28:10 | Argument -1 indirection [b_] |
| simple.cpp:26:15:26:15 | *f [b_] | simple.cpp:29:10:29:10 | Argument -1 indirection [b_] |
| simple.cpp:28:10:28:10 | Argument -1 indirection [a_] | simple.cpp:28:12:28:12 | call to a |
| simple.cpp:28:10:28:10 | Argument -1 indirection [b_] | simple.cpp:28:10:28:10 | a output argument [b_] |
| simple.cpp:28:10:28:10 | a output argument [b_] | simple.cpp:29:10:29:10 | Argument -1 indirection [b_] |
| simple.cpp:29:10:29:10 | Argument -1 indirection [b_] | simple.cpp:29:12:29:12 | call to b |
| simple.cpp:39:5:39:5 | setA output argument [a_] | simple.cpp:45:9:45:9 | Argument 0 indirection [a_] |
| simple.cpp:26:15:26:15 | *f [a_] | simple.cpp:28:12:28:12 | call to a |
| simple.cpp:26:15:26:15 | *f [b_] | simple.cpp:28:10:28:10 | a output argument [b_] |
| simple.cpp:26:15:26:15 | *f [b_] | simple.cpp:29:12:29:12 | call to b |
| simple.cpp:28:10:28:10 | a output argument [b_] | simple.cpp:29:12:29:12 | call to b |
| simple.cpp:39:5:39:5 | setA output argument [a_] | simple.cpp:26:15:26:15 | *f [a_] |
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:39:5:39:5 | setA output argument [a_] |
| simple.cpp:40:5:40:5 | setB output argument [b_] | simple.cpp:48:9:48:9 | Argument 0 indirection [b_] |
| simple.cpp:40:5:40:5 | setB output argument [b_] | simple.cpp:26:15:26:15 | *f [b_] |
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:40:5:40:5 | setB output argument [b_] |
| simple.cpp:41:5:41:5 | setA output argument [a_] | simple.cpp:42:5:42:5 | Argument -1 indirection [a_] |
| simple.cpp:41:5:41:5 | setA output argument [a_] | simple.cpp:51:9:51:9 | Argument 0 indirection [a_] |
| simple.cpp:41:5:41:5 | setA output argument [a_] | simple.cpp:26:15:26:15 | *f [a_] |
| simple.cpp:41:5:41:5 | setA output argument [a_] | simple.cpp:42:5:42:5 | setB output argument [a_] |
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:41:5:41:5 | setA output argument [a_] |
| simple.cpp:42:5:42:5 | Argument -1 indirection [a_] | simple.cpp:42:5:42:5 | setB output argument [a_] |
| simple.cpp:42:5:42:5 | setB output argument [a_] | simple.cpp:51:9:51:9 | Argument 0 indirection [a_] |
| simple.cpp:42:5:42:5 | setB output argument [b_] | simple.cpp:51:9:51:9 | Argument 0 indirection [b_] |
| simple.cpp:42:5:42:5 | setB output argument [a_] | simple.cpp:26:15:26:15 | *f [a_] |
| simple.cpp:42:5:42:5 | setB output argument [b_] | simple.cpp:26:15:26:15 | *f [b_] |
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:5:42:5 | setB output argument [b_] |
| simple.cpp:45:9:45:9 | Argument 0 indirection [a_] | simple.cpp:26:15:26:15 | *f [a_] |
| simple.cpp:48:9:48:9 | Argument 0 indirection [b_] | simple.cpp:26:15:26:15 | *f [b_] |
| simple.cpp:51:9:51:9 | Argument 0 indirection [a_] | simple.cpp:26:15:26:15 | *f [a_] |
| simple.cpp:51:9:51:9 | Argument 0 indirection [b_] | simple.cpp:26:15:26:15 | *f [b_] |
| simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] |
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] |
| simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i |
| simple.cpp:83:9:83:28 | Chi [f1] | simple.cpp:84:14:84:20 | Argument -1 indirection [f1] |
| simple.cpp:83:9:83:28 | Chi [f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
| simple.cpp:83:9:83:28 | Store | simple.cpp:83:9:83:28 | Chi [f1] |
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Store |
| simple.cpp:84:14:84:20 | Argument -1 indirection [f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
| simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] |
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] |
| simple.cpp:93:20:93:20 | Store [i] | simple.cpp:94:13:94:13 | i |
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:12:15:12 | a |
| struct_init.c:20:20:20:29 | Chi [a] | struct_init.c:24:10:24:12 | Argument 0 indirection [a] |
| struct_init.c:20:20:20:29 | Chi [a] | struct_init.c:14:24:14:25 | *ab [a] |
| struct_init.c:20:20:20:29 | Store | struct_init.c:20:20:20:29 | Chi [a] |
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:20:20:29 | Store |
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a |
| struct_init.c:24:10:24:12 | Argument 0 indirection [a] | struct_init.c:14:24:14:25 | *ab [a] |
| struct_init.c:27:7:27:16 | Chi [a] | struct_init.c:36:10:36:24 | Argument 0 indirection [a] |
| struct_init.c:27:7:27:16 | Chi [a] | struct_init.c:14:24:14:25 | *ab [a] |
| struct_init.c:27:7:27:16 | Store | struct_init.c:27:7:27:16 | Chi [a] |
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:27:7:27:16 | Store |
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a |
| struct_init.c:36:10:36:24 | Argument 0 indirection [a] | struct_init.c:14:24:14:25 | *ab [a] |
nodes
| A.cpp:55:5:55:5 | set output argument [c] | semmle.label | set output argument [c] |
| A.cpp:55:12:55:19 | (C *)... | semmle.label | (C *)... |
| A.cpp:55:12:55:19 | new | semmle.label | new |
| A.cpp:56:10:56:10 | Argument -1 indirection [c] | semmle.label | Argument -1 indirection [c] |
| A.cpp:56:13:56:15 | call to get | semmle.label | call to get |
| A.cpp:57:10:57:25 | Argument -1 indirection [c] | semmle.label | Argument -1 indirection [c] |
| A.cpp:57:11:57:24 | B output argument [c] | semmle.label | B output argument [c] |
| A.cpp:57:17:57:23 | new | semmle.label | new |
| A.cpp:57:28:57:30 | call to get | semmle.label | call to get |
| A.cpp:98:12:98:18 | new | semmle.label | new |
| A.cpp:100:5:100:13 | Chi [a] | semmle.label | Chi [a] |
| A.cpp:100:5:100:13 | Store | semmle.label | Store |
| A.cpp:101:8:101:9 | Argument 0 indirection [a] | semmle.label | Argument 0 indirection [a] |
| A.cpp:103:14:103:14 | *c [a] | semmle.label | *c [a] |
| A.cpp:107:16:107:16 | a | semmle.label | a |
| A.cpp:126:5:126:5 | Chi [c] | semmle.label | Chi [c] |
@@ -267,13 +228,10 @@ nodes
| A.cpp:151:12:151:24 | D output argument [b] | semmle.label | D output argument [b] |
| A.cpp:151:18:151:18 | Chi [c] | semmle.label | Chi [c] |
| A.cpp:151:18:151:18 | D output argument [c] | semmle.label | D output argument [c] |
| A.cpp:151:18:151:18 | b | semmle.label | b |
| A.cpp:152:13:152:13 | b | semmle.label | b |
| A.cpp:154:13:154:13 | c | semmle.label | c |
| C.cpp:18:12:18:18 | C output argument [s1] | semmle.label | C output argument [s1] |
| C.cpp:18:12:18:18 | C output argument [s3] | semmle.label | C output argument [s3] |
| C.cpp:19:5:19:5 | Argument -1 indirection [s1] | semmle.label | Argument -1 indirection [s1] |
| C.cpp:19:5:19:5 | Argument -1 indirection [s3] | semmle.label | Argument -1 indirection [s3] |
| C.cpp:22:12:22:21 | Chi [s1] | semmle.label | Chi [s1] |
| C.cpp:22:12:22:21 | Store | semmle.label | Store |
| C.cpp:22:12:22:21 | new | semmle.label | new |
@@ -361,20 +319,16 @@ nodes
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | semmle.label | setDirectly output argument [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:51:8:51:8 | Argument -1 indirection [a] | semmle.label | Argument -1 indirection [a] |
| by_reference.cpp:51:10:51:20 | call to getDirectly | semmle.label | call to getDirectly |
| by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] | semmle.label | setIndirectly output argument [a] |
| by_reference.cpp:56:19:56:28 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:57:8:57:8 | Argument -1 indirection [a] | semmle.label | Argument -1 indirection [a] |
| by_reference.cpp:57:10:57:22 | call to getIndirectly | semmle.label | call to getIndirectly |
| by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] | semmle.label | setThroughNonMember output argument [a] |
| by_reference.cpp:62:25:62:34 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:63:8:63:8 | Argument -1 indirection [a] | semmle.label | Argument -1 indirection [a] |
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | semmle.label | call to getThroughNonMember |
| by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | semmle.label | nonMemberSetA output argument [a] |
| by_reference.cpp:68:21:68:30 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
| by_reference.cpp:69:22:69:23 | Argument 0 indirection [a] | semmle.label | Argument 0 indirection [a] |
| by_reference.cpp:84:3:84:25 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:84:3:84:25 | Store | semmle.label | Store |
| by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input |
@@ -417,11 +371,8 @@ nodes
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
| complex.cpp:40:17:40:17 | *b [a_] | semmle.label | *b [a_] |
| complex.cpp:40:17:40:17 | *b [b_] | semmle.label | *b [b_] |
| complex.cpp:51:16:51:16 | Argument -1 indirection [a_] | semmle.label | Argument -1 indirection [a_] |
| complex.cpp:51:16:51:16 | Argument -1 indirection [b_] | semmle.label | Argument -1 indirection [b_] |
| complex.cpp:51:16:51:16 | a output argument [b_] | semmle.label | a output argument [b_] |
| complex.cpp:51:18:51:18 | call to a | semmle.label | call to a |
| complex.cpp:52:16:52:16 | Argument -1 indirection [b_] | semmle.label | Argument -1 indirection [b_] |
| complex.cpp:52:18:52:18 | call to b | semmle.label | call to b |
| complex.cpp:62:12:62:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
| complex.cpp:62:19:62:28 | call to user_input | semmle.label | call to user_input |
@@ -429,21 +380,13 @@ nodes
| complex.cpp:63:19:63:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:64:12:64:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
| complex.cpp:64:19:64:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:65:12:65:12 | Argument -1 indirection [a_] | semmle.label | Argument -1 indirection [a_] |
| complex.cpp:65:12:65:12 | setB output argument [a_] | semmle.label | setB output argument [a_] |
| complex.cpp:65:12:65:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
| complex.cpp:65:19:65:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:68:7:68:8 | Argument 0 indirection [a_] | semmle.label | Argument 0 indirection [a_] |
| complex.cpp:71:7:71:8 | Argument 0 indirection [b_] | semmle.label | Argument 0 indirection [b_] |
| complex.cpp:74:7:74:8 | Argument 0 indirection [a_] | semmle.label | Argument 0 indirection [a_] |
| complex.cpp:74:7:74:8 | Argument 0 indirection [b_] | semmle.label | Argument 0 indirection [b_] |
| constructors.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] |
| constructors.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] |
| constructors.cpp:28:10:28:10 | Argument -1 indirection [a_] | semmle.label | Argument -1 indirection [a_] |
| constructors.cpp:28:10:28:10 | Argument -1 indirection [b_] | semmle.label | Argument -1 indirection [b_] |
| constructors.cpp:28:10:28:10 | a output argument [b_] | semmle.label | a output argument [b_] |
| constructors.cpp:28:12:28:12 | call to a | semmle.label | call to a |
| constructors.cpp:29:10:29:10 | Argument -1 indirection [b_] | semmle.label | Argument -1 indirection [b_] |
| constructors.cpp:29:12:29:12 | call to b | semmle.label | call to b |
| constructors.cpp:34:11:34:20 | call to user_input | semmle.label | call to user_input |
| constructors.cpp:34:11:34:26 | Foo output argument [a_] | semmle.label | Foo output argument [a_] |
@@ -453,17 +396,10 @@ nodes
| constructors.cpp:36:11:36:37 | Foo output argument [a_] | semmle.label | Foo output argument [a_] |
| constructors.cpp:36:11:36:37 | Foo output argument [b_] | semmle.label | Foo output argument [b_] |
| constructors.cpp:36:25:36:34 | call to user_input | semmle.label | call to user_input |
| constructors.cpp:40:9:40:9 | Argument 0 indirection [a_] | semmle.label | Argument 0 indirection [a_] |
| constructors.cpp:43:9:43:9 | Argument 0 indirection [b_] | semmle.label | Argument 0 indirection [b_] |
| constructors.cpp:46:9:46:9 | Argument 0 indirection [a_] | semmle.label | Argument 0 indirection [a_] |
| constructors.cpp:46:9:46:9 | Argument 0 indirection [b_] | semmle.label | Argument 0 indirection [b_] |
| simple.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] |
| simple.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] |
| simple.cpp:28:10:28:10 | Argument -1 indirection [a_] | semmle.label | Argument -1 indirection [a_] |
| simple.cpp:28:10:28:10 | Argument -1 indirection [b_] | semmle.label | Argument -1 indirection [b_] |
| simple.cpp:28:10:28:10 | a output argument [b_] | semmle.label | a output argument [b_] |
| simple.cpp:28:12:28:12 | call to a | semmle.label | call to a |
| simple.cpp:29:10:29:10 | Argument -1 indirection [b_] | semmle.label | Argument -1 indirection [b_] |
| simple.cpp:29:12:29:12 | call to b | semmle.label | call to b |
| simple.cpp:39:5:39:5 | setA output argument [a_] | semmle.label | setA output argument [a_] |
| simple.cpp:39:12:39:21 | call to user_input | semmle.label | call to user_input |
@@ -471,14 +407,9 @@ nodes
| simple.cpp:40:12:40:21 | call to user_input | semmle.label | call to user_input |
| simple.cpp:41:5:41:5 | setA output argument [a_] | semmle.label | setA output argument [a_] |
| simple.cpp:41:12:41:21 | call to user_input | semmle.label | call to user_input |
| simple.cpp:42:5:42:5 | Argument -1 indirection [a_] | semmle.label | Argument -1 indirection [a_] |
| simple.cpp:42:5:42:5 | setB output argument [a_] | semmle.label | setB output argument [a_] |
| simple.cpp:42:5:42:5 | setB output argument [b_] | semmle.label | setB output argument [b_] |
| simple.cpp:42:12:42:21 | call to user_input | semmle.label | call to user_input |
| simple.cpp:45:9:45:9 | Argument 0 indirection [a_] | semmle.label | Argument 0 indirection [a_] |
| simple.cpp:48:9:48:9 | Argument 0 indirection [b_] | semmle.label | Argument 0 indirection [b_] |
| simple.cpp:51:9:51:9 | Argument 0 indirection [a_] | semmle.label | Argument 0 indirection [a_] |
| simple.cpp:51:9:51:9 | Argument 0 indirection [b_] | semmle.label | Argument 0 indirection [b_] |
| simple.cpp:65:5:65:22 | Store [i] | semmle.label | Store [i] |
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] |
@@ -486,7 +417,6 @@ nodes
| simple.cpp:83:9:83:28 | Chi [f1] | semmle.label | Chi [f1] |
| simple.cpp:83:9:83:28 | Store | semmle.label | Store |
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
| simple.cpp:84:14:84:20 | Argument -1 indirection [f1] | semmle.label | Argument -1 indirection [f1] |
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
| simple.cpp:92:5:92:22 | Store [i] | semmle.label | Store [i] |
| simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input |
@@ -498,12 +428,10 @@ nodes
| struct_init.c:20:20:20:29 | Store | semmle.label | Store |
| struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input |
| struct_init.c:22:11:22:11 | a | semmle.label | a |
| struct_init.c:24:10:24:12 | Argument 0 indirection [a] | semmle.label | Argument 0 indirection [a] |
| struct_init.c:27:7:27:16 | Chi [a] | semmle.label | Chi [a] |
| struct_init.c:27:7:27:16 | Store | semmle.label | Store |
| struct_init.c:27:7:27:16 | call to user_input | semmle.label | call to user_input |
| struct_init.c:31:23:31:23 | a | semmle.label | a |
| struct_init.c:36:10:36:24 | Argument 0 indirection [a] | semmle.label | Argument 0 indirection [a] |
#select
| A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | (C *)... | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | (C *)... | (C *)... |
| A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | new | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new | new |

View File

@@ -25,13 +25,10 @@ class TestAllocationConfig extends TaintTracking::Configuration {
sink.(DataFlow::ExprNode).getConvertedExpr() instanceof ReferenceDereferenceExpr
)
or
sink
.asInstruction()
.(ReadSideEffectInstruction)
.getPrimaryInstruction()
.(CallInstruction)
.getStaticCallTarget()
.hasName("sink")
exists(ReadSideEffectInstruction read |
read.getSideEffectOperand() = sink.asOperand() and
read.getPrimaryInstruction().(CallInstruction).getStaticCallTarget().hasName("sink")
)
}
override predicate isSanitizer(DataFlow::Node barrier) {

View File

@@ -1844,6 +1844,943 @@
| movableclass.cpp:65:13:65:18 | call to source | movableclass.cpp:65:13:65:20 | call to MyMovableClass | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:8:65:9 | ref arg s3 | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:11:65:11 | call to operator= | TAINT |
| set.cpp:17:19:17:20 | call to set | set.cpp:19:7:19:8 | s1 | |
| set.cpp:17:19:17:20 | call to set | set.cpp:23:12:23:13 | s1 | |
| set.cpp:17:19:17:20 | call to set | set.cpp:23:24:23:25 | s1 | |
| set.cpp:17:19:17:20 | call to set | set.cpp:25:7:25:8 | s1 | |
| set.cpp:17:19:17:20 | call to set | set.cpp:31:7:31:8 | s1 | |
| set.cpp:17:19:17:20 | call to set | set.cpp:55:12:55:13 | s1 | |
| set.cpp:17:19:17:20 | call to set | set.cpp:55:30:55:31 | s1 | |
| set.cpp:17:19:17:20 | call to set | set.cpp:126:1:126:1 | s1 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:20:7:20:8 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:24:12:24:13 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:24:24:24:25 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:26:7:26:8 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:32:7:32:8 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:39:22:39:23 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:40:24:40:25 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:41:22:41:23 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:41:34:41:35 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:43:8:43:9 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:59:12:59:13 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:59:30:59:31 | s2 | |
| set.cpp:17:23:17:24 | call to set | set.cpp:126:1:126:1 | s2 | |
| set.cpp:17:27:17:28 | call to set | set.cpp:21:7:21:8 | s3 | |
| set.cpp:17:27:17:28 | call to set | set.cpp:21:17:21:18 | s3 | |
| set.cpp:17:27:17:28 | call to set | set.cpp:27:7:27:8 | s3 | |
| set.cpp:17:27:17:28 | call to set | set.cpp:33:7:33:8 | s3 | |
| set.cpp:17:27:17:28 | call to set | set.cpp:126:1:126:1 | s3 | |
| set.cpp:17:31:17:32 | call to set | set.cpp:22:7:22:8 | s4 | |
| set.cpp:17:31:17:32 | call to set | set.cpp:22:17:22:18 | s4 | |
| set.cpp:17:31:17:32 | call to set | set.cpp:28:7:28:8 | s4 | |
| set.cpp:17:31:17:32 | call to set | set.cpp:34:7:34:8 | s4 | |
| set.cpp:17:31:17:32 | call to set | set.cpp:126:1:126:1 | s4 | |
| set.cpp:17:35:17:36 | call to set | set.cpp:23:2:23:3 | s5 | |
| set.cpp:17:35:17:36 | call to set | set.cpp:29:7:29:8 | s5 | |
| set.cpp:17:35:17:36 | call to set | set.cpp:35:7:35:8 | s5 | |
| set.cpp:17:35:17:36 | call to set | set.cpp:126:1:126:1 | s5 | |
| set.cpp:17:39:17:40 | call to set | set.cpp:24:2:24:3 | s6 | |
| set.cpp:17:39:17:40 | call to set | set.cpp:30:7:30:8 | s6 | |
| set.cpp:17:39:17:40 | call to set | set.cpp:36:7:36:8 | s6 | |
| set.cpp:17:39:17:40 | call to set | set.cpp:126:1:126:1 | s6 | |
| set.cpp:19:7:19:8 | ref arg s1 | set.cpp:23:12:23:13 | s1 | |
| set.cpp:19:7:19:8 | ref arg s1 | set.cpp:23:24:23:25 | s1 | |
| set.cpp:19:7:19:8 | ref arg s1 | set.cpp:25:7:25:8 | s1 | |
| set.cpp:19:7:19:8 | ref arg s1 | set.cpp:31:7:31:8 | s1 | |
| set.cpp:19:7:19:8 | ref arg s1 | set.cpp:55:12:55:13 | s1 | |
| set.cpp:19:7:19:8 | ref arg s1 | set.cpp:55:30:55:31 | s1 | |
| set.cpp:19:7:19:8 | ref arg s1 | set.cpp:126:1:126:1 | s1 | |
| set.cpp:19:17:19:21 | abc | set.cpp:19:7:19:8 | ref arg s1 | TAINT |
| set.cpp:19:17:19:21 | abc | set.cpp:19:10:19:15 | call to insert | TAINT |
| set.cpp:19:24:19:28 | first | set.cpp:19:7:19:28 | call to iterator | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:24:12:24:13 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:24:24:24:25 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:26:7:26:8 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:32:7:32:8 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:39:22:39:23 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:40:24:40:25 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:41:22:41:23 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:41:34:41:35 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:43:8:43:9 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:59:12:59:13 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:20:7:20:8 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:20:17:20:22 | call to source | set.cpp:20:7:20:8 | ref arg s2 | TAINT |
| set.cpp:20:17:20:22 | call to source | set.cpp:20:10:20:15 | call to insert | TAINT |
| set.cpp:20:27:20:31 | first | set.cpp:20:7:20:31 | call to iterator | |
| set.cpp:21:7:21:8 | ref arg s3 | set.cpp:27:7:27:8 | s3 | |
| set.cpp:21:7:21:8 | ref arg s3 | set.cpp:33:7:33:8 | s3 | |
| set.cpp:21:7:21:8 | ref arg s3 | set.cpp:126:1:126:1 | s3 | |
| set.cpp:21:17:21:18 | ref arg s3 | set.cpp:21:7:21:8 | s3 | |
| set.cpp:21:17:21:18 | ref arg s3 | set.cpp:27:7:27:8 | s3 | |
| set.cpp:21:17:21:18 | ref arg s3 | set.cpp:33:7:33:8 | s3 | |
| set.cpp:21:17:21:18 | ref arg s3 | set.cpp:126:1:126:1 | s3 | |
| set.cpp:21:17:21:18 | s3 | set.cpp:21:20:21:24 | call to begin | TAINT |
| set.cpp:21:20:21:24 | call to begin | set.cpp:21:17:21:26 | call to iterator | TAINT |
| set.cpp:21:29:21:33 | abc | set.cpp:21:7:21:8 | ref arg s3 | TAINT |
| set.cpp:21:29:21:33 | abc | set.cpp:21:10:21:15 | call to insert | TAINT |
| set.cpp:22:7:22:8 | ref arg s4 | set.cpp:28:7:28:8 | s4 | |
| set.cpp:22:7:22:8 | ref arg s4 | set.cpp:34:7:34:8 | s4 | |
| set.cpp:22:7:22:8 | ref arg s4 | set.cpp:126:1:126:1 | s4 | |
| set.cpp:22:17:22:18 | ref arg s4 | set.cpp:22:7:22:8 | s4 | |
| set.cpp:22:17:22:18 | ref arg s4 | set.cpp:28:7:28:8 | s4 | |
| set.cpp:22:17:22:18 | ref arg s4 | set.cpp:34:7:34:8 | s4 | |
| set.cpp:22:17:22:18 | ref arg s4 | set.cpp:126:1:126:1 | s4 | |
| set.cpp:22:17:22:18 | s4 | set.cpp:22:20:22:24 | call to begin | TAINT |
| set.cpp:22:20:22:24 | call to begin | set.cpp:22:17:22:26 | call to iterator | TAINT |
| set.cpp:22:29:22:34 | call to source | set.cpp:22:7:22:8 | ref arg s4 | TAINT |
| set.cpp:22:29:22:34 | call to source | set.cpp:22:10:22:15 | call to insert | TAINT |
| set.cpp:23:2:23:3 | ref arg s5 | set.cpp:29:7:29:8 | s5 | |
| set.cpp:23:2:23:3 | ref arg s5 | set.cpp:35:7:35:8 | s5 | |
| set.cpp:23:2:23:3 | ref arg s5 | set.cpp:126:1:126:1 | s5 | |
| set.cpp:23:12:23:13 | ref arg s1 | set.cpp:23:24:23:25 | s1 | |
| set.cpp:23:12:23:13 | ref arg s1 | set.cpp:25:7:25:8 | s1 | |
| set.cpp:23:12:23:13 | ref arg s1 | set.cpp:31:7:31:8 | s1 | |
| set.cpp:23:12:23:13 | ref arg s1 | set.cpp:55:12:55:13 | s1 | |
| set.cpp:23:12:23:13 | ref arg s1 | set.cpp:55:30:55:31 | s1 | |
| set.cpp:23:12:23:13 | ref arg s1 | set.cpp:126:1:126:1 | s1 | |
| set.cpp:23:12:23:13 | s1 | set.cpp:23:15:23:19 | call to begin | TAINT |
| set.cpp:23:24:23:25 | ref arg s1 | set.cpp:25:7:25:8 | s1 | |
| set.cpp:23:24:23:25 | ref arg s1 | set.cpp:31:7:31:8 | s1 | |
| set.cpp:23:24:23:25 | ref arg s1 | set.cpp:55:12:55:13 | s1 | |
| set.cpp:23:24:23:25 | ref arg s1 | set.cpp:55:30:55:31 | s1 | |
| set.cpp:23:24:23:25 | ref arg s1 | set.cpp:126:1:126:1 | s1 | |
| set.cpp:23:24:23:25 | s1 | set.cpp:23:27:23:29 | call to end | TAINT |
| set.cpp:23:27:23:29 | call to end | set.cpp:23:2:23:3 | ref arg s5 | TAINT |
| set.cpp:23:27:23:29 | call to end | set.cpp:23:5:23:10 | call to insert | TAINT |
| set.cpp:24:2:24:3 | ref arg s6 | set.cpp:30:7:30:8 | s6 | |
| set.cpp:24:2:24:3 | ref arg s6 | set.cpp:36:7:36:8 | s6 | |
| set.cpp:24:2:24:3 | ref arg s6 | set.cpp:126:1:126:1 | s6 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:24:24:24:25 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:26:7:26:8 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:32:7:32:8 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:39:22:39:23 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:40:24:40:25 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:41:22:41:23 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:41:34:41:35 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:43:8:43:9 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:59:12:59:13 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:24:12:24:13 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:24:12:24:13 | s2 | set.cpp:24:15:24:19 | call to begin | TAINT |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:26:7:26:8 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:32:7:32:8 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:39:22:39:23 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:40:24:40:25 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:41:22:41:23 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:41:34:41:35 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:43:8:43:9 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:59:12:59:13 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:24:24:24:25 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:24:24:24:25 | s2 | set.cpp:24:27:24:29 | call to end | TAINT |
| set.cpp:24:27:24:29 | call to end | set.cpp:24:2:24:3 | ref arg s6 | TAINT |
| set.cpp:24:27:24:29 | call to end | set.cpp:24:5:24:10 | call to insert | TAINT |
| set.cpp:25:7:25:8 | s1 | set.cpp:25:7:25:8 | call to set | |
| set.cpp:26:7:26:8 | s2 | set.cpp:26:7:26:8 | call to set | |
| set.cpp:27:7:27:8 | s3 | set.cpp:27:7:27:8 | call to set | |
| set.cpp:28:7:28:8 | s4 | set.cpp:28:7:28:8 | call to set | |
| set.cpp:29:7:29:8 | s5 | set.cpp:29:7:29:8 | call to set | |
| set.cpp:30:7:30:8 | s6 | set.cpp:30:7:30:8 | call to set | |
| set.cpp:31:7:31:8 | ref arg s1 | set.cpp:55:12:55:13 | s1 | |
| set.cpp:31:7:31:8 | ref arg s1 | set.cpp:55:30:55:31 | s1 | |
| set.cpp:31:7:31:8 | ref arg s1 | set.cpp:126:1:126:1 | s1 | |
| set.cpp:31:7:31:8 | s1 | set.cpp:31:10:31:13 | call to find | TAINT |
| set.cpp:32:7:32:8 | ref arg s2 | set.cpp:39:22:39:23 | s2 | |
| set.cpp:32:7:32:8 | ref arg s2 | set.cpp:40:24:40:25 | s2 | |
| set.cpp:32:7:32:8 | ref arg s2 | set.cpp:41:22:41:23 | s2 | |
| set.cpp:32:7:32:8 | ref arg s2 | set.cpp:41:34:41:35 | s2 | |
| set.cpp:32:7:32:8 | ref arg s2 | set.cpp:43:8:43:9 | s2 | |
| set.cpp:32:7:32:8 | ref arg s2 | set.cpp:59:12:59:13 | s2 | |
| set.cpp:32:7:32:8 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:32:7:32:8 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:32:7:32:8 | s2 | set.cpp:32:10:32:13 | call to find | TAINT |
| set.cpp:33:7:33:8 | ref arg s3 | set.cpp:126:1:126:1 | s3 | |
| set.cpp:33:7:33:8 | s3 | set.cpp:33:10:33:13 | call to find | TAINT |
| set.cpp:34:7:34:8 | ref arg s4 | set.cpp:126:1:126:1 | s4 | |
| set.cpp:34:7:34:8 | s4 | set.cpp:34:10:34:13 | call to find | TAINT |
| set.cpp:35:7:35:8 | ref arg s5 | set.cpp:126:1:126:1 | s5 | |
| set.cpp:35:7:35:8 | s5 | set.cpp:35:10:35:13 | call to find | TAINT |
| set.cpp:36:7:36:8 | ref arg s6 | set.cpp:126:1:126:1 | s6 | |
| set.cpp:36:7:36:8 | s6 | set.cpp:36:10:36:13 | call to find | TAINT |
| set.cpp:39:22:39:23 | s2 | set.cpp:39:22:39:24 | call to set | |
| set.cpp:39:22:39:24 | call to set | set.cpp:44:7:44:8 | s7 | |
| set.cpp:39:22:39:24 | call to set | set.cpp:48:7:48:8 | s7 | |
| set.cpp:39:22:39:24 | call to set | set.cpp:126:1:126:1 | s7 | |
| set.cpp:40:23:40:25 | call to set | set.cpp:45:7:45:8 | s8 | |
| set.cpp:40:23:40:25 | call to set | set.cpp:49:7:49:8 | s8 | |
| set.cpp:40:23:40:25 | call to set | set.cpp:126:1:126:1 | s8 | |
| set.cpp:40:24:40:25 | s2 | set.cpp:40:23:40:25 | call to set | |
| set.cpp:41:22:41:23 | ref arg s2 | set.cpp:41:34:41:35 | s2 | |
| set.cpp:41:22:41:23 | ref arg s2 | set.cpp:43:8:43:9 | s2 | |
| set.cpp:41:22:41:23 | ref arg s2 | set.cpp:59:12:59:13 | s2 | |
| set.cpp:41:22:41:23 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:41:22:41:23 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:41:22:41:23 | s2 | set.cpp:41:25:41:29 | call to begin | TAINT |
| set.cpp:41:22:41:42 | call to set | set.cpp:46:7:46:8 | s9 | |
| set.cpp:41:22:41:42 | call to set | set.cpp:50:7:50:8 | s9 | |
| set.cpp:41:22:41:42 | call to set | set.cpp:126:1:126:1 | s9 | |
| set.cpp:41:25:41:29 | call to begin | set.cpp:41:22:41:42 | call to set | TAINT |
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:43:8:43:9 | s2 | |
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:59:12:59:13 | s2 | |
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:41:34:41:35 | s2 | set.cpp:41:37:41:39 | call to end | TAINT |
| set.cpp:41:37:41:39 | call to end | set.cpp:41:22:41:42 | call to set | TAINT |
| set.cpp:42:19:42:21 | call to set | set.cpp:43:2:43:4 | s10 | |
| set.cpp:42:19:42:21 | call to set | set.cpp:47:7:47:9 | s10 | |
| set.cpp:42:19:42:21 | call to set | set.cpp:51:7:51:9 | s10 | |
| set.cpp:42:19:42:21 | call to set | set.cpp:126:1:126:1 | s10 | |
| set.cpp:43:2:43:4 | ref arg s10 | set.cpp:47:7:47:9 | s10 | |
| set.cpp:43:2:43:4 | ref arg s10 | set.cpp:51:7:51:9 | s10 | |
| set.cpp:43:2:43:4 | ref arg s10 | set.cpp:126:1:126:1 | s10 | |
| set.cpp:43:8:43:9 | s2 | set.cpp:43:2:43:4 | ref arg s10 | TAINT |
| set.cpp:43:8:43:9 | s2 | set.cpp:43:6:43:6 | call to operator= | TAINT |
| set.cpp:44:7:44:8 | s7 | set.cpp:44:7:44:8 | call to set | |
| set.cpp:45:7:45:8 | s8 | set.cpp:45:7:45:8 | call to set | |
| set.cpp:46:7:46:8 | s9 | set.cpp:46:7:46:8 | call to set | |
| set.cpp:47:7:47:9 | s10 | set.cpp:47:7:47:9 | call to set | |
| set.cpp:48:7:48:8 | ref arg s7 | set.cpp:126:1:126:1 | s7 | |
| set.cpp:48:7:48:8 | s7 | set.cpp:48:10:48:13 | call to find | TAINT |
| set.cpp:49:7:49:8 | ref arg s8 | set.cpp:126:1:126:1 | s8 | |
| set.cpp:49:7:49:8 | s8 | set.cpp:49:10:49:13 | call to find | TAINT |
| set.cpp:50:7:50:8 | ref arg s9 | set.cpp:126:1:126:1 | s9 | |
| set.cpp:50:7:50:8 | s9 | set.cpp:50:10:50:13 | call to find | TAINT |
| set.cpp:51:7:51:9 | ref arg s10 | set.cpp:126:1:126:1 | s10 | |
| set.cpp:51:7:51:9 | s10 | set.cpp:51:11:51:14 | call to find | TAINT |
| set.cpp:55:12:55:13 | ref arg s1 | set.cpp:55:30:55:31 | s1 | |
| set.cpp:55:12:55:13 | ref arg s1 | set.cpp:126:1:126:1 | s1 | |
| set.cpp:55:12:55:13 | s1 | set.cpp:55:15:55:19 | call to begin | TAINT |
| set.cpp:55:15:55:19 | call to begin | set.cpp:55:7:55:21 | ... = ... | |
| set.cpp:55:15:55:19 | call to begin | set.cpp:55:24:55:25 | i1 | |
| set.cpp:55:15:55:19 | call to begin | set.cpp:55:40:55:41 | i1 | |
| set.cpp:55:15:55:19 | call to begin | set.cpp:57:9:57:10 | i1 | |
| set.cpp:55:30:55:31 | ref arg s1 | set.cpp:55:30:55:31 | s1 | |
| set.cpp:55:30:55:31 | ref arg s1 | set.cpp:126:1:126:1 | s1 | |
| set.cpp:55:30:55:31 | s1 | set.cpp:55:33:55:35 | call to end | TAINT |
| set.cpp:55:40:55:41 | i1 | set.cpp:55:42:55:42 | call to operator++ | |
| set.cpp:55:40:55:41 | ref arg i1 | set.cpp:55:24:55:25 | i1 | |
| set.cpp:55:40:55:41 | ref arg i1 | set.cpp:55:40:55:41 | i1 | |
| set.cpp:55:40:55:41 | ref arg i1 | set.cpp:57:9:57:10 | i1 | |
| set.cpp:57:9:57:10 | i1 | set.cpp:57:8:57:8 | call to operator* | TAINT |
| set.cpp:59:12:59:13 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:59:12:59:13 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:59:12:59:13 | s2 | set.cpp:59:15:59:19 | call to begin | TAINT |
| set.cpp:59:15:59:19 | call to begin | set.cpp:59:7:59:21 | ... = ... | |
| set.cpp:59:15:59:19 | call to begin | set.cpp:59:24:59:25 | i2 | |
| set.cpp:59:15:59:19 | call to begin | set.cpp:59:40:59:41 | i2 | |
| set.cpp:59:15:59:19 | call to begin | set.cpp:61:9:61:10 | i2 | |
| set.cpp:59:30:59:31 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:59:30:59:31 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:59:30:59:31 | s2 | set.cpp:59:33:59:35 | call to end | TAINT |
| set.cpp:59:40:59:41 | i2 | set.cpp:59:42:59:42 | call to operator++ | |
| set.cpp:59:40:59:41 | ref arg i2 | set.cpp:59:24:59:25 | i2 | |
| set.cpp:59:40:59:41 | ref arg i2 | set.cpp:59:40:59:41 | i2 | |
| set.cpp:59:40:59:41 | ref arg i2 | set.cpp:61:9:61:10 | i2 | |
| set.cpp:61:9:61:10 | i2 | set.cpp:61:8:61:8 | call to operator* | TAINT |
| set.cpp:65:19:65:21 | call to set | set.cpp:66:2:66:4 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:67:2:67:4 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:68:2:68:4 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:69:7:69:9 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:70:7:70:9 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:71:7:71:9 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:72:7:72:9 | s11 | |
| set.cpp:65:19:65:21 | call to set | set.cpp:126:1:126:1 | s11 | |
| set.cpp:66:2:66:4 | ref arg s11 | set.cpp:67:2:67:4 | s11 | |
| set.cpp:66:2:66:4 | ref arg s11 | set.cpp:68:2:68:4 | s11 | |
| set.cpp:66:2:66:4 | ref arg s11 | set.cpp:69:7:69:9 | s11 | |
| set.cpp:66:2:66:4 | ref arg s11 | set.cpp:70:7:70:9 | s11 | |
| set.cpp:66:2:66:4 | ref arg s11 | set.cpp:71:7:71:9 | s11 | |
| set.cpp:66:2:66:4 | ref arg s11 | set.cpp:72:7:72:9 | s11 | |
| set.cpp:66:2:66:4 | ref arg s11 | set.cpp:126:1:126:1 | s11 | |
| set.cpp:66:13:66:15 | a | set.cpp:66:2:66:4 | ref arg s11 | TAINT |
| set.cpp:66:13:66:15 | a | set.cpp:66:6:66:11 | call to insert | TAINT |
| set.cpp:67:2:67:4 | ref arg s11 | set.cpp:68:2:68:4 | s11 | |
| set.cpp:67:2:67:4 | ref arg s11 | set.cpp:69:7:69:9 | s11 | |
| set.cpp:67:2:67:4 | ref arg s11 | set.cpp:70:7:70:9 | s11 | |
| set.cpp:67:2:67:4 | ref arg s11 | set.cpp:71:7:71:9 | s11 | |
| set.cpp:67:2:67:4 | ref arg s11 | set.cpp:72:7:72:9 | s11 | |
| set.cpp:67:2:67:4 | ref arg s11 | set.cpp:126:1:126:1 | s11 | |
| set.cpp:67:13:67:18 | call to source | set.cpp:67:2:67:4 | ref arg s11 | TAINT |
| set.cpp:67:13:67:18 | call to source | set.cpp:67:6:67:11 | call to insert | TAINT |
| set.cpp:68:2:68:4 | ref arg s11 | set.cpp:69:7:69:9 | s11 | |
| set.cpp:68:2:68:4 | ref arg s11 | set.cpp:70:7:70:9 | s11 | |
| set.cpp:68:2:68:4 | ref arg s11 | set.cpp:71:7:71:9 | s11 | |
| set.cpp:68:2:68:4 | ref arg s11 | set.cpp:72:7:72:9 | s11 | |
| set.cpp:68:2:68:4 | ref arg s11 | set.cpp:126:1:126:1 | s11 | |
| set.cpp:68:13:68:15 | c | set.cpp:68:2:68:4 | ref arg s11 | TAINT |
| set.cpp:68:13:68:15 | c | set.cpp:68:6:68:11 | call to insert | TAINT |
| set.cpp:69:7:69:9 | ref arg s11 | set.cpp:70:7:70:9 | s11 | |
| set.cpp:69:7:69:9 | ref arg s11 | set.cpp:71:7:71:9 | s11 | |
| set.cpp:69:7:69:9 | ref arg s11 | set.cpp:72:7:72:9 | s11 | |
| set.cpp:69:7:69:9 | ref arg s11 | set.cpp:126:1:126:1 | s11 | |
| set.cpp:70:7:70:9 | ref arg s11 | set.cpp:71:7:71:9 | s11 | |
| set.cpp:70:7:70:9 | ref arg s11 | set.cpp:72:7:72:9 | s11 | |
| set.cpp:70:7:70:9 | ref arg s11 | set.cpp:126:1:126:1 | s11 | |
| set.cpp:71:7:71:9 | ref arg s11 | set.cpp:72:7:72:9 | s11 | |
| set.cpp:71:7:71:9 | ref arg s11 | set.cpp:126:1:126:1 | s11 | |
| set.cpp:71:28:71:32 | first | set.cpp:71:7:71:32 | call to iterator | |
| set.cpp:72:7:72:9 | ref arg s11 | set.cpp:126:1:126:1 | s11 | |
| set.cpp:72:28:72:33 | second | set.cpp:72:7:72:33 | call to iterator | |
| set.cpp:75:19:75:21 | call to set | set.cpp:76:2:76:4 | s12 | |
| set.cpp:75:19:75:21 | call to set | set.cpp:78:7:78:9 | s12 | |
| set.cpp:75:19:75:21 | call to set | set.cpp:82:2:82:4 | s12 | |
| set.cpp:75:19:75:21 | call to set | set.cpp:84:7:84:9 | s12 | |
| set.cpp:75:19:75:21 | call to set | set.cpp:126:1:126:1 | s12 | |
| set.cpp:75:24:75:26 | call to set | set.cpp:79:7:79:9 | s13 | |
| set.cpp:75:24:75:26 | call to set | set.cpp:82:11:82:13 | s13 | |
| set.cpp:75:24:75:26 | call to set | set.cpp:85:7:85:9 | s13 | |
| set.cpp:75:24:75:26 | call to set | set.cpp:126:1:126:1 | s13 | |
| set.cpp:75:29:75:31 | call to set | set.cpp:80:7:80:9 | s14 | |
| set.cpp:75:29:75:31 | call to set | set.cpp:83:2:83:4 | s14 | |
| set.cpp:75:29:75:31 | call to set | set.cpp:86:7:86:9 | s14 | |
| set.cpp:75:29:75:31 | call to set | set.cpp:126:1:126:1 | s14 | |
| set.cpp:75:34:75:36 | call to set | set.cpp:77:2:77:4 | s15 | |
| set.cpp:75:34:75:36 | call to set | set.cpp:81:7:81:9 | s15 | |
| set.cpp:75:34:75:36 | call to set | set.cpp:83:11:83:13 | s15 | |
| set.cpp:75:34:75:36 | call to set | set.cpp:87:7:87:9 | s15 | |
| set.cpp:75:34:75:36 | call to set | set.cpp:126:1:126:1 | s15 | |
| set.cpp:76:2:76:4 | ref arg s12 | set.cpp:78:7:78:9 | s12 | |
| set.cpp:76:2:76:4 | ref arg s12 | set.cpp:82:2:82:4 | s12 | |
| set.cpp:76:2:76:4 | ref arg s12 | set.cpp:84:7:84:9 | s12 | |
| set.cpp:76:2:76:4 | ref arg s12 | set.cpp:126:1:126:1 | s12 | |
| set.cpp:76:13:76:18 | call to source | set.cpp:76:2:76:4 | ref arg s12 | TAINT |
| set.cpp:76:13:76:18 | call to source | set.cpp:76:6:76:11 | call to insert | TAINT |
| set.cpp:77:2:77:4 | ref arg s15 | set.cpp:81:7:81:9 | s15 | |
| set.cpp:77:2:77:4 | ref arg s15 | set.cpp:83:11:83:13 | s15 | |
| set.cpp:77:2:77:4 | ref arg s15 | set.cpp:87:7:87:9 | s15 | |
| set.cpp:77:2:77:4 | ref arg s15 | set.cpp:126:1:126:1 | s15 | |
| set.cpp:77:13:77:18 | call to source | set.cpp:77:2:77:4 | ref arg s15 | TAINT |
| set.cpp:77:13:77:18 | call to source | set.cpp:77:6:77:11 | call to insert | TAINT |
| set.cpp:78:7:78:9 | s12 | set.cpp:78:7:78:9 | call to set | |
| set.cpp:79:7:79:9 | s13 | set.cpp:79:7:79:9 | call to set | |
| set.cpp:80:7:80:9 | s14 | set.cpp:80:7:80:9 | call to set | |
| set.cpp:81:7:81:9 | s15 | set.cpp:81:7:81:9 | call to set | |
| set.cpp:82:2:82:4 | ref arg s12 | set.cpp:84:7:84:9 | s12 | |
| set.cpp:82:2:82:4 | ref arg s12 | set.cpp:126:1:126:1 | s12 | |
| set.cpp:82:2:82:4 | s12 | set.cpp:82:11:82:13 | ref arg s13 | TAINT |
| set.cpp:82:11:82:13 | ref arg s13 | set.cpp:85:7:85:9 | s13 | |
| set.cpp:82:11:82:13 | ref arg s13 | set.cpp:126:1:126:1 | s13 | |
| set.cpp:82:11:82:13 | s13 | set.cpp:82:2:82:4 | ref arg s12 | TAINT |
| set.cpp:83:2:83:4 | ref arg s14 | set.cpp:86:7:86:9 | s14 | |
| set.cpp:83:2:83:4 | ref arg s14 | set.cpp:126:1:126:1 | s14 | |
| set.cpp:83:2:83:4 | s14 | set.cpp:83:11:83:13 | ref arg s15 | TAINT |
| set.cpp:83:11:83:13 | ref arg s15 | set.cpp:87:7:87:9 | s15 | |
| set.cpp:83:11:83:13 | ref arg s15 | set.cpp:126:1:126:1 | s15 | |
| set.cpp:83:11:83:13 | s15 | set.cpp:83:2:83:4 | ref arg s14 | TAINT |
| set.cpp:84:7:84:9 | s12 | set.cpp:84:7:84:9 | call to set | |
| set.cpp:85:7:85:9 | s13 | set.cpp:85:7:85:9 | call to set | |
| set.cpp:86:7:86:9 | s14 | set.cpp:86:7:86:9 | call to set | |
| set.cpp:87:7:87:9 | s15 | set.cpp:87:7:87:9 | call to set | |
| set.cpp:90:19:90:21 | call to set | set.cpp:91:2:91:4 | s16 | |
| set.cpp:90:19:90:21 | call to set | set.cpp:95:7:95:9 | s16 | |
| set.cpp:90:19:90:21 | call to set | set.cpp:99:2:99:4 | s16 | |
| set.cpp:90:19:90:21 | call to set | set.cpp:101:7:101:9 | s16 | |
| set.cpp:90:19:90:21 | call to set | set.cpp:126:1:126:1 | s16 | |
| set.cpp:90:24:90:26 | call to set | set.cpp:92:2:92:4 | s17 | |
| set.cpp:90:24:90:26 | call to set | set.cpp:96:7:96:9 | s17 | |
| set.cpp:90:24:90:26 | call to set | set.cpp:99:12:99:14 | s17 | |
| set.cpp:90:24:90:26 | call to set | set.cpp:102:7:102:9 | s17 | |
| set.cpp:90:24:90:26 | call to set | set.cpp:126:1:126:1 | s17 | |
| set.cpp:90:29:90:31 | call to set | set.cpp:93:2:93:4 | s18 | |
| set.cpp:90:29:90:31 | call to set | set.cpp:97:7:97:9 | s18 | |
| set.cpp:90:29:90:31 | call to set | set.cpp:100:2:100:4 | s18 | |
| set.cpp:90:29:90:31 | call to set | set.cpp:103:7:103:9 | s18 | |
| set.cpp:90:29:90:31 | call to set | set.cpp:126:1:126:1 | s18 | |
| set.cpp:90:34:90:36 | call to set | set.cpp:94:2:94:4 | s19 | |
| set.cpp:90:34:90:36 | call to set | set.cpp:98:7:98:9 | s19 | |
| set.cpp:90:34:90:36 | call to set | set.cpp:100:12:100:14 | s19 | |
| set.cpp:90:34:90:36 | call to set | set.cpp:104:7:104:9 | s19 | |
| set.cpp:90:34:90:36 | call to set | set.cpp:126:1:126:1 | s19 | |
| set.cpp:91:2:91:4 | ref arg s16 | set.cpp:95:7:95:9 | s16 | |
| set.cpp:91:2:91:4 | ref arg s16 | set.cpp:99:2:99:4 | s16 | |
| set.cpp:91:2:91:4 | ref arg s16 | set.cpp:101:7:101:9 | s16 | |
| set.cpp:91:2:91:4 | ref arg s16 | set.cpp:126:1:126:1 | s16 | |
| set.cpp:91:13:91:18 | call to source | set.cpp:91:2:91:4 | ref arg s16 | TAINT |
| set.cpp:91:13:91:18 | call to source | set.cpp:91:6:91:11 | call to insert | TAINT |
| set.cpp:92:2:92:4 | ref arg s17 | set.cpp:96:7:96:9 | s17 | |
| set.cpp:92:2:92:4 | ref arg s17 | set.cpp:99:12:99:14 | s17 | |
| set.cpp:92:2:92:4 | ref arg s17 | set.cpp:102:7:102:9 | s17 | |
| set.cpp:92:2:92:4 | ref arg s17 | set.cpp:126:1:126:1 | s17 | |
| set.cpp:92:13:92:17 | abc | set.cpp:92:2:92:4 | ref arg s17 | TAINT |
| set.cpp:92:13:92:17 | abc | set.cpp:92:6:92:11 | call to insert | TAINT |
| set.cpp:93:2:93:4 | ref arg s18 | set.cpp:97:7:97:9 | s18 | |
| set.cpp:93:2:93:4 | ref arg s18 | set.cpp:100:2:100:4 | s18 | |
| set.cpp:93:2:93:4 | ref arg s18 | set.cpp:103:7:103:9 | s18 | |
| set.cpp:93:2:93:4 | ref arg s18 | set.cpp:126:1:126:1 | s18 | |
| set.cpp:93:13:93:17 | def | set.cpp:93:2:93:4 | ref arg s18 | TAINT |
| set.cpp:93:13:93:17 | def | set.cpp:93:6:93:11 | call to insert | TAINT |
| set.cpp:94:2:94:4 | ref arg s19 | set.cpp:98:7:98:9 | s19 | |
| set.cpp:94:2:94:4 | ref arg s19 | set.cpp:100:12:100:14 | s19 | |
| set.cpp:94:2:94:4 | ref arg s19 | set.cpp:104:7:104:9 | s19 | |
| set.cpp:94:2:94:4 | ref arg s19 | set.cpp:126:1:126:1 | s19 | |
| set.cpp:94:13:94:18 | call to source | set.cpp:94:2:94:4 | ref arg s19 | TAINT |
| set.cpp:94:13:94:18 | call to source | set.cpp:94:6:94:11 | call to insert | TAINT |
| set.cpp:95:7:95:9 | s16 | set.cpp:95:7:95:9 | call to set | |
| set.cpp:96:7:96:9 | s17 | set.cpp:96:7:96:9 | call to set | |
| set.cpp:97:7:97:9 | s18 | set.cpp:97:7:97:9 | call to set | |
| set.cpp:98:7:98:9 | s19 | set.cpp:98:7:98:9 | call to set | |
| set.cpp:99:2:99:4 | ref arg s16 | set.cpp:101:7:101:9 | s16 | |
| set.cpp:99:2:99:4 | ref arg s16 | set.cpp:126:1:126:1 | s16 | |
| set.cpp:99:12:99:14 | ref arg s17 | set.cpp:102:7:102:9 | s17 | |
| set.cpp:99:12:99:14 | ref arg s17 | set.cpp:126:1:126:1 | s17 | |
| set.cpp:100:2:100:4 | ref arg s18 | set.cpp:103:7:103:9 | s18 | |
| set.cpp:100:2:100:4 | ref arg s18 | set.cpp:126:1:126:1 | s18 | |
| set.cpp:100:12:100:14 | ref arg s19 | set.cpp:104:7:104:9 | s19 | |
| set.cpp:100:12:100:14 | ref arg s19 | set.cpp:126:1:126:1 | s19 | |
| set.cpp:101:7:101:9 | s16 | set.cpp:101:7:101:9 | call to set | |
| set.cpp:102:7:102:9 | s17 | set.cpp:102:7:102:9 | call to set | |
| set.cpp:103:7:103:9 | s18 | set.cpp:103:7:103:9 | call to set | |
| set.cpp:104:7:104:9 | s19 | set.cpp:104:7:104:9 | call to set | |
| set.cpp:107:19:107:21 | call to set | set.cpp:108:2:108:4 | s20 | |
| set.cpp:107:19:107:21 | call to set | set.cpp:109:2:109:4 | s20 | |
| set.cpp:107:19:107:21 | call to set | set.cpp:110:7:110:9 | s20 | |
| set.cpp:107:19:107:21 | call to set | set.cpp:111:7:111:9 | s20 | |
| set.cpp:107:19:107:21 | call to set | set.cpp:111:17:111:19 | s20 | |
| set.cpp:107:19:107:21 | call to set | set.cpp:112:7:112:9 | s20 | |
| set.cpp:107:19:107:21 | call to set | set.cpp:113:2:113:4 | s20 | |
| set.cpp:107:19:107:21 | call to set | set.cpp:114:7:114:9 | s20 | |
| set.cpp:107:19:107:21 | call to set | set.cpp:126:1:126:1 | s20 | |
| set.cpp:108:2:108:4 | ref arg s20 | set.cpp:109:2:109:4 | s20 | |
| set.cpp:108:2:108:4 | ref arg s20 | set.cpp:110:7:110:9 | s20 | |
| set.cpp:108:2:108:4 | ref arg s20 | set.cpp:111:7:111:9 | s20 | |
| set.cpp:108:2:108:4 | ref arg s20 | set.cpp:111:17:111:19 | s20 | |
| set.cpp:108:2:108:4 | ref arg s20 | set.cpp:112:7:112:9 | s20 | |
| set.cpp:108:2:108:4 | ref arg s20 | set.cpp:113:2:113:4 | s20 | |
| set.cpp:108:2:108:4 | ref arg s20 | set.cpp:114:7:114:9 | s20 | |
| set.cpp:108:2:108:4 | ref arg s20 | set.cpp:126:1:126:1 | s20 | |
| set.cpp:108:13:108:18 | call to source | set.cpp:108:2:108:4 | ref arg s20 | TAINT |
| set.cpp:108:13:108:18 | call to source | set.cpp:108:6:108:11 | call to insert | TAINT |
| set.cpp:109:2:109:4 | ref arg s20 | set.cpp:110:7:110:9 | s20 | |
| set.cpp:109:2:109:4 | ref arg s20 | set.cpp:111:7:111:9 | s20 | |
| set.cpp:109:2:109:4 | ref arg s20 | set.cpp:111:17:111:19 | s20 | |
| set.cpp:109:2:109:4 | ref arg s20 | set.cpp:112:7:112:9 | s20 | |
| set.cpp:109:2:109:4 | ref arg s20 | set.cpp:113:2:113:4 | s20 | |
| set.cpp:109:2:109:4 | ref arg s20 | set.cpp:114:7:114:9 | s20 | |
| set.cpp:109:2:109:4 | ref arg s20 | set.cpp:126:1:126:1 | s20 | |
| set.cpp:109:13:109:18 | call to source | set.cpp:109:2:109:4 | ref arg s20 | TAINT |
| set.cpp:109:13:109:18 | call to source | set.cpp:109:6:109:11 | call to insert | TAINT |
| set.cpp:110:7:110:9 | s20 | set.cpp:110:7:110:9 | call to set | |
| set.cpp:111:7:111:9 | ref arg s20 | set.cpp:112:7:112:9 | s20 | |
| set.cpp:111:7:111:9 | ref arg s20 | set.cpp:113:2:113:4 | s20 | |
| set.cpp:111:7:111:9 | ref arg s20 | set.cpp:114:7:114:9 | s20 | |
| set.cpp:111:7:111:9 | ref arg s20 | set.cpp:126:1:126:1 | s20 | |
| set.cpp:111:7:111:9 | s20 | set.cpp:111:11:111:15 | call to erase | TAINT |
| set.cpp:111:17:111:19 | ref arg s20 | set.cpp:111:7:111:9 | s20 | |
| set.cpp:111:17:111:19 | ref arg s20 | set.cpp:112:7:112:9 | s20 | |
| set.cpp:111:17:111:19 | ref arg s20 | set.cpp:113:2:113:4 | s20 | |
| set.cpp:111:17:111:19 | ref arg s20 | set.cpp:114:7:114:9 | s20 | |
| set.cpp:111:17:111:19 | ref arg s20 | set.cpp:126:1:126:1 | s20 | |
| set.cpp:111:17:111:19 | s20 | set.cpp:111:21:111:25 | call to begin | TAINT |
| set.cpp:112:7:112:9 | s20 | set.cpp:112:7:112:9 | call to set | |
| set.cpp:113:2:113:4 | ref arg s20 | set.cpp:114:7:114:9 | s20 | |
| set.cpp:113:2:113:4 | ref arg s20 | set.cpp:126:1:126:1 | s20 | |
| set.cpp:114:7:114:9 | s20 | set.cpp:114:7:114:9 | call to set | |
| set.cpp:117:19:117:21 | call to set | set.cpp:118:7:118:9 | s21 | |
| set.cpp:117:19:117:21 | call to set | set.cpp:119:7:119:9 | s21 | |
| set.cpp:117:19:117:21 | call to set | set.cpp:120:7:120:9 | s21 | |
| set.cpp:117:19:117:21 | call to set | set.cpp:121:7:121:9 | s21 | |
| set.cpp:117:19:117:21 | call to set | set.cpp:126:1:126:1 | s21 | |
| set.cpp:117:24:117:26 | call to set | set.cpp:122:7:122:9 | s22 | |
| set.cpp:117:24:117:26 | call to set | set.cpp:122:24:122:26 | s22 | |
| set.cpp:117:24:117:26 | call to set | set.cpp:123:7:123:9 | s22 | |
| set.cpp:117:24:117:26 | call to set | set.cpp:124:7:124:9 | s22 | |
| set.cpp:117:24:117:26 | call to set | set.cpp:124:24:124:26 | s22 | |
| set.cpp:117:24:117:26 | call to set | set.cpp:125:7:125:9 | s22 | |
| set.cpp:117:24:117:26 | call to set | set.cpp:126:1:126:1 | s22 | |
| set.cpp:118:7:118:9 | ref arg s21 | set.cpp:119:7:119:9 | s21 | |
| set.cpp:118:7:118:9 | ref arg s21 | set.cpp:120:7:120:9 | s21 | |
| set.cpp:118:7:118:9 | ref arg s21 | set.cpp:121:7:121:9 | s21 | |
| set.cpp:118:7:118:9 | ref arg s21 | set.cpp:126:1:126:1 | s21 | |
| set.cpp:118:26:118:30 | first | set.cpp:118:7:118:30 | call to iterator | |
| set.cpp:119:7:119:9 | s21 | set.cpp:119:7:119:9 | call to set | |
| set.cpp:120:7:120:9 | ref arg s21 | set.cpp:121:7:121:9 | s21 | |
| set.cpp:120:7:120:9 | ref arg s21 | set.cpp:126:1:126:1 | s21 | |
| set.cpp:120:29:120:33 | first | set.cpp:120:7:120:33 | call to iterator | |
| set.cpp:121:7:121:9 | s21 | set.cpp:121:7:121:9 | call to set | |
| set.cpp:122:7:122:9 | ref arg s22 | set.cpp:123:7:123:9 | s22 | |
| set.cpp:122:7:122:9 | ref arg s22 | set.cpp:124:7:124:9 | s22 | |
| set.cpp:122:7:122:9 | ref arg s22 | set.cpp:124:24:124:26 | s22 | |
| set.cpp:122:7:122:9 | ref arg s22 | set.cpp:125:7:125:9 | s22 | |
| set.cpp:122:7:122:9 | ref arg s22 | set.cpp:126:1:126:1 | s22 | |
| set.cpp:122:24:122:26 | ref arg s22 | set.cpp:122:7:122:9 | s22 | |
| set.cpp:122:24:122:26 | ref arg s22 | set.cpp:123:7:123:9 | s22 | |
| set.cpp:122:24:122:26 | ref arg s22 | set.cpp:124:7:124:9 | s22 | |
| set.cpp:122:24:122:26 | ref arg s22 | set.cpp:124:24:124:26 | s22 | |
| set.cpp:122:24:122:26 | ref arg s22 | set.cpp:125:7:125:9 | s22 | |
| set.cpp:122:24:122:26 | ref arg s22 | set.cpp:126:1:126:1 | s22 | |
| set.cpp:122:24:122:26 | s22 | set.cpp:122:28:122:32 | call to begin | TAINT |
| set.cpp:122:28:122:32 | call to begin | set.cpp:122:24:122:34 | call to iterator | TAINT |
| set.cpp:123:7:123:9 | s22 | set.cpp:123:7:123:9 | call to set | |
| set.cpp:124:7:124:9 | ref arg s22 | set.cpp:125:7:125:9 | s22 | |
| set.cpp:124:7:124:9 | ref arg s22 | set.cpp:126:1:126:1 | s22 | |
| set.cpp:124:24:124:26 | ref arg s22 | set.cpp:124:7:124:9 | s22 | |
| set.cpp:124:24:124:26 | ref arg s22 | set.cpp:125:7:125:9 | s22 | |
| set.cpp:124:24:124:26 | ref arg s22 | set.cpp:126:1:126:1 | s22 | |
| set.cpp:124:24:124:26 | s22 | set.cpp:124:28:124:32 | call to begin | TAINT |
| set.cpp:124:28:124:32 | call to begin | set.cpp:124:24:124:34 | call to iterator | TAINT |
| set.cpp:125:7:125:9 | s22 | set.cpp:125:7:125:9 | call to set | |
| set.cpp:131:29:131:30 | call to unordered_set | set.cpp:133:7:133:8 | s1 | |
| set.cpp:131:29:131:30 | call to unordered_set | set.cpp:137:12:137:13 | s1 | |
| set.cpp:131:29:131:30 | call to unordered_set | set.cpp:137:24:137:25 | s1 | |
| set.cpp:131:29:131:30 | call to unordered_set | set.cpp:139:7:139:8 | s1 | |
| set.cpp:131:29:131:30 | call to unordered_set | set.cpp:145:7:145:8 | s1 | |
| set.cpp:131:29:131:30 | call to unordered_set | set.cpp:169:12:169:13 | s1 | |
| set.cpp:131:29:131:30 | call to unordered_set | set.cpp:169:30:169:31 | s1 | |
| set.cpp:131:29:131:30 | call to unordered_set | set.cpp:238:1:238:1 | s1 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:134:7:134:8 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:138:12:138:13 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:138:24:138:25 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:140:7:140:8 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:146:7:146:8 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:153:32:153:33 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:154:34:154:35 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:155:32:155:33 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:155:44:155:45 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:157:8:157:9 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:173:12:173:13 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:173:30:173:31 | s2 | |
| set.cpp:131:33:131:34 | call to unordered_set | set.cpp:238:1:238:1 | s2 | |
| set.cpp:131:37:131:38 | call to unordered_set | set.cpp:135:7:135:8 | s3 | |
| set.cpp:131:37:131:38 | call to unordered_set | set.cpp:135:17:135:18 | s3 | |
| set.cpp:131:37:131:38 | call to unordered_set | set.cpp:141:7:141:8 | s3 | |
| set.cpp:131:37:131:38 | call to unordered_set | set.cpp:147:7:147:8 | s3 | |
| set.cpp:131:37:131:38 | call to unordered_set | set.cpp:238:1:238:1 | s3 | |
| set.cpp:131:41:131:42 | call to unordered_set | set.cpp:136:7:136:8 | s4 | |
| set.cpp:131:41:131:42 | call to unordered_set | set.cpp:136:17:136:18 | s4 | |
| set.cpp:131:41:131:42 | call to unordered_set | set.cpp:142:7:142:8 | s4 | |
| set.cpp:131:41:131:42 | call to unordered_set | set.cpp:148:7:148:8 | s4 | |
| set.cpp:131:41:131:42 | call to unordered_set | set.cpp:238:1:238:1 | s4 | |
| set.cpp:131:45:131:46 | call to unordered_set | set.cpp:137:2:137:3 | s5 | |
| set.cpp:131:45:131:46 | call to unordered_set | set.cpp:143:7:143:8 | s5 | |
| set.cpp:131:45:131:46 | call to unordered_set | set.cpp:149:7:149:8 | s5 | |
| set.cpp:131:45:131:46 | call to unordered_set | set.cpp:238:1:238:1 | s5 | |
| set.cpp:131:49:131:50 | call to unordered_set | set.cpp:138:2:138:3 | s6 | |
| set.cpp:131:49:131:50 | call to unordered_set | set.cpp:144:7:144:8 | s6 | |
| set.cpp:131:49:131:50 | call to unordered_set | set.cpp:150:7:150:8 | s6 | |
| set.cpp:131:49:131:50 | call to unordered_set | set.cpp:238:1:238:1 | s6 | |
| set.cpp:133:7:133:8 | ref arg s1 | set.cpp:137:12:137:13 | s1 | |
| set.cpp:133:7:133:8 | ref arg s1 | set.cpp:137:24:137:25 | s1 | |
| set.cpp:133:7:133:8 | ref arg s1 | set.cpp:139:7:139:8 | s1 | |
| set.cpp:133:7:133:8 | ref arg s1 | set.cpp:145:7:145:8 | s1 | |
| set.cpp:133:7:133:8 | ref arg s1 | set.cpp:169:12:169:13 | s1 | |
| set.cpp:133:7:133:8 | ref arg s1 | set.cpp:169:30:169:31 | s1 | |
| set.cpp:133:7:133:8 | ref arg s1 | set.cpp:238:1:238:1 | s1 | |
| set.cpp:133:17:133:21 | abc | set.cpp:133:7:133:8 | ref arg s1 | TAINT |
| set.cpp:133:17:133:21 | abc | set.cpp:133:10:133:15 | call to insert | TAINT |
| set.cpp:133:24:133:28 | first | set.cpp:133:7:133:28 | call to iterator | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:138:12:138:13 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:138:24:138:25 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:140:7:140:8 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:146:7:146:8 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:153:32:153:33 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:154:34:154:35 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:155:32:155:33 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:155:44:155:45 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:157:8:157:9 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:173:12:173:13 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:134:7:134:8 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:134:17:134:22 | call to source | set.cpp:134:7:134:8 | ref arg s2 | TAINT |
| set.cpp:134:17:134:22 | call to source | set.cpp:134:10:134:15 | call to insert | TAINT |
| set.cpp:134:27:134:31 | first | set.cpp:134:7:134:31 | call to iterator | |
| set.cpp:135:7:135:8 | ref arg s3 | set.cpp:141:7:141:8 | s3 | |
| set.cpp:135:7:135:8 | ref arg s3 | set.cpp:147:7:147:8 | s3 | |
| set.cpp:135:7:135:8 | ref arg s3 | set.cpp:238:1:238:1 | s3 | |
| set.cpp:135:17:135:18 | ref arg s3 | set.cpp:135:7:135:8 | s3 | |
| set.cpp:135:17:135:18 | ref arg s3 | set.cpp:141:7:141:8 | s3 | |
| set.cpp:135:17:135:18 | ref arg s3 | set.cpp:147:7:147:8 | s3 | |
| set.cpp:135:17:135:18 | ref arg s3 | set.cpp:238:1:238:1 | s3 | |
| set.cpp:135:17:135:18 | s3 | set.cpp:135:20:135:24 | call to begin | TAINT |
| set.cpp:135:20:135:24 | call to begin | set.cpp:135:17:135:26 | call to iterator | TAINT |
| set.cpp:135:29:135:33 | abc | set.cpp:135:7:135:8 | ref arg s3 | TAINT |
| set.cpp:135:29:135:33 | abc | set.cpp:135:10:135:15 | call to insert | TAINT |
| set.cpp:136:7:136:8 | ref arg s4 | set.cpp:142:7:142:8 | s4 | |
| set.cpp:136:7:136:8 | ref arg s4 | set.cpp:148:7:148:8 | s4 | |
| set.cpp:136:7:136:8 | ref arg s4 | set.cpp:238:1:238:1 | s4 | |
| set.cpp:136:17:136:18 | ref arg s4 | set.cpp:136:7:136:8 | s4 | |
| set.cpp:136:17:136:18 | ref arg s4 | set.cpp:142:7:142:8 | s4 | |
| set.cpp:136:17:136:18 | ref arg s4 | set.cpp:148:7:148:8 | s4 | |
| set.cpp:136:17:136:18 | ref arg s4 | set.cpp:238:1:238:1 | s4 | |
| set.cpp:136:17:136:18 | s4 | set.cpp:136:20:136:24 | call to begin | TAINT |
| set.cpp:136:20:136:24 | call to begin | set.cpp:136:17:136:26 | call to iterator | TAINT |
| set.cpp:136:29:136:34 | call to source | set.cpp:136:7:136:8 | ref arg s4 | TAINT |
| set.cpp:136:29:136:34 | call to source | set.cpp:136:10:136:15 | call to insert | TAINT |
| set.cpp:137:2:137:3 | ref arg s5 | set.cpp:143:7:143:8 | s5 | |
| set.cpp:137:2:137:3 | ref arg s5 | set.cpp:149:7:149:8 | s5 | |
| set.cpp:137:2:137:3 | ref arg s5 | set.cpp:238:1:238:1 | s5 | |
| set.cpp:137:12:137:13 | ref arg s1 | set.cpp:137:24:137:25 | s1 | |
| set.cpp:137:12:137:13 | ref arg s1 | set.cpp:139:7:139:8 | s1 | |
| set.cpp:137:12:137:13 | ref arg s1 | set.cpp:145:7:145:8 | s1 | |
| set.cpp:137:12:137:13 | ref arg s1 | set.cpp:169:12:169:13 | s1 | |
| set.cpp:137:12:137:13 | ref arg s1 | set.cpp:169:30:169:31 | s1 | |
| set.cpp:137:12:137:13 | ref arg s1 | set.cpp:238:1:238:1 | s1 | |
| set.cpp:137:12:137:13 | s1 | set.cpp:137:15:137:19 | call to begin | TAINT |
| set.cpp:137:24:137:25 | ref arg s1 | set.cpp:139:7:139:8 | s1 | |
| set.cpp:137:24:137:25 | ref arg s1 | set.cpp:145:7:145:8 | s1 | |
| set.cpp:137:24:137:25 | ref arg s1 | set.cpp:169:12:169:13 | s1 | |
| set.cpp:137:24:137:25 | ref arg s1 | set.cpp:169:30:169:31 | s1 | |
| set.cpp:137:24:137:25 | ref arg s1 | set.cpp:238:1:238:1 | s1 | |
| set.cpp:137:24:137:25 | s1 | set.cpp:137:27:137:29 | call to end | TAINT |
| set.cpp:137:27:137:29 | call to end | set.cpp:137:2:137:3 | ref arg s5 | TAINT |
| set.cpp:137:27:137:29 | call to end | set.cpp:137:5:137:10 | call to insert | TAINT |
| set.cpp:138:2:138:3 | ref arg s6 | set.cpp:144:7:144:8 | s6 | |
| set.cpp:138:2:138:3 | ref arg s6 | set.cpp:150:7:150:8 | s6 | |
| set.cpp:138:2:138:3 | ref arg s6 | set.cpp:238:1:238:1 | s6 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:138:24:138:25 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:140:7:140:8 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:146:7:146:8 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:153:32:153:33 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:154:34:154:35 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:155:32:155:33 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:155:44:155:45 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:157:8:157:9 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:173:12:173:13 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:138:12:138:13 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:138:12:138:13 | s2 | set.cpp:138:15:138:19 | call to begin | TAINT |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:140:7:140:8 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:146:7:146:8 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:153:32:153:33 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:154:34:154:35 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:155:32:155:33 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:155:44:155:45 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:157:8:157:9 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:173:12:173:13 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:138:24:138:25 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:138:24:138:25 | s2 | set.cpp:138:27:138:29 | call to end | TAINT |
| set.cpp:138:27:138:29 | call to end | set.cpp:138:2:138:3 | ref arg s6 | TAINT |
| set.cpp:138:27:138:29 | call to end | set.cpp:138:5:138:10 | call to insert | TAINT |
| set.cpp:139:7:139:8 | s1 | set.cpp:139:7:139:8 | call to unordered_set | |
| set.cpp:140:7:140:8 | s2 | set.cpp:140:7:140:8 | call to unordered_set | |
| set.cpp:141:7:141:8 | s3 | set.cpp:141:7:141:8 | call to unordered_set | |
| set.cpp:142:7:142:8 | s4 | set.cpp:142:7:142:8 | call to unordered_set | |
| set.cpp:143:7:143:8 | s5 | set.cpp:143:7:143:8 | call to unordered_set | |
| set.cpp:144:7:144:8 | s6 | set.cpp:144:7:144:8 | call to unordered_set | |
| set.cpp:145:7:145:8 | ref arg s1 | set.cpp:169:12:169:13 | s1 | |
| set.cpp:145:7:145:8 | ref arg s1 | set.cpp:169:30:169:31 | s1 | |
| set.cpp:145:7:145:8 | ref arg s1 | set.cpp:238:1:238:1 | s1 | |
| set.cpp:145:7:145:8 | s1 | set.cpp:145:10:145:13 | call to find | TAINT |
| set.cpp:146:7:146:8 | ref arg s2 | set.cpp:153:32:153:33 | s2 | |
| set.cpp:146:7:146:8 | ref arg s2 | set.cpp:154:34:154:35 | s2 | |
| set.cpp:146:7:146:8 | ref arg s2 | set.cpp:155:32:155:33 | s2 | |
| set.cpp:146:7:146:8 | ref arg s2 | set.cpp:155:44:155:45 | s2 | |
| set.cpp:146:7:146:8 | ref arg s2 | set.cpp:157:8:157:9 | s2 | |
| set.cpp:146:7:146:8 | ref arg s2 | set.cpp:173:12:173:13 | s2 | |
| set.cpp:146:7:146:8 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:146:7:146:8 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:146:7:146:8 | s2 | set.cpp:146:10:146:13 | call to find | TAINT |
| set.cpp:147:7:147:8 | ref arg s3 | set.cpp:238:1:238:1 | s3 | |
| set.cpp:147:7:147:8 | s3 | set.cpp:147:10:147:13 | call to find | TAINT |
| set.cpp:148:7:148:8 | ref arg s4 | set.cpp:238:1:238:1 | s4 | |
| set.cpp:148:7:148:8 | s4 | set.cpp:148:10:148:13 | call to find | TAINT |
| set.cpp:149:7:149:8 | ref arg s5 | set.cpp:238:1:238:1 | s5 | |
| set.cpp:149:7:149:8 | s5 | set.cpp:149:10:149:13 | call to find | TAINT |
| set.cpp:150:7:150:8 | ref arg s6 | set.cpp:238:1:238:1 | s6 | |
| set.cpp:150:7:150:8 | s6 | set.cpp:150:10:150:13 | call to find | TAINT |
| set.cpp:153:32:153:33 | s2 | set.cpp:153:32:153:34 | call to unordered_set | |
| set.cpp:153:32:153:34 | call to unordered_set | set.cpp:158:7:158:8 | s7 | |
| set.cpp:153:32:153:34 | call to unordered_set | set.cpp:162:7:162:8 | s7 | |
| set.cpp:153:32:153:34 | call to unordered_set | set.cpp:238:1:238:1 | s7 | |
| set.cpp:154:33:154:35 | call to unordered_set | set.cpp:159:7:159:8 | s8 | |
| set.cpp:154:33:154:35 | call to unordered_set | set.cpp:163:7:163:8 | s8 | |
| set.cpp:154:33:154:35 | call to unordered_set | set.cpp:238:1:238:1 | s8 | |
| set.cpp:154:34:154:35 | s2 | set.cpp:154:33:154:35 | call to unordered_set | |
| set.cpp:155:32:155:33 | ref arg s2 | set.cpp:155:44:155:45 | s2 | |
| set.cpp:155:32:155:33 | ref arg s2 | set.cpp:157:8:157:9 | s2 | |
| set.cpp:155:32:155:33 | ref arg s2 | set.cpp:173:12:173:13 | s2 | |
| set.cpp:155:32:155:33 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:155:32:155:33 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:155:32:155:33 | s2 | set.cpp:155:35:155:39 | call to begin | TAINT |
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:160:7:160:8 | s9 | |
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:164:7:164:8 | s9 | |
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:238:1:238:1 | s9 | |
| set.cpp:155:35:155:39 | call to begin | set.cpp:155:32:155:52 | call to unordered_set | TAINT |
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:157:8:157:9 | s2 | |
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:173:12:173:13 | s2 | |
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:155:44:155:45 | s2 | set.cpp:155:47:155:49 | call to end | TAINT |
| set.cpp:155:47:155:49 | call to end | set.cpp:155:32:155:52 | call to unordered_set | TAINT |
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:157:2:157:4 | s10 | |
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:161:7:161:9 | s10 | |
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:165:7:165:9 | s10 | |
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:238:1:238:1 | s10 | |
| set.cpp:157:2:157:4 | ref arg s10 | set.cpp:161:7:161:9 | s10 | |
| set.cpp:157:2:157:4 | ref arg s10 | set.cpp:165:7:165:9 | s10 | |
| set.cpp:157:2:157:4 | ref arg s10 | set.cpp:238:1:238:1 | s10 | |
| set.cpp:157:8:157:9 | s2 | set.cpp:157:2:157:4 | ref arg s10 | TAINT |
| set.cpp:157:8:157:9 | s2 | set.cpp:157:6:157:6 | call to operator= | TAINT |
| set.cpp:158:7:158:8 | s7 | set.cpp:158:7:158:8 | call to unordered_set | |
| set.cpp:159:7:159:8 | s8 | set.cpp:159:7:159:8 | call to unordered_set | |
| set.cpp:160:7:160:8 | s9 | set.cpp:160:7:160:8 | call to unordered_set | |
| set.cpp:161:7:161:9 | s10 | set.cpp:161:7:161:9 | call to unordered_set | |
| set.cpp:162:7:162:8 | ref arg s7 | set.cpp:238:1:238:1 | s7 | |
| set.cpp:162:7:162:8 | s7 | set.cpp:162:10:162:13 | call to find | TAINT |
| set.cpp:163:7:163:8 | ref arg s8 | set.cpp:238:1:238:1 | s8 | |
| set.cpp:163:7:163:8 | s8 | set.cpp:163:10:163:13 | call to find | TAINT |
| set.cpp:164:7:164:8 | ref arg s9 | set.cpp:238:1:238:1 | s9 | |
| set.cpp:164:7:164:8 | s9 | set.cpp:164:10:164:13 | call to find | TAINT |
| set.cpp:165:7:165:9 | ref arg s10 | set.cpp:238:1:238:1 | s10 | |
| set.cpp:165:7:165:9 | s10 | set.cpp:165:11:165:14 | call to find | TAINT |
| set.cpp:169:12:169:13 | ref arg s1 | set.cpp:169:30:169:31 | s1 | |
| set.cpp:169:12:169:13 | ref arg s1 | set.cpp:238:1:238:1 | s1 | |
| set.cpp:169:12:169:13 | s1 | set.cpp:169:15:169:19 | call to begin | TAINT |
| set.cpp:169:15:169:19 | call to begin | set.cpp:169:7:169:21 | ... = ... | |
| set.cpp:169:15:169:19 | call to begin | set.cpp:169:24:169:25 | i1 | |
| set.cpp:169:15:169:19 | call to begin | set.cpp:169:40:169:41 | i1 | |
| set.cpp:169:15:169:19 | call to begin | set.cpp:171:9:171:10 | i1 | |
| set.cpp:169:30:169:31 | ref arg s1 | set.cpp:169:30:169:31 | s1 | |
| set.cpp:169:30:169:31 | ref arg s1 | set.cpp:238:1:238:1 | s1 | |
| set.cpp:169:30:169:31 | s1 | set.cpp:169:33:169:35 | call to end | TAINT |
| set.cpp:169:40:169:41 | i1 | set.cpp:169:42:169:42 | call to operator++ | |
| set.cpp:169:40:169:41 | ref arg i1 | set.cpp:169:24:169:25 | i1 | |
| set.cpp:169:40:169:41 | ref arg i1 | set.cpp:169:40:169:41 | i1 | |
| set.cpp:169:40:169:41 | ref arg i1 | set.cpp:171:9:171:10 | i1 | |
| set.cpp:171:9:171:10 | i1 | set.cpp:171:8:171:8 | call to operator* | TAINT |
| set.cpp:173:12:173:13 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:173:12:173:13 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:173:12:173:13 | s2 | set.cpp:173:15:173:19 | call to begin | TAINT |
| set.cpp:173:15:173:19 | call to begin | set.cpp:173:7:173:21 | ... = ... | |
| set.cpp:173:15:173:19 | call to begin | set.cpp:173:24:173:25 | i2 | |
| set.cpp:173:15:173:19 | call to begin | set.cpp:173:40:173:41 | i2 | |
| set.cpp:173:15:173:19 | call to begin | set.cpp:175:9:175:10 | i2 | |
| set.cpp:173:30:173:31 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:173:30:173:31 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:173:30:173:31 | s2 | set.cpp:173:33:173:35 | call to end | TAINT |
| set.cpp:173:40:173:41 | i2 | set.cpp:173:42:173:42 | call to operator++ | |
| set.cpp:173:40:173:41 | ref arg i2 | set.cpp:173:24:173:25 | i2 | |
| set.cpp:173:40:173:41 | ref arg i2 | set.cpp:173:40:173:41 | i2 | |
| set.cpp:173:40:173:41 | ref arg i2 | set.cpp:175:9:175:10 | i2 | |
| set.cpp:175:9:175:10 | i2 | set.cpp:175:8:175:8 | call to operator* | TAINT |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:180:2:180:4 | s11 | |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:181:2:181:4 | s11 | |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:182:2:182:4 | s11 | |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:183:7:183:9 | s11 | |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:184:7:184:9 | s11 | |
| set.cpp:179:29:179:31 | call to unordered_set | set.cpp:238:1:238:1 | s11 | |
| set.cpp:180:2:180:4 | ref arg s11 | set.cpp:181:2:181:4 | s11 | |
| set.cpp:180:2:180:4 | ref arg s11 | set.cpp:182:2:182:4 | s11 | |
| set.cpp:180:2:180:4 | ref arg s11 | set.cpp:183:7:183:9 | s11 | |
| set.cpp:180:2:180:4 | ref arg s11 | set.cpp:184:7:184:9 | s11 | |
| set.cpp:180:2:180:4 | ref arg s11 | set.cpp:238:1:238:1 | s11 | |
| set.cpp:180:13:180:15 | a | set.cpp:180:2:180:4 | ref arg s11 | TAINT |
| set.cpp:180:13:180:15 | a | set.cpp:180:6:180:11 | call to insert | TAINT |
| set.cpp:181:2:181:4 | ref arg s11 | set.cpp:182:2:182:4 | s11 | |
| set.cpp:181:2:181:4 | ref arg s11 | set.cpp:183:7:183:9 | s11 | |
| set.cpp:181:2:181:4 | ref arg s11 | set.cpp:184:7:184:9 | s11 | |
| set.cpp:181:2:181:4 | ref arg s11 | set.cpp:238:1:238:1 | s11 | |
| set.cpp:181:13:181:18 | call to source | set.cpp:181:2:181:4 | ref arg s11 | TAINT |
| set.cpp:181:13:181:18 | call to source | set.cpp:181:6:181:11 | call to insert | TAINT |
| set.cpp:182:2:182:4 | ref arg s11 | set.cpp:183:7:183:9 | s11 | |
| set.cpp:182:2:182:4 | ref arg s11 | set.cpp:184:7:184:9 | s11 | |
| set.cpp:182:2:182:4 | ref arg s11 | set.cpp:238:1:238:1 | s11 | |
| set.cpp:182:13:182:15 | c | set.cpp:182:2:182:4 | ref arg s11 | TAINT |
| set.cpp:182:13:182:15 | c | set.cpp:182:6:182:11 | call to insert | TAINT |
| set.cpp:183:7:183:9 | ref arg s11 | set.cpp:184:7:184:9 | s11 | |
| set.cpp:183:7:183:9 | ref arg s11 | set.cpp:238:1:238:1 | s11 | |
| set.cpp:183:28:183:32 | first | set.cpp:183:7:183:32 | call to iterator | |
| set.cpp:184:7:184:9 | ref arg s11 | set.cpp:238:1:238:1 | s11 | |
| set.cpp:184:28:184:33 | second | set.cpp:184:7:184:33 | call to iterator | |
| set.cpp:187:29:187:31 | call to unordered_set | set.cpp:188:2:188:4 | s12 | |
| set.cpp:187:29:187:31 | call to unordered_set | set.cpp:190:7:190:9 | s12 | |
| set.cpp:187:29:187:31 | call to unordered_set | set.cpp:194:2:194:4 | s12 | |
| set.cpp:187:29:187:31 | call to unordered_set | set.cpp:196:7:196:9 | s12 | |
| set.cpp:187:29:187:31 | call to unordered_set | set.cpp:238:1:238:1 | s12 | |
| set.cpp:187:34:187:36 | call to unordered_set | set.cpp:191:7:191:9 | s13 | |
| set.cpp:187:34:187:36 | call to unordered_set | set.cpp:194:11:194:13 | s13 | |
| set.cpp:187:34:187:36 | call to unordered_set | set.cpp:197:7:197:9 | s13 | |
| set.cpp:187:34:187:36 | call to unordered_set | set.cpp:238:1:238:1 | s13 | |
| set.cpp:187:39:187:41 | call to unordered_set | set.cpp:192:7:192:9 | s14 | |
| set.cpp:187:39:187:41 | call to unordered_set | set.cpp:195:2:195:4 | s14 | |
| set.cpp:187:39:187:41 | call to unordered_set | set.cpp:198:7:198:9 | s14 | |
| set.cpp:187:39:187:41 | call to unordered_set | set.cpp:238:1:238:1 | s14 | |
| set.cpp:187:44:187:46 | call to unordered_set | set.cpp:189:2:189:4 | s15 | |
| set.cpp:187:44:187:46 | call to unordered_set | set.cpp:193:7:193:9 | s15 | |
| set.cpp:187:44:187:46 | call to unordered_set | set.cpp:195:11:195:13 | s15 | |
| set.cpp:187:44:187:46 | call to unordered_set | set.cpp:199:7:199:9 | s15 | |
| set.cpp:187:44:187:46 | call to unordered_set | set.cpp:238:1:238:1 | s15 | |
| set.cpp:188:2:188:4 | ref arg s12 | set.cpp:190:7:190:9 | s12 | |
| set.cpp:188:2:188:4 | ref arg s12 | set.cpp:194:2:194:4 | s12 | |
| set.cpp:188:2:188:4 | ref arg s12 | set.cpp:196:7:196:9 | s12 | |
| set.cpp:188:2:188:4 | ref arg s12 | set.cpp:238:1:238:1 | s12 | |
| set.cpp:188:13:188:18 | call to source | set.cpp:188:2:188:4 | ref arg s12 | TAINT |
| set.cpp:188:13:188:18 | call to source | set.cpp:188:6:188:11 | call to insert | TAINT |
| set.cpp:189:2:189:4 | ref arg s15 | set.cpp:193:7:193:9 | s15 | |
| set.cpp:189:2:189:4 | ref arg s15 | set.cpp:195:11:195:13 | s15 | |
| set.cpp:189:2:189:4 | ref arg s15 | set.cpp:199:7:199:9 | s15 | |
| set.cpp:189:2:189:4 | ref arg s15 | set.cpp:238:1:238:1 | s15 | |
| set.cpp:189:13:189:18 | call to source | set.cpp:189:2:189:4 | ref arg s15 | TAINT |
| set.cpp:189:13:189:18 | call to source | set.cpp:189:6:189:11 | call to insert | TAINT |
| set.cpp:190:7:190:9 | s12 | set.cpp:190:7:190:9 | call to unordered_set | |
| set.cpp:191:7:191:9 | s13 | set.cpp:191:7:191:9 | call to unordered_set | |
| set.cpp:192:7:192:9 | s14 | set.cpp:192:7:192:9 | call to unordered_set | |
| set.cpp:193:7:193:9 | s15 | set.cpp:193:7:193:9 | call to unordered_set | |
| set.cpp:194:2:194:4 | ref arg s12 | set.cpp:196:7:196:9 | s12 | |
| set.cpp:194:2:194:4 | ref arg s12 | set.cpp:238:1:238:1 | s12 | |
| set.cpp:194:2:194:4 | s12 | set.cpp:194:11:194:13 | ref arg s13 | TAINT |
| set.cpp:194:11:194:13 | ref arg s13 | set.cpp:197:7:197:9 | s13 | |
| set.cpp:194:11:194:13 | ref arg s13 | set.cpp:238:1:238:1 | s13 | |
| set.cpp:194:11:194:13 | s13 | set.cpp:194:2:194:4 | ref arg s12 | TAINT |
| set.cpp:195:2:195:4 | ref arg s14 | set.cpp:198:7:198:9 | s14 | |
| set.cpp:195:2:195:4 | ref arg s14 | set.cpp:238:1:238:1 | s14 | |
| set.cpp:195:2:195:4 | s14 | set.cpp:195:11:195:13 | ref arg s15 | TAINT |
| set.cpp:195:11:195:13 | ref arg s15 | set.cpp:199:7:199:9 | s15 | |
| set.cpp:195:11:195:13 | ref arg s15 | set.cpp:238:1:238:1 | s15 | |
| set.cpp:195:11:195:13 | s15 | set.cpp:195:2:195:4 | ref arg s14 | TAINT |
| set.cpp:196:7:196:9 | s12 | set.cpp:196:7:196:9 | call to unordered_set | |
| set.cpp:197:7:197:9 | s13 | set.cpp:197:7:197:9 | call to unordered_set | |
| set.cpp:198:7:198:9 | s14 | set.cpp:198:7:198:9 | call to unordered_set | |
| set.cpp:199:7:199:9 | s15 | set.cpp:199:7:199:9 | call to unordered_set | |
| set.cpp:202:29:202:31 | call to unordered_set | set.cpp:203:2:203:4 | s16 | |
| set.cpp:202:29:202:31 | call to unordered_set | set.cpp:207:7:207:9 | s16 | |
| set.cpp:202:29:202:31 | call to unordered_set | set.cpp:211:2:211:4 | s16 | |
| set.cpp:202:29:202:31 | call to unordered_set | set.cpp:213:7:213:9 | s16 | |
| set.cpp:202:29:202:31 | call to unordered_set | set.cpp:238:1:238:1 | s16 | |
| set.cpp:202:34:202:36 | call to unordered_set | set.cpp:204:2:204:4 | s17 | |
| set.cpp:202:34:202:36 | call to unordered_set | set.cpp:208:7:208:9 | s17 | |
| set.cpp:202:34:202:36 | call to unordered_set | set.cpp:211:12:211:14 | s17 | |
| set.cpp:202:34:202:36 | call to unordered_set | set.cpp:214:7:214:9 | s17 | |
| set.cpp:202:34:202:36 | call to unordered_set | set.cpp:238:1:238:1 | s17 | |
| set.cpp:202:39:202:41 | call to unordered_set | set.cpp:205:2:205:4 | s18 | |
| set.cpp:202:39:202:41 | call to unordered_set | set.cpp:209:7:209:9 | s18 | |
| set.cpp:202:39:202:41 | call to unordered_set | set.cpp:212:2:212:4 | s18 | |
| set.cpp:202:39:202:41 | call to unordered_set | set.cpp:215:7:215:9 | s18 | |
| set.cpp:202:39:202:41 | call to unordered_set | set.cpp:238:1:238:1 | s18 | |
| set.cpp:202:44:202:46 | call to unordered_set | set.cpp:206:2:206:4 | s19 | |
| set.cpp:202:44:202:46 | call to unordered_set | set.cpp:210:7:210:9 | s19 | |
| set.cpp:202:44:202:46 | call to unordered_set | set.cpp:212:12:212:14 | s19 | |
| set.cpp:202:44:202:46 | call to unordered_set | set.cpp:216:7:216:9 | s19 | |
| set.cpp:202:44:202:46 | call to unordered_set | set.cpp:238:1:238:1 | s19 | |
| set.cpp:203:2:203:4 | ref arg s16 | set.cpp:207:7:207:9 | s16 | |
| set.cpp:203:2:203:4 | ref arg s16 | set.cpp:211:2:211:4 | s16 | |
| set.cpp:203:2:203:4 | ref arg s16 | set.cpp:213:7:213:9 | s16 | |
| set.cpp:203:2:203:4 | ref arg s16 | set.cpp:238:1:238:1 | s16 | |
| set.cpp:203:13:203:18 | call to source | set.cpp:203:2:203:4 | ref arg s16 | TAINT |
| set.cpp:203:13:203:18 | call to source | set.cpp:203:6:203:11 | call to insert | TAINT |
| set.cpp:204:2:204:4 | ref arg s17 | set.cpp:208:7:208:9 | s17 | |
| set.cpp:204:2:204:4 | ref arg s17 | set.cpp:211:12:211:14 | s17 | |
| set.cpp:204:2:204:4 | ref arg s17 | set.cpp:214:7:214:9 | s17 | |
| set.cpp:204:2:204:4 | ref arg s17 | set.cpp:238:1:238:1 | s17 | |
| set.cpp:204:13:204:17 | abc | set.cpp:204:2:204:4 | ref arg s17 | TAINT |
| set.cpp:204:13:204:17 | abc | set.cpp:204:6:204:11 | call to insert | TAINT |
| set.cpp:205:2:205:4 | ref arg s18 | set.cpp:209:7:209:9 | s18 | |
| set.cpp:205:2:205:4 | ref arg s18 | set.cpp:212:2:212:4 | s18 | |
| set.cpp:205:2:205:4 | ref arg s18 | set.cpp:215:7:215:9 | s18 | |
| set.cpp:205:2:205:4 | ref arg s18 | set.cpp:238:1:238:1 | s18 | |
| set.cpp:205:13:205:17 | def | set.cpp:205:2:205:4 | ref arg s18 | TAINT |
| set.cpp:205:13:205:17 | def | set.cpp:205:6:205:11 | call to insert | TAINT |
| set.cpp:206:2:206:4 | ref arg s19 | set.cpp:210:7:210:9 | s19 | |
| set.cpp:206:2:206:4 | ref arg s19 | set.cpp:212:12:212:14 | s19 | |
| set.cpp:206:2:206:4 | ref arg s19 | set.cpp:216:7:216:9 | s19 | |
| set.cpp:206:2:206:4 | ref arg s19 | set.cpp:238:1:238:1 | s19 | |
| set.cpp:206:13:206:18 | call to source | set.cpp:206:2:206:4 | ref arg s19 | TAINT |
| set.cpp:206:13:206:18 | call to source | set.cpp:206:6:206:11 | call to insert | TAINT |
| set.cpp:207:7:207:9 | s16 | set.cpp:207:7:207:9 | call to unordered_set | |
| set.cpp:208:7:208:9 | s17 | set.cpp:208:7:208:9 | call to unordered_set | |
| set.cpp:209:7:209:9 | s18 | set.cpp:209:7:209:9 | call to unordered_set | |
| set.cpp:210:7:210:9 | s19 | set.cpp:210:7:210:9 | call to unordered_set | |
| set.cpp:211:2:211:4 | ref arg s16 | set.cpp:213:7:213:9 | s16 | |
| set.cpp:211:2:211:4 | ref arg s16 | set.cpp:238:1:238:1 | s16 | |
| set.cpp:211:12:211:14 | ref arg s17 | set.cpp:214:7:214:9 | s17 | |
| set.cpp:211:12:211:14 | ref arg s17 | set.cpp:238:1:238:1 | s17 | |
| set.cpp:212:2:212:4 | ref arg s18 | set.cpp:215:7:215:9 | s18 | |
| set.cpp:212:2:212:4 | ref arg s18 | set.cpp:238:1:238:1 | s18 | |
| set.cpp:212:12:212:14 | ref arg s19 | set.cpp:216:7:216:9 | s19 | |
| set.cpp:212:12:212:14 | ref arg s19 | set.cpp:238:1:238:1 | s19 | |
| set.cpp:213:7:213:9 | s16 | set.cpp:213:7:213:9 | call to unordered_set | |
| set.cpp:214:7:214:9 | s17 | set.cpp:214:7:214:9 | call to unordered_set | |
| set.cpp:215:7:215:9 | s18 | set.cpp:215:7:215:9 | call to unordered_set | |
| set.cpp:216:7:216:9 | s19 | set.cpp:216:7:216:9 | call to unordered_set | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:220:2:220:4 | s20 | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:221:2:221:4 | s20 | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:222:7:222:9 | s20 | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:223:7:223:9 | s20 | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:223:17:223:19 | s20 | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:224:7:224:9 | s20 | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:225:2:225:4 | s20 | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:226:7:226:9 | s20 | |
| set.cpp:219:29:219:31 | call to unordered_set | set.cpp:238:1:238:1 | s20 | |
| set.cpp:220:2:220:4 | ref arg s20 | set.cpp:221:2:221:4 | s20 | |
| set.cpp:220:2:220:4 | ref arg s20 | set.cpp:222:7:222:9 | s20 | |
| set.cpp:220:2:220:4 | ref arg s20 | set.cpp:223:7:223:9 | s20 | |
| set.cpp:220:2:220:4 | ref arg s20 | set.cpp:223:17:223:19 | s20 | |
| set.cpp:220:2:220:4 | ref arg s20 | set.cpp:224:7:224:9 | s20 | |
| set.cpp:220:2:220:4 | ref arg s20 | set.cpp:225:2:225:4 | s20 | |
| set.cpp:220:2:220:4 | ref arg s20 | set.cpp:226:7:226:9 | s20 | |
| set.cpp:220:2:220:4 | ref arg s20 | set.cpp:238:1:238:1 | s20 | |
| set.cpp:220:13:220:18 | call to source | set.cpp:220:2:220:4 | ref arg s20 | TAINT |
| set.cpp:220:13:220:18 | call to source | set.cpp:220:6:220:11 | call to insert | TAINT |
| set.cpp:221:2:221:4 | ref arg s20 | set.cpp:222:7:222:9 | s20 | |
| set.cpp:221:2:221:4 | ref arg s20 | set.cpp:223:7:223:9 | s20 | |
| set.cpp:221:2:221:4 | ref arg s20 | set.cpp:223:17:223:19 | s20 | |
| set.cpp:221:2:221:4 | ref arg s20 | set.cpp:224:7:224:9 | s20 | |
| set.cpp:221:2:221:4 | ref arg s20 | set.cpp:225:2:225:4 | s20 | |
| set.cpp:221:2:221:4 | ref arg s20 | set.cpp:226:7:226:9 | s20 | |
| set.cpp:221:2:221:4 | ref arg s20 | set.cpp:238:1:238:1 | s20 | |
| set.cpp:221:13:221:18 | call to source | set.cpp:221:2:221:4 | ref arg s20 | TAINT |
| set.cpp:221:13:221:18 | call to source | set.cpp:221:6:221:11 | call to insert | TAINT |
| set.cpp:222:7:222:9 | s20 | set.cpp:222:7:222:9 | call to unordered_set | |
| set.cpp:223:7:223:9 | ref arg s20 | set.cpp:224:7:224:9 | s20 | |
| set.cpp:223:7:223:9 | ref arg s20 | set.cpp:225:2:225:4 | s20 | |
| set.cpp:223:7:223:9 | ref arg s20 | set.cpp:226:7:226:9 | s20 | |
| set.cpp:223:7:223:9 | ref arg s20 | set.cpp:238:1:238:1 | s20 | |
| set.cpp:223:7:223:9 | s20 | set.cpp:223:11:223:15 | call to erase | TAINT |
| set.cpp:223:17:223:19 | ref arg s20 | set.cpp:223:7:223:9 | s20 | |
| set.cpp:223:17:223:19 | ref arg s20 | set.cpp:224:7:224:9 | s20 | |
| set.cpp:223:17:223:19 | ref arg s20 | set.cpp:225:2:225:4 | s20 | |
| set.cpp:223:17:223:19 | ref arg s20 | set.cpp:226:7:226:9 | s20 | |
| set.cpp:223:17:223:19 | ref arg s20 | set.cpp:238:1:238:1 | s20 | |
| set.cpp:223:17:223:19 | s20 | set.cpp:223:21:223:25 | call to begin | TAINT |
| set.cpp:224:7:224:9 | s20 | set.cpp:224:7:224:9 | call to unordered_set | |
| set.cpp:225:2:225:4 | ref arg s20 | set.cpp:226:7:226:9 | s20 | |
| set.cpp:225:2:225:4 | ref arg s20 | set.cpp:238:1:238:1 | s20 | |
| set.cpp:226:7:226:9 | s20 | set.cpp:226:7:226:9 | call to unordered_set | |
| set.cpp:229:29:229:31 | call to unordered_set | set.cpp:230:7:230:9 | s21 | |
| set.cpp:229:29:229:31 | call to unordered_set | set.cpp:231:7:231:9 | s21 | |
| set.cpp:229:29:229:31 | call to unordered_set | set.cpp:232:7:232:9 | s21 | |
| set.cpp:229:29:229:31 | call to unordered_set | set.cpp:233:7:233:9 | s21 | |
| set.cpp:229:29:229:31 | call to unordered_set | set.cpp:238:1:238:1 | s21 | |
| set.cpp:229:34:229:36 | call to unordered_set | set.cpp:234:7:234:9 | s22 | |
| set.cpp:229:34:229:36 | call to unordered_set | set.cpp:234:24:234:26 | s22 | |
| set.cpp:229:34:229:36 | call to unordered_set | set.cpp:235:7:235:9 | s22 | |
| set.cpp:229:34:229:36 | call to unordered_set | set.cpp:236:7:236:9 | s22 | |
| set.cpp:229:34:229:36 | call to unordered_set | set.cpp:236:24:236:26 | s22 | |
| set.cpp:229:34:229:36 | call to unordered_set | set.cpp:237:7:237:9 | s22 | |
| set.cpp:229:34:229:36 | call to unordered_set | set.cpp:238:1:238:1 | s22 | |
| set.cpp:230:7:230:9 | ref arg s21 | set.cpp:231:7:231:9 | s21 | |
| set.cpp:230:7:230:9 | ref arg s21 | set.cpp:232:7:232:9 | s21 | |
| set.cpp:230:7:230:9 | ref arg s21 | set.cpp:233:7:233:9 | s21 | |
| set.cpp:230:7:230:9 | ref arg s21 | set.cpp:238:1:238:1 | s21 | |
| set.cpp:230:26:230:30 | first | set.cpp:230:7:230:30 | call to iterator | |
| set.cpp:231:7:231:9 | s21 | set.cpp:231:7:231:9 | call to unordered_set | |
| set.cpp:232:7:232:9 | ref arg s21 | set.cpp:233:7:233:9 | s21 | |
| set.cpp:232:7:232:9 | ref arg s21 | set.cpp:238:1:238:1 | s21 | |
| set.cpp:232:29:232:33 | first | set.cpp:232:7:232:33 | call to iterator | |
| set.cpp:233:7:233:9 | s21 | set.cpp:233:7:233:9 | call to unordered_set | |
| set.cpp:234:7:234:9 | ref arg s22 | set.cpp:235:7:235:9 | s22 | |
| set.cpp:234:7:234:9 | ref arg s22 | set.cpp:236:7:236:9 | s22 | |
| set.cpp:234:7:234:9 | ref arg s22 | set.cpp:236:24:236:26 | s22 | |
| set.cpp:234:7:234:9 | ref arg s22 | set.cpp:237:7:237:9 | s22 | |
| set.cpp:234:7:234:9 | ref arg s22 | set.cpp:238:1:238:1 | s22 | |
| set.cpp:234:24:234:26 | ref arg s22 | set.cpp:234:7:234:9 | s22 | |
| set.cpp:234:24:234:26 | ref arg s22 | set.cpp:235:7:235:9 | s22 | |
| set.cpp:234:24:234:26 | ref arg s22 | set.cpp:236:7:236:9 | s22 | |
| set.cpp:234:24:234:26 | ref arg s22 | set.cpp:236:24:236:26 | s22 | |
| set.cpp:234:24:234:26 | ref arg s22 | set.cpp:237:7:237:9 | s22 | |
| set.cpp:234:24:234:26 | ref arg s22 | set.cpp:238:1:238:1 | s22 | |
| set.cpp:234:24:234:26 | s22 | set.cpp:234:28:234:32 | call to begin | TAINT |
| set.cpp:234:28:234:32 | call to begin | set.cpp:234:24:234:34 | call to iterator | TAINT |
| set.cpp:235:7:235:9 | s22 | set.cpp:235:7:235:9 | call to unordered_set | |
| set.cpp:236:7:236:9 | ref arg s22 | set.cpp:237:7:237:9 | s22 | |
| set.cpp:236:7:236:9 | ref arg s22 | set.cpp:238:1:238:1 | s22 | |
| set.cpp:236:24:236:26 | ref arg s22 | set.cpp:236:7:236:9 | s22 | |
| set.cpp:236:24:236:26 | ref arg s22 | set.cpp:237:7:237:9 | s22 | |
| set.cpp:236:24:236:26 | ref arg s22 | set.cpp:238:1:238:1 | s22 | |
| set.cpp:236:24:236:26 | s22 | set.cpp:236:28:236:32 | call to begin | TAINT |
| set.cpp:236:28:236:32 | call to begin | set.cpp:236:24:236:34 | call to iterator | TAINT |
| set.cpp:237:7:237:9 | s22 | set.cpp:237:7:237:9 | call to unordered_set | |
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:12:11:12:11 | p | |
| smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:13:10:13:10 | p | |
| smart_pointer.cpp:11:52:11:57 | call to source | smart_pointer.cpp:11:30:11:50 | call to make_shared | TAINT |

View File

@@ -0,0 +1,238 @@
#include "stl.h"
using namespace std;
char *source();
void sink(char *);
void sink(std::set<char *>);
void sink(std::set<char *>::iterator);
void sink(std::unordered_set<char *>);
void sink(std::unordered_set<char *>::iterator);
void test_set()
{
// insert, find
std::set<char *> s1, s2, s3, s4, s5, s6;
sink(s1.insert("abc").first);
sink(s2.insert(source()).first); // tainted
sink(s3.insert(s3.begin(), "abc"));
sink(s4.insert(s4.begin(), source())); // tainted
s5.insert(s1.begin(), s1.end());
s6.insert(s2.begin(), s2.end());
sink(s1);
sink(s2); // tainted
sink(s3);
sink(s4); // tainted
sink(s5);
sink(s6); // tainted
sink(s1.find("abc"));
sink(s2.find("abc")); // tainted
sink(s3.find("abc"));
sink(s4.find("abc")); // tainted
sink(s5.find("abc"));
sink(s6.find("abc")); // tainted
// copy constructors and assignment
std::set<char *> s7(s2);
std::set<char *> s8 = s2;
std::set<char *> s9(s2.begin(), s2.end());
std::set<char *> s10;
s10 = s2;
sink(s7); // tainted
sink(s8); // tainted
sink(s9); // tainted
sink(s10); // tainted
sink(s7.find("abc")); // tainted
sink(s8.find("abc")); // tainted
sink(s9.find("abc")); // tainted
sink(s10.find("abc")); // tainted
// iterators
std::set<char *>::iterator i1, i2;
for (i1 = s1.begin(); i1 != s1.end(); i1++)
{
sink(*i1);
}
for (i2 = s2.begin(); i2 != s2.end(); i2++)
{
sink(*i2); // tainted
}
// ranges
std::set<char *> s11;
s11.insert("a");
s11.insert(source());
s11.insert("c");
sink(s11.lower_bound("b")); // tainted [NOT DETECTED]
sink(s11.upper_bound("b")); // tainted [NOT DETECTED]
sink(s11.equal_range("b").first); // tainted [NOT DETECTED]
sink(s11.equal_range("b").second); // tainted [NOT DETECTED]
// swap
std::set<char *> s12, s13, s14, s15;
s12.insert(source());
s15.insert(source());
sink(s12); // tainted
sink(s13);
sink(s14);
sink(s15); // tainted
s12.swap(s13);
s14.swap(s15);
sink(s12); // [FALSE POSITIVE]
sink(s13); // tainted
sink(s14); // tainted
sink(s15); // [FALSE POSITIVE]
// merge
std::set<char *> s16, s17, s18, s19;
s16.insert(source());
s17.insert("abc");
s18.insert("def");
s19.insert(source());
sink(s16); // tainted
sink(s17);
sink(s18);
sink(s19); // tainted
s16.merge(s17);
s18.merge(s19);
sink(s16); // tainted
sink(s17); // tainted [NOT DETECTED]
sink(s18); // tainted [NOT DETECTED]
sink(s19); // tainted
// erase, clear
std::set<char *> s20;
s20.insert(source());
s20.insert(source());
sink(s20); // tainted
sink(s20.erase(s20.begin())); // tainted
sink(s20); // tainted
s20.clear();
sink(s20); // [FALSE POSITIVE]
// emplace, emplace_hint
std::set<char *> s21, s22;
sink(s21.emplace("abc").first);
sink(s21);
sink(s21.emplace(source()).first); // tainted [NOT DETECTED]
sink(s21); // tainted [NOT DETECTED]
sink(s22.emplace_hint(s22.begin(), "abc"));
sink(s22);
sink(s22.emplace_hint(s22.begin(), source())); // tainted [NOT DETECTED]
sink(s22); // tainted [NOT DETECTED]
}
void test_unordered_set()
{
// insert, find
std::unordered_set<char *> s1, s2, s3, s4, s5, s6;
sink(s1.insert("abc").first);
sink(s2.insert(source()).first); // tainted
sink(s3.insert(s3.begin(), "abc"));
sink(s4.insert(s4.begin(), source())); // tainted
s5.insert(s1.begin(), s1.end());
s6.insert(s2.begin(), s2.end());
sink(s1);
sink(s2); // tainted
sink(s3);
sink(s4); // tainted
sink(s5);
sink(s6); // tainted
sink(s1.find("abc"));
sink(s2.find("abc")); // tainted
sink(s3.find("abc"));
sink(s4.find("abc")); // tainted
sink(s5.find("abc"));
sink(s6.find("abc")); // tainted
// copy constructors and assignment
std::unordered_set<char *> s7(s2);
std::unordered_set<char *> s8 = s2;
std::unordered_set<char *> s9(s2.begin(), s2.end());
std::unordered_set<char *> s10;
s10 = s2;
sink(s7); // tainted
sink(s8); // tainted
sink(s9); // tainted
sink(s10); // tainted
sink(s7.find("abc")); // tainted
sink(s8.find("abc")); // tainted
sink(s9.find("abc")); // tainted
sink(s10.find("abc")); // tainted
// iterators
std::unordered_set<char *>::iterator i1, i2;
for (i1 = s1.begin(); i1 != s1.end(); i1++)
{
sink(*i1);
}
for (i2 = s2.begin(); i2 != s2.end(); i2++)
{
sink(*i2); // tainted
}
// ranges
std::unordered_set<char *> s11;
s11.insert("a");
s11.insert(source());
s11.insert("c");
sink(s11.equal_range("b").first); // tainted [NOT DETECTED]
sink(s11.equal_range("b").second); // tainted [NOT DETECTED]
// swap
std::unordered_set<char *> s12, s13, s14, s15;
s12.insert(source());
s15.insert(source());
sink(s12); // tainted
sink(s13);
sink(s14);
sink(s15); // tainted
s12.swap(s13);
s14.swap(s15);
sink(s12); // [FALSE POSITIVE]
sink(s13); // tainted
sink(s14); // tainted
sink(s15); // [FALSE POSITIVE]
// merge
std::unordered_set<char *> s16, s17, s18, s19;
s16.insert(source());
s17.insert("abc");
s18.insert("def");
s19.insert(source());
sink(s16); // tainted
sink(s17);
sink(s18);
sink(s19); // tainted
s16.merge(s17);
s18.merge(s19);
sink(s16); // tainted
sink(s17); // tainted [NOT DETECTED]
sink(s18); // tainted [NOT DETECTED]
sink(s19); // tainted
// erase, clear
std::unordered_set<char *> s20;
s20.insert(source());
s20.insert(source());
sink(s20); // tainted
sink(s20.erase(s20.begin())); // tainted
sink(s20); // tainted
s20.clear();
sink(s20); // [FALSE POSITIVE]
// emplace, emplace_hint
std::unordered_set<char *> s21, s22;
sink(s21.emplace("abc").first);
sink(s21);
sink(s21.emplace(source()).first); // tainted [NOT DETECTED]
sink(s21); // tainted [NOT DETECTED]
sink(s22.emplace_hint(s22.begin(), "abc"));
sink(s22);
sink(s22.emplace_hint(s22.begin(), source())); // tainted [NOT DETECTED]
sink(s22); // tainted [NOT DETECTED]
}

View File

@@ -482,3 +482,108 @@ namespace std {
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
};
};
// --- set ---
namespace std {
template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
class set {
public:
using key_type = Key;
using value_type = Key;
using size_type = size_t;
using allocator_type = Allocator;
using iterator = std::iterator<random_access_iterator_tag, value_type >;
using const_iterator = std::iterator<random_access_iterator_tag, const value_type >;
set() /*: set(Compare())*/ { }
set(const set& x);
set(set&& x);
template<class InputIterator> set(InputIterator first, InputIterator last/*, const Compare& comp = Compare(), const Allocator& = Allocator()*/);
~set();
set& operator=(const set& x);
set& operator=(set&& x) noexcept/*(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>)*/;
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
template<class... Args> pair<iterator, bool> emplace(Args&&... args);
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
pair<iterator,bool> insert(const value_type& x);
pair<iterator,bool> insert(value_type&& x);
iterator insert(const_iterator position, const value_type& x);
iterator insert(const_iterator position, value_type&& x);
template<class InputIterator> void insert(InputIterator first, InputIterator last);
iterator erase(iterator position);
iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);
void swap(set&) noexcept/*(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>)*/;
void clear() noexcept;
template<class C2> void merge(set<Key, C2, Allocator>& source);
template<class C2> void merge(set<Key, C2, Allocator>&& source);
iterator find(const key_type& x);
const_iterator find(const key_type& x) const;
iterator lower_bound(const key_type& x);
const_iterator lower_bound(const key_type& x) const;
iterator upper_bound(const key_type& x);
const_iterator upper_bound(const key_type& x) const;
pair<iterator, iterator> equal_range(const key_type& x);
pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
};
template<class Key, class Hash = hash<Key>, class Pred = equal_to<Key>, class Allocator = allocator<Key>>
class unordered_set {
public:
using key_type = Key;
using value_type = Key;
using hasher = Hash;
using key_equal = Pred;
using allocator_type = Allocator;
using size_type = size_t;
using iterator = std::iterator<random_access_iterator_tag, value_type >;
using const_iterator = std::iterator<random_access_iterator_tag, const value_type >;
unordered_set();
unordered_set(const unordered_set&);
unordered_set(unordered_set&&);
template<class InputIterator> unordered_set(InputIterator f, InputIterator l, size_type n = 0/*, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()*/);
~unordered_set();
unordered_set& operator=(const unordered_set&);
unordered_set& operator=(unordered_set&&) noexcept/*(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>)*/;
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
template<class... Args> pair<iterator, bool> emplace(Args&&... args);
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
pair<iterator, bool> insert(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj);
iterator insert(const_iterator hint, const value_type& obj);
iterator insert(const_iterator hint, value_type&& obj);
template<class InputIterator> void insert(InputIterator first, InputIterator last);
iterator erase(iterator position);
iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);
void swap(unordered_set&) noexcept/*(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>)*/;
void clear() noexcept;
template<class H2, class P2> void merge(unordered_set<Key, H2, P2, Allocator>& source);
template<class H2, class P2> void merge(unordered_set<Key, H2, P2, Allocator>&& source);
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
pair<iterator, iterator> equal_range(const key_type& k);
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
};
}

View File

@@ -142,6 +142,74 @@
| movableclass.cpp:55:8:55:9 | s2 | movableclass.cpp:52:23:52:28 | call to source |
| movableclass.cpp:64:8:64:9 | s2 | movableclass.cpp:23:55:23:60 | call to source |
| movableclass.cpp:65:11:65:11 | call to operator= | movableclass.cpp:65:13:65:18 | call to source |
| set.cpp:22:10:22:15 | call to insert | set.cpp:22:29:22:34 | call to source |
| set.cpp:26:7:26:8 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:28:7:28:8 | call to set | set.cpp:22:29:22:34 | call to source |
| set.cpp:30:7:30:8 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:32:10:32:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:34:10:34:13 | call to find | set.cpp:22:29:22:34 | call to source |
| set.cpp:36:10:36:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:44:7:44:8 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:45:7:45:8 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:46:7:46:8 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:47:7:47:9 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:48:10:48:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:49:10:49:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:50:10:50:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:51:11:51:14 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:61:8:61:8 | call to operator* | set.cpp:20:17:20:22 | call to source |
| set.cpp:78:7:78:9 | call to set | set.cpp:76:13:76:18 | call to source |
| set.cpp:81:7:81:9 | call to set | set.cpp:77:13:77:18 | call to source |
| set.cpp:84:7:84:9 | call to set | set.cpp:76:13:76:18 | call to source |
| set.cpp:85:7:85:9 | call to set | set.cpp:76:13:76:18 | call to source |
| set.cpp:86:7:86:9 | call to set | set.cpp:77:13:77:18 | call to source |
| set.cpp:87:7:87:9 | call to set | set.cpp:77:13:77:18 | call to source |
| set.cpp:95:7:95:9 | call to set | set.cpp:91:13:91:18 | call to source |
| set.cpp:98:7:98:9 | call to set | set.cpp:94:13:94:18 | call to source |
| set.cpp:101:7:101:9 | call to set | set.cpp:91:13:91:18 | call to source |
| set.cpp:104:7:104:9 | call to set | set.cpp:94:13:94:18 | call to source |
| set.cpp:110:7:110:9 | call to set | set.cpp:108:13:108:18 | call to source |
| set.cpp:110:7:110:9 | call to set | set.cpp:109:13:109:18 | call to source |
| set.cpp:111:11:111:15 | call to erase | set.cpp:108:13:108:18 | call to source |
| set.cpp:111:11:111:15 | call to erase | set.cpp:109:13:109:18 | call to source |
| set.cpp:112:7:112:9 | call to set | set.cpp:108:13:108:18 | call to source |
| set.cpp:112:7:112:9 | call to set | set.cpp:109:13:109:18 | call to source |
| set.cpp:114:7:114:9 | call to set | set.cpp:108:13:108:18 | call to source |
| set.cpp:114:7:114:9 | call to set | set.cpp:109:13:109:18 | call to source |
| set.cpp:136:10:136:15 | call to insert | set.cpp:136:29:136:34 | call to source |
| set.cpp:140:7:140:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:142:7:142:8 | call to unordered_set | set.cpp:136:29:136:34 | call to source |
| set.cpp:144:7:144:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:146:10:146:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:148:10:148:13 | call to find | set.cpp:136:29:136:34 | call to source |
| set.cpp:150:10:150:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:158:7:158:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:159:7:159:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:160:7:160:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:161:7:161:9 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:162:10:162:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:163:10:163:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:164:10:164:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:165:11:165:14 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:175:8:175:8 | call to operator* | set.cpp:134:17:134:22 | call to source |
| set.cpp:190:7:190:9 | call to unordered_set | set.cpp:188:13:188:18 | call to source |
| set.cpp:193:7:193:9 | call to unordered_set | set.cpp:189:13:189:18 | call to source |
| set.cpp:196:7:196:9 | call to unordered_set | set.cpp:188:13:188:18 | call to source |
| set.cpp:197:7:197:9 | call to unordered_set | set.cpp:188:13:188:18 | call to source |
| set.cpp:198:7:198:9 | call to unordered_set | set.cpp:189:13:189:18 | call to source |
| set.cpp:199:7:199:9 | call to unordered_set | set.cpp:189:13:189:18 | call to source |
| set.cpp:207:7:207:9 | call to unordered_set | set.cpp:203:13:203:18 | call to source |
| set.cpp:210:7:210:9 | call to unordered_set | set.cpp:206:13:206:18 | call to source |
| set.cpp:213:7:213:9 | call to unordered_set | set.cpp:203:13:203:18 | call to source |
| set.cpp:216:7:216:9 | call to unordered_set | set.cpp:206:13:206:18 | call to source |
| set.cpp:222:7:222:9 | call to unordered_set | set.cpp:220:13:220:18 | call to source |
| set.cpp:222:7:222:9 | call to unordered_set | set.cpp:221:13:221:18 | call to source |
| set.cpp:223:11:223:15 | call to erase | set.cpp:220:13:220:18 | call to source |
| set.cpp:223:11:223:15 | call to erase | set.cpp:221:13:221:18 | call to source |
| set.cpp:224:7:224:9 | call to unordered_set | set.cpp:220:13:220:18 | call to source |
| set.cpp:224:7:224:9 | call to unordered_set | set.cpp:221:13:221:18 | call to source |
| set.cpp:226:7:226:9 | call to unordered_set | set.cpp:220:13:220:18 | call to source |
| set.cpp:226:7:226:9 | call to unordered_set | set.cpp:221:13:221:18 | call to source |
| smart_pointer.cpp:12:10:12:10 | call to operator* | smart_pointer.cpp:11:52:11:57 | call to source |
| smart_pointer.cpp:13:10:13:10 | p | smart_pointer.cpp:11:52:11:57 | call to source |
| smart_pointer.cpp:24:10:24:10 | call to operator* | smart_pointer.cpp:23:52:23:57 | call to source |

View File

@@ -104,6 +104,60 @@
| map.cpp:375:7:375:9 | map.cpp:370:49:370:54 | AST only |
| movableclass.cpp:65:11:65:11 | movableclass.cpp:65:13:65:18 | AST only |
| movableclass.cpp:65:11:65:21 | movableclass.cpp:65:13:65:18 | IR only |
| set.cpp:20:7:20:31 | set.cpp:20:17:20:22 | IR only |
| set.cpp:26:7:26:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:28:7:28:8 | set.cpp:22:29:22:34 | AST only |
| set.cpp:30:7:30:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:44:7:44:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:45:7:45:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:46:7:46:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:47:7:47:9 | set.cpp:20:17:20:22 | AST only |
| set.cpp:48:10:48:13 | set.cpp:20:17:20:22 | AST only |
| set.cpp:49:10:49:13 | set.cpp:20:17:20:22 | AST only |
| set.cpp:61:8:61:11 | set.cpp:20:17:20:22 | IR only |
| set.cpp:78:7:78:9 | set.cpp:76:13:76:18 | AST only |
| set.cpp:81:7:81:9 | set.cpp:77:13:77:18 | AST only |
| set.cpp:84:7:84:9 | set.cpp:76:13:76:18 | AST only |
| set.cpp:85:7:85:9 | set.cpp:76:13:76:18 | AST only |
| set.cpp:86:7:86:9 | set.cpp:77:13:77:18 | AST only |
| set.cpp:87:7:87:9 | set.cpp:77:13:77:18 | AST only |
| set.cpp:95:7:95:9 | set.cpp:91:13:91:18 | AST only |
| set.cpp:98:7:98:9 | set.cpp:94:13:94:18 | AST only |
| set.cpp:101:7:101:9 | set.cpp:91:13:91:18 | AST only |
| set.cpp:104:7:104:9 | set.cpp:94:13:94:18 | AST only |
| set.cpp:110:7:110:9 | set.cpp:108:13:108:18 | AST only |
| set.cpp:110:7:110:9 | set.cpp:109:13:109:18 | AST only |
| set.cpp:112:7:112:9 | set.cpp:108:13:108:18 | AST only |
| set.cpp:112:7:112:9 | set.cpp:109:13:109:18 | AST only |
| set.cpp:114:7:114:9 | set.cpp:108:13:108:18 | AST only |
| set.cpp:114:7:114:9 | set.cpp:109:13:109:18 | AST only |
| set.cpp:134:7:134:31 | set.cpp:134:17:134:22 | IR only |
| set.cpp:140:7:140:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:142:7:142:8 | set.cpp:136:29:136:34 | AST only |
| set.cpp:144:7:144:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:158:7:158:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:159:7:159:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:160:7:160:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:161:7:161:9 | set.cpp:134:17:134:22 | AST only |
| set.cpp:162:10:162:13 | set.cpp:134:17:134:22 | AST only |
| set.cpp:163:10:163:13 | set.cpp:134:17:134:22 | AST only |
| set.cpp:175:8:175:11 | set.cpp:134:17:134:22 | IR only |
| set.cpp:190:7:190:9 | set.cpp:188:13:188:18 | AST only |
| set.cpp:193:7:193:9 | set.cpp:189:13:189:18 | AST only |
| set.cpp:196:7:196:9 | set.cpp:188:13:188:18 | AST only |
| set.cpp:197:7:197:9 | set.cpp:188:13:188:18 | AST only |
| set.cpp:198:7:198:9 | set.cpp:189:13:189:18 | AST only |
| set.cpp:199:7:199:9 | set.cpp:189:13:189:18 | AST only |
| set.cpp:207:7:207:9 | set.cpp:203:13:203:18 | AST only |
| set.cpp:210:7:210:9 | set.cpp:206:13:206:18 | AST only |
| set.cpp:213:7:213:9 | set.cpp:203:13:203:18 | AST only |
| set.cpp:216:7:216:9 | set.cpp:206:13:206:18 | AST only |
| set.cpp:222:7:222:9 | set.cpp:220:13:220:18 | AST only |
| set.cpp:222:7:222:9 | set.cpp:221:13:221:18 | AST only |
| set.cpp:224:7:224:9 | set.cpp:220:13:220:18 | AST only |
| set.cpp:224:7:224:9 | set.cpp:221:13:221:18 | AST only |
| set.cpp:226:7:226:9 | set.cpp:220:13:220:18 | AST only |
| set.cpp:226:7:226:9 | set.cpp:221:13:221:18 | AST only |
| smart_pointer.cpp:12:10:12:10 | smart_pointer.cpp:11:52:11:57 | AST only |
| smart_pointer.cpp:24:10:24:10 | smart_pointer.cpp:23:52:23:57 | AST only |
| standalone_iterators.cpp:41:10:41:10 | standalone_iterators.cpp:39:45:39:51 | AST only |

View File

@@ -112,6 +112,28 @@
| movableclass.cpp:55:8:55:9 | s2 | movableclass.cpp:52:23:52:28 | call to source |
| movableclass.cpp:64:8:64:9 | s2 | movableclass.cpp:23:55:23:60 | call to source |
| movableclass.cpp:65:11:65:21 | (reference dereference) | movableclass.cpp:65:13:65:18 | call to source |
| set.cpp:20:7:20:31 | call to iterator | set.cpp:20:17:20:22 | call to source |
| set.cpp:22:10:22:15 | call to insert | set.cpp:22:29:22:34 | call to source |
| set.cpp:32:10:32:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:34:10:34:13 | call to find | set.cpp:22:29:22:34 | call to source |
| set.cpp:36:10:36:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:50:10:50:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:51:11:51:14 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:61:8:61:8 | call to operator* | set.cpp:20:17:20:22 | call to source |
| set.cpp:61:8:61:11 | (reference dereference) | set.cpp:20:17:20:22 | call to source |
| set.cpp:111:11:111:15 | call to erase | set.cpp:108:13:108:18 | call to source |
| set.cpp:111:11:111:15 | call to erase | set.cpp:109:13:109:18 | call to source |
| set.cpp:134:7:134:31 | call to iterator | set.cpp:134:17:134:22 | call to source |
| set.cpp:136:10:136:15 | call to insert | set.cpp:136:29:136:34 | call to source |
| set.cpp:146:10:146:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:148:10:148:13 | call to find | set.cpp:136:29:136:34 | call to source |
| set.cpp:150:10:150:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:164:10:164:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:165:11:165:14 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:175:8:175:8 | call to operator* | set.cpp:134:17:134:22 | call to source |
| set.cpp:175:8:175:11 | (reference dereference) | set.cpp:134:17:134:22 | call to source |
| set.cpp:223:11:223:15 | call to erase | set.cpp:220:13:220:18 | call to source |
| set.cpp:223:11:223:15 | call to erase | set.cpp:221:13:221:18 | call to source |
| smart_pointer.cpp:13:10:13:10 | Argument 0 indirection | smart_pointer.cpp:11:52:11:57 | call to source |
| smart_pointer.cpp:25:10:25:10 | Argument 0 indirection | smart_pointer.cpp:23:52:23:57 | call to source |
| smart_pointer.cpp:52:12:52:14 | call to get | smart_pointer.cpp:51:52:51:57 | call to source |

View File

@@ -582,10 +582,16 @@
| test.c:635:9:635:10 | ss | -32768 |
| test.c:638:7:638:8 | ss | -32768 |
| test.c:639:9:639:10 | ss | -1 |
| test.c:645:7:645:7 | i | 0 |
| test.c:646:9:646:9 | i | -2147483648 |
| test.c:650:7:650:7 | u | 0 |
| test.c:651:9:651:9 | u | 0 |
| test.c:645:8:645:8 | s | -2147483648 |
| test.c:645:15:645:15 | s | 0 |
| test.c:645:23:645:23 | s | 0 |
| test.c:646:18:646:18 | s | 0 |
| test.c:646:22:646:22 | s | 0 |
| test.c:647:9:647:14 | result | 0 |
| test.c:653:7:653:7 | i | 0 |
| test.c:654:9:654:9 | i | -2147483648 |
| test.c:658:7:658:7 | u | 0 |
| test.c:659:9:659:9 | u | 0 |
| test.cpp:10:7:10:7 | b | -2147483648 |
| test.cpp:11:5:11:5 | x | -2147483648 |
| test.cpp:13:10:13:10 | x | -2147483648 |

View File

@@ -640,6 +640,14 @@ void two_bounds_from_one_test(short ss, unsigned short us) {
}
}
void widen_recursive_expr() {
int s;
for (s = 0; s < 10; s++) {
int result = s + s; // 0 .. 9 [BUG: upper bound is 15 due to widening]
out(result); // 0 .. 18 [BUG: upper bound is 127 due to double widening]
}
}
void guard_bound_out_of_range(void) {
int i = 0;
if (i < 0) {

View File

@@ -582,10 +582,16 @@
| test.c:635:9:635:10 | ss | 32767 |
| test.c:638:7:638:8 | ss | 32767 |
| test.c:639:9:639:10 | ss | 2 |
| test.c:645:7:645:7 | i | 0 |
| test.c:646:9:646:9 | i | 2147483647 |
| test.c:650:7:650:7 | u | 0 |
| test.c:651:9:651:9 | u | 4294967295 |
| test.c:645:8:645:8 | s | 2147483647 |
| test.c:645:15:645:15 | s | 127 |
| test.c:645:23:645:23 | s | 15 |
| test.c:646:18:646:18 | s | 15 |
| test.c:646:22:646:22 | s | 15 |
| test.c:647:9:647:14 | result | 127 |
| test.c:653:7:653:7 | i | 0 |
| test.c:654:9:654:9 | i | 2147483647 |
| test.c:658:7:658:7 | u | 0 |
| test.c:659:9:659:9 | u | 4294967295 |
| test.cpp:10:7:10:7 | b | 2147483647 |
| test.cpp:11:5:11:5 | x | 2147483647 |
| test.cpp:13:10:13:10 | x | 2147483647 |

View File

@@ -70,3 +70,56 @@ argHasPostUpdate
| destructors.cpp:52:14:52:16 | ref | ArgumentNode is missing PostUpdateNode. |
| ir.cpp:623:5:623:5 | r | ArgumentNode is missing PostUpdateNode. |
| ir.cpp:625:5:625:5 | s | ArgumentNode is missing PostUpdateNode. |
postWithInFlow
| VacuousDestructorCall.cpp:10:22:10:22 | i [inner post update] | PostUpdateNode should not be the target of local flow. |
| allocators.cpp:4:11:4:13 | m_x [post update] | PostUpdateNode should not be the target of local flow. |
| allocators.cpp:4:17:4:19 | m_y [post update] | PostUpdateNode should not be the target of local flow. |
| assignexpr.cpp:9:4:9:4 | i [post update] | PostUpdateNode should not be the target of local flow. |
| builtin.c:34:23:34:31 | staticint [inner post update] | PostUpdateNode should not be the target of local flow. |
| builtin.c:39:37:39:45 | carry_out [inner post update] | PostUpdateNode should not be the target of local flow. |
| builtin.c:43:41:43:49 | staticint [inner post update] | PostUpdateNode should not be the target of local flow. |
| builtin.c:51:30:51:38 | staticint [inner post update] | PostUpdateNode should not be the target of local flow. |
| builtin.c:54:29:54:38 | atomic_int [inner post update] | PostUpdateNode should not be the target of local flow. |
| condition_decls.cpp:3:5:3:9 | m_ptr [post update] | PostUpdateNode should not be the target of local flow. |
| condition_decls.cpp:17:11:17:15 | m_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| condition_decls.cpp:20:11:20:15 | m_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| condition_decls.cpp:28:11:28:15 | m_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| condition_decls.cpp:31:11:31:15 | m_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| condition_decls.cpp:34:9:34:13 | m_ptr [inner post update] | PostUpdateNode should not be the target of local flow. |
| conditional_destructors.cpp:6:13:6:15 | val [post update] | PostUpdateNode should not be the target of local flow. |
| conditional_destructors.cpp:18:13:18:15 | val [post update] | PostUpdateNode should not be the target of local flow. |
| cpp11.cpp:7:7:7:8 | el [post update] | PostUpdateNode should not be the target of local flow. |
| cpp11.cpp:77:19:77:21 | call to Val | PostUpdateNode should not be the target of local flow. |
| cpp11.cpp:82:11:82:14 | call to Val | PostUpdateNode should not be the target of local flow. |
| cpp11.cpp:82:45:82:48 | call to Val | PostUpdateNode should not be the target of local flow. |
| cpp11.cpp:82:51:82:51 | call to Val | PostUpdateNode should not be the target of local flow. |
| ir.cpp:177:5:177:5 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:177:5:177:8 | access to array [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:178:5:178:8 | access to array [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:178:7:178:7 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:183:5:183:5 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:183:5:183:8 | access to array [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:184:5:184:8 | access to array [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:184:7:184:7 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:342:5:342:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:342:6:342:6 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:428:8:428:8 | x [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:429:8:429:8 | y [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:643:15:643:17 | m_a [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:644:11:644:14 | this [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:644:17:644:19 | m_a [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:645:9:645:11 | m_a [post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:654:11:654:14 | this [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:745:8:745:8 | base_s [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:754:8:754:8 | middle_s [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:763:8:763:8 | derived_s [inner post update] | PostUpdateNode should not be the target of local flow. |
| ir.cpp:809:7:809:13 | call to Base | PostUpdateNode should not be the target of local flow. |
| ir.cpp:810:7:810:26 | call to Base | PostUpdateNode should not be the target of local flow. |
| ir.cpp:823:7:823:13 | call to Base | PostUpdateNode should not be the target of local flow. |
| ir.cpp:824:7:824:26 | call to Base | PostUpdateNode should not be the target of local flow. |
| misc.c:130:7:130:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
| misc.c:131:9:131:9 | i [post update] | PostUpdateNode should not be the target of local flow. |
| misc.c:220:3:220:5 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| misc.c:220:4:220:5 | sp [inner post update] | PostUpdateNode should not be the target of local flow. |
| static_init_templates.cpp:3:2:3:4 | ref [post update] | PostUpdateNode should not be the target of local flow. |
| static_init_templates.cpp:21:2:21:4 | val [post update] | PostUpdateNode should not be the target of local flow. |

View File

@@ -1472,3 +1472,92 @@ uniquePostUpdate
postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
| aggregateinitializer.c:3:14:3:18 | Chi | PostUpdateNode should not be the target of local flow. |
| aggregateinitializer.c:3:21:3:25 | Chi | PostUpdateNode should not be the target of local flow. |
| allocators.cpp:3:27:3:27 | Chi | PostUpdateNode should not be the target of local flow. |
| allocators.cpp:3:35:3:35 | Chi | PostUpdateNode should not be the target of local flow. |
| allocators.cpp:4:11:4:23 | Chi | PostUpdateNode should not be the target of local flow. |
| allocators.cpp:4:17:4:23 | Chi | PostUpdateNode should not be the target of local flow. |
| assignexpr.cpp:9:2:9:12 | Store | PostUpdateNode should not be the target of local flow. |
| bad_asts.cpp:15:10:15:12 | Store | PostUpdateNode should not be the target of local flow. |
| builtin.c:14:26:14:26 | Chi | PostUpdateNode should not be the target of local flow. |
| builtin.c:14:29:14:29 | Chi | PostUpdateNode should not be the target of local flow. |
| builtin.c:14:32:14:32 | Chi | PostUpdateNode should not be the target of local flow. |
| builtin.c:14:35:14:35 | Chi | PostUpdateNode should not be the target of local flow. |
| condition_decls.cpp:3:5:3:22 | Chi | PostUpdateNode should not be the target of local flow. |
| condition_decls.cpp:3:21:3:21 | Chi | PostUpdateNode should not be the target of local flow. |
| conditional_destructors.cpp:6:13:6:19 | Chi | PostUpdateNode should not be the target of local flow. |
| conditional_destructors.cpp:18:13:18:19 | Chi | PostUpdateNode should not be the target of local flow. |
| cpp11.cpp:65:19:65:45 | Store | PostUpdateNode should not be the target of local flow. |
| cpp11.cpp:82:17:82:55 | Chi | PostUpdateNode should not be the target of local flow. |
| cpp11.cpp:82:45:82:48 | Chi | PostUpdateNode should not be the target of local flow. |
| defdestructordeleteexpr.cpp:4:9:4:15 | Chi | PostUpdateNode should not be the target of local flow. |
| deleteexpr.cpp:7:9:7:15 | Chi | PostUpdateNode should not be the target of local flow. |
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:177:5:177:12 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:178:5:178:12 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:183:5:183:12 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:184:5:184:12 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:342:5:342:10 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:428:5:428:12 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:429:5:429:15 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:504:19:504:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:504:22:504:22 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:505:16:505:21 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:505:19:505:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:506:16:506:18 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:506:16:506:18 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:513:14:513:16 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:513:14:513:16 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:514:14:514:26 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:514:19:514:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:514:22:514:22 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:515:19:515:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:515:22:515:22 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:515:29:515:29 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:515:32:515:32 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:516:17:516:21 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:516:19:516:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:516:24:516:28 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:516:26:516:26 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:521:19:521:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:521:22:521:22 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:521:25:521:25 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:522:16:522:21 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:522:19:522:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:531:14:531:14 | Store | PostUpdateNode should not be the target of local flow. |
| ir.cpp:577:16:577:21 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:577:19:577:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:578:19:578:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:578:22:578:22 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:579:16:579:21 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:579:19:579:19 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:643:9:643:21 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:644:9:644:23 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:645:9:645:15 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:659:9:659:14 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:660:13:660:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:661:9:661:13 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:943:3:943:11 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:947:3:947:25 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:962:17:962:47 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:962:17:962:47 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:962:17:962:47 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:962:26:962:30 | Chi | PostUpdateNode should not be the target of local flow. |
| ir.cpp:962:41:962:45 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:130:5:130:11 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:131:5:131:13 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:154:32:154:32 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:154:35:154:35 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:154:40:154:40 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:154:43:154:43 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:157:14:157:18 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:158:14:158:18 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:160:31:160:33 | Chi | PostUpdateNode should not be the target of local flow. |
| misc.c:160:31:160:33 | Chi | PostUpdateNode should not be the target of local flow. |
| range_analysis.c:102:5:102:15 | Chi | PostUpdateNode should not be the target of local flow. |
| static_init_templates.cpp:3:2:3:8 | Chi | PostUpdateNode should not be the target of local flow. |
| static_init_templates.cpp:21:2:21:12 | Chi | PostUpdateNode should not be the target of local flow. |

View File

@@ -4,12 +4,10 @@ edges
| search.c:14:24:14:28 | query | search.c:17:8:17:12 | query |
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
| search.c:41:21:41:26 | call to getenv | search.c:45:17:45:25 | raw_query |
| search.c:41:21:41:26 | call to getenv | search.c:45:17:45:25 | raw_query |
| search.c:41:21:41:26 | call to getenv | search.c:47:17:47:25 | raw_query |
| search.c:41:21:41:26 | call to getenv | search.c:47:17:47:25 | raw_query |
| search.c:45:17:45:25 | raw_query | search.c:14:24:14:28 | query |
| search.c:47:17:47:25 | raw_query | search.c:22:24:22:28 | query |
| search.c:41:21:41:26 | call to getenv | search.c:14:24:14:28 | query |
| search.c:41:21:41:26 | call to getenv | search.c:14:24:14:28 | query |
| search.c:41:21:41:26 | call to getenv | search.c:22:24:22:28 | query |
| search.c:41:21:41:26 | call to getenv | search.c:22:24:22:28 | query |
nodes
| search.c:14:24:14:28 | query | semmle.label | query |
| search.c:17:8:17:12 | (const char *)... | semmle.label | (const char *)... |
@@ -23,8 +21,8 @@ nodes
| search.c:23:39:23:43 | query | semmle.label | query |
| search.c:41:21:41:26 | call to getenv | semmle.label | call to getenv |
| search.c:41:21:41:26 | call to getenv | semmle.label | call to getenv |
| search.c:45:17:45:25 | raw_query | semmle.label | raw_query |
| search.c:47:17:47:25 | raw_query | semmle.label | raw_query |
| search.c:45:5:45:15 | Argument 0 | semmle.label | Argument 0 |
| search.c:47:5:47:15 | Argument 0 | semmle.label | Argument 0 |
#select
| search.c:17:8:17:12 | query | search.c:41:21:41:26 | call to getenv | search.c:17:8:17:12 | query | Cross-site scripting vulnerability due to $@. | search.c:41:21:41:26 | call to getenv | this query data |
| search.c:23:39:23:43 | query | search.c:41:21:41:26 | call to getenv | search.c:23:39:23:43 | query | Cross-site scripting vulnerability due to $@. | search.c:41:21:41:26 | call to getenv | this query data |

View File

@@ -32,8 +32,10 @@ nodes
| test.cpp:31:10:31:16 | command | semmle.label | command |
| test.cpp:31:10:31:16 | command | semmle.label | command |
| test.cpp:31:10:31:16 | command | semmle.label | command |
| test.cpp:42:7:42:16 | Argument 0 | semmle.label | Argument 0 |
| test.cpp:42:18:42:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:42:18:42:34 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:43:7:43:16 | Argument 0 | semmle.label | Argument 0 |
| test.cpp:43:18:43:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:43:18:43:34 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |

View File

@@ -65,26 +65,22 @@ edges
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | Argument 0 indirection |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | Argument 0 indirection |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | printWrapper output argument |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | printWrapper output argument |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | Argument 0 indirection |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | Argument 0 indirection |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | printWrapper output argument |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | printWrapper output argument |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
@@ -93,20 +89,15 @@ edges
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
| argvLocal.c:117:15:117:16 | Argument 0 indirection | argvLocal.c:117:15:117:16 | printWrapper output argument |
| argvLocal.c:117:15:117:16 | array to pointer conversion | argvLocal.c:117:15:117:16 | printWrapper output argument |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | (const char *)... |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | Argument 0 indirection |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | printWrapper output argument |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
| argvLocal.c:122:15:122:16 | Argument 0 indirection | argvLocal.c:122:15:122:16 | printWrapper output argument |
| argvLocal.c:122:15:122:16 | i4 | argvLocal.c:122:15:122:16 | printWrapper output argument |
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... |
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ |
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
@@ -115,14 +106,12 @@ edges
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | Argument 0 indirection |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | Argument 0 indirection |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | printWrapper output argument |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | printWrapper output argument |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | (const char *)... |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | (const char *)... |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... |
@@ -131,8 +120,6 @@ edges
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
| argvLocal.c:128:15:128:16 | Argument 0 indirection | argvLocal.c:128:15:128:16 | printWrapper output argument |
| argvLocal.c:128:15:128:16 | array to pointer conversion | argvLocal.c:128:15:128:16 | printWrapper output argument |
| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | (const char *)... |
| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | ... + ... |
| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... |
@@ -227,6 +214,7 @@ nodes
| argvLocal.c:116:9:116:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:116:9:116:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
| argvLocal.c:117:2:117:13 | Argument 0 | semmle.label | Argument 0 |
| argvLocal.c:117:15:117:16 | Argument 0 indirection | semmle.label | Argument 0 indirection |
| argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion |
| argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion |
@@ -235,6 +223,7 @@ nodes
| argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
| argvLocal.c:122:2:122:13 | Argument 0 | semmle.label | Argument 0 |
| argvLocal.c:122:15:122:16 | Argument 0 indirection | semmle.label | Argument 0 indirection |
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
@@ -245,6 +234,7 @@ nodes
| argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
| argvLocal.c:128:2:128:13 | Argument 0 | semmle.label | Argument 0 |
| argvLocal.c:128:15:128:16 | Argument 0 indirection | semmle.label | Argument 0 indirection |
| argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion |
| argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion |

View File

@@ -36,6 +36,7 @@ nodes
| globalVars.c:12:2:12:15 | Store | semmle.label | Store |
| globalVars.c:15:21:15:23 | val | semmle.label | val |
| globalVars.c:16:2:16:12 | Store | semmle.label | Store |
| globalVars.c:24:2:24:9 | Argument 0 | semmle.label | Argument 0 |
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
| globalVars.c:27:9:27:12 | (const char *)... | semmle.label | (const char *)... |
@@ -46,6 +47,7 @@ nodes
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
| globalVars.c:35:2:35:9 | Argument 0 | semmle.label | Argument 0 |
| globalVars.c:35:11:35:14 | copy | semmle.label | copy |
| globalVars.c:38:9:38:13 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:38:9:38:13 | (const char *)... | semmle.label | (const char *)... |

View File

@@ -47,18 +47,16 @@ edges
| test.cpp:214:23:214:23 | s | test.cpp:215:21:215:21 | s |
| test.cpp:220:21:220:21 | s | test.cpp:221:21:221:21 | s |
| test.cpp:220:21:220:21 | s | test.cpp:221:21:221:21 | s |
| test.cpp:227:24:227:29 | call to getenv | test.cpp:214:23:214:23 | s |
| test.cpp:227:24:227:29 | call to getenv | test.cpp:220:21:220:21 | s |
| test.cpp:227:24:227:29 | call to getenv | test.cpp:229:9:229:18 | (size_t)... |
| test.cpp:227:24:227:29 | call to getenv | test.cpp:229:9:229:18 | local_size |
| test.cpp:227:24:227:29 | call to getenv | test.cpp:229:9:229:18 | local_size |
| test.cpp:227:24:227:29 | call to getenv | test.cpp:235:11:235:20 | (size_t)... |
| test.cpp:227:24:227:29 | call to getenv | test.cpp:237:10:237:19 | (size_t)... |
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:214:23:214:23 | s |
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:220:21:220:21 | s |
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:229:9:229:18 | (size_t)... |
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:229:9:229:18 | local_size |
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:229:9:229:18 | local_size |
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:235:11:235:20 | (size_t)... |
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:237:10:237:19 | (size_t)... |
| test.cpp:235:11:235:20 | (size_t)... | test.cpp:214:23:214:23 | s |
| test.cpp:237:10:237:19 | (size_t)... | test.cpp:220:21:220:21 | s |
| test.cpp:241:2:241:32 | Chi [array content] | test.cpp:279:17:279:20 | get_size output argument [array content] |
| test.cpp:241:2:241:32 | Chi [array content] | test.cpp:295:18:295:21 | get_size output argument [array content] |
| test.cpp:241:2:241:32 | Store | test.cpp:241:2:241:32 | Chi [array content] |
@@ -143,8 +141,8 @@ nodes
| test.cpp:231:9:231:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
| test.cpp:231:9:231:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
| test.cpp:231:9:231:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
| test.cpp:235:11:235:20 | (size_t)... | semmle.label | (size_t)... |
| test.cpp:237:10:237:19 | (size_t)... | semmle.label | (size_t)... |
| test.cpp:235:2:235:9 | Argument 0 | semmle.label | Argument 0 |
| test.cpp:237:2:237:8 | Argument 0 | semmle.label | Argument 0 |
| test.cpp:241:2:241:32 | Chi [array content] | semmle.label | Chi [array content] |
| test.cpp:241:2:241:32 | Store | semmle.label | Store |
| test.cpp:241:18:241:23 | call to getenv | semmle.label | call to getenv |

View File

@@ -710,9 +710,9 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
[Fact]
public void TestWindowCSharpMsBuild()
{
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test1.sln"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln -DisableParallelProcessing"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
@@ -741,9 +741,9 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
[Fact]
public void TestWindowCSharpMsBuildMultipleSolutions()
{
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.csproj -DisableParallelProcessing"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj -DisableParallelProcessing"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project\test1.csproj"] = true;
@@ -786,7 +786,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
[Fact]
public void TestWindowCSharpMsBuildFailed()
{
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.sln"] = 0;
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 1;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
@@ -994,8 +994,8 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
[Fact]
public void TestDirsProjWindows()
{
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\dirs.proj"] = 0;
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj -DisableParallelProcessing"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\dirs.proj -DisableParallelProcessing"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project\a\test.csproj"] = true;
@@ -1038,8 +1038,8 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
[Fact]
public void TestDirsProjLinux()
{
Actions.RunProcess[@"nuget restore C:\Project/dirs.proj"] = 1;
Actions.RunProcess[@"mono C:\Project/.nuget/nuget.exe restore C:\Project/dirs.proj"] = 0;
Actions.RunProcess[@"nuget restore C:\Project/dirs.proj -DisableParallelProcessing"] = 1;
Actions.RunProcess[@"mono C:\Project/.nuget/nuget.exe restore C:\Project/dirs.proj -DisableParallelProcessing"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto msbuild C:\Project/dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project/a/test.csproj"] = true;

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Autobuild.CSharp</AssemblyName>
<RootNamespace>Semmle.Autobuild.CSharp</RootNamespace>
<ApplicationIcon />

View File

@@ -53,6 +53,7 @@ namespace Semmle.Autobuild.Shared
RunCommand(nuget).
Argument("restore").
QuoteArgument(projectOrSolution.FullPath).
Argument("-DisableParallelProcessing").
Script;
var nugetRestore = GetNugetRestoreScript();
var msbuildRestoreCommand = new CommandBuilder(builder.Actions).

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Autobuild.Shared</AssemblyName>
<RootNamespace>Semmle.Autobuild.Shared</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Extraction.CIL.Driver</AssemblyName>
<RootNamespace>Semmle.Extraction.CIL.Driver</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Extraction.CIL</AssemblyName>
<RootNamespace>Semmle.Extraction.CIL</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Extraction.CSharp.Driver</AssemblyName>
<RootNamespace>Semmle.Extraction.CSharp.Driver</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Extraction.CSharp.Standalone</AssemblyName>
<RootNamespace>Semmle.Extraction.CSharp.Standalone</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -9,25 +9,28 @@ namespace Semmle.Extraction.CSharp.Entities
protected Accessor(Context cx, IMethodSymbol init)
: base(cx, init) { }
/// <summary>
/// Gets the property symbol associated accessor `symbol`, or `null`
/// if there is no associated symbol.
/// </summary>
public static IPropertySymbol GetPropertySymbol(IMethodSymbol symbol)
{
// Usually, the property/indexer can be fetched from the associated symbol
var prop = symbol.AssociatedSymbol as IPropertySymbol;
if (prop != null)
return prop;
// But for properties/indexers that implement explicit interfaces, Roslyn
// does not properly populate `AssociatedSymbol`
var props = symbol.ContainingType.GetMembers().OfType<IPropertySymbol>();
props = props.Where(p => SymbolEqualityComparer.Default.Equals(symbol, p.GetMethod) || SymbolEqualityComparer.Default.Equals(symbol, p.SetMethod));
return props.SingleOrDefault();
}
/// <summary>
/// Gets the property symbol associated with this accessor.
/// </summary>
IPropertySymbol PropertySymbol
{
get
{
// Usually, the property/indexer can be fetched from the associated symbol
var prop = symbol.AssociatedSymbol as IPropertySymbol;
if (prop != null)
return prop;
// But for properties/indexers that implement explicit interfaces, Roslyn
// does not properly populate `AssociatedSymbol`
var props = symbol.ContainingType.GetMembers().OfType<IPropertySymbol>();
props = props.Where(p => SymbolEqualityComparer.Default.Equals(symbol, p.GetMethod) || SymbolEqualityComparer.Default.Equals(symbol, p.SetMethod));
return props.SingleOrDefault();
}
}
IPropertySymbol PropertySymbol => GetPropertySymbol(symbol);
public new Accessor OriginalDefinition => Create(Context, symbol.OriginalDefinition);

View File

@@ -240,7 +240,7 @@ namespace Semmle.Extraction.CSharp.Entities
return Destructor.Create(cx, methodDecl);
case MethodKind.PropertyGet:
case MethodKind.PropertySet:
return methodDecl.AssociatedSymbol is null ? OrdinaryMethod.Create(cx, methodDecl) : (Method)Accessor.Create(cx, methodDecl);
return Accessor.GetPropertySymbol(methodDecl) is null ? OrdinaryMethod.Create(cx, methodDecl) : (Method)Accessor.Create(cx, methodDecl);
case MethodKind.EventAdd:
case MethodKind.EventRemove:
return EventAccessor.Create(cx, methodDecl);

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Extraction.CSharp</AssemblyName>
<RootNamespace>Semmle.Extraction.CSharp</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -45,10 +45,14 @@ namespace Semmle.Extraction.Tests
Directory.SetCurrentDirectory(tmpDir);
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
// `Directory.SetCurrentDirectory()` doesn't seem to work on macOS,
// so disable this test on macOS, for now
// `Directory.SetCurrentDirectory()` seems to slightly change the path on macOS,
// so adjusting it:
Assert.NotEqual(Directory.GetCurrentDirectory(), tmpDir);
return;
tmpDir = "/private" + tmpDir;
// Remove trailing slash:
Assert.Equal('/', tmpDir[tmpDir.Length - 1]);
tmpDir = tmpDir.Substring(0, tmpDir.Length - 1);
Assert.Equal(Directory.GetCurrentDirectory(), tmpDir);
}
var f1 = project!.GetTrapPath(Logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip);
var g1 = TrapWriter.NestPaths(Logger, tmpDir, "foo.cs.trap.gz");

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Extraction</AssemblyName>
<RootNamespace>Semmle.Extraction</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Semmle.Util</AssemblyName>
<RootNamespace>Semmle.Util</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

View File

@@ -39,7 +39,7 @@ module Stages {
cached
private predicate forceCachingInSameStageRev() {
any(ControlFlowElement cfe).controlsBlock(_, _)
any(ControlFlowElement cfe).controlsBlock(_, _, _)
or
exists(GuardedExpr ge)
or

View File

@@ -62,7 +62,7 @@ class Assertion extends MethodCall {
* does not work.
*/
pragma[nomagic]
private predicate immediatelyDominatesBlockSplit(BasicBlock succ) {
deprecated private predicate immediatelyDominatesBlockSplit(BasicBlock succ) {
// Only calculate dominance by explicit recursion for split nodes;
// all other nodes can use regular CFG dominance
this instanceof ControlFlow::Internal::SplitControlFlowElement and
@@ -78,11 +78,11 @@ class Assertion extends MethodCall {
}
pragma[noinline]
private predicate strictlyDominatesJoinBlockPredecessor(JoinBlock jb, int i) {
deprecated private predicate strictlyDominatesJoinBlockPredecessor(JoinBlock jb, int i) {
this.strictlyDominatesSplit(jb.getJoinBlockPredecessor(i))
}
private predicate strictlyDominatesJoinBlockSplit(JoinBlock jb, int i) {
deprecated private predicate strictlyDominatesJoinBlockSplit(JoinBlock jb, int i) {
i = -1 and
this.strictlyDominatesJoinBlockPredecessor(jb, _)
or
@@ -95,7 +95,7 @@ class Assertion extends MethodCall {
}
pragma[nomagic]
private predicate strictlyDominatesSplit(BasicBlock bb) {
deprecated private predicate strictlyDominatesSplit(BasicBlock bb) {
this.immediatelyDominatesBlockSplit(bb)
or
// Equivalent with
@@ -121,6 +121,8 @@ class Assertion extends MethodCall {
}
/**
* DEPRECATED: Use `getExpr().controlsBlock()` instead.
*
* Holds if this assertion strictly dominates basic block `bb`. That is, `bb`
* can only be reached from the callable entry point by going via *some* basic
* block containing this element.
@@ -130,7 +132,7 @@ class Assertion extends MethodCall {
* in that it takes control flow splitting into account.
*/
pragma[nomagic]
predicate strictlyDominates(BasicBlock bb) {
deprecated predicate strictlyDominates(BasicBlock bb) {
this.strictlyDominatesSplit(bb)
or
this.getAControlFlowNode().getBasicBlock().strictlyDominates(bb)

View File

@@ -126,39 +126,47 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
* ```
*
* does not work.
*
* `cb` records all of the possible condition blocks for this control flow element
* that a path from the callable entry point to `succ` may go through.
*/
pragma[nomagic]
private predicate immediatelyControlsBlockSplit(BasicBlock succ, ConditionalSuccessor s) {
exists(ConditionBlock cb | this.immediatelyControlsBlockSplit0(cb, succ, s) |
forall(BasicBlock pred, SuccessorType t |
this.immediatelyControlsBlockSplit1(cb, succ, s, pred, t)
|
this.immediatelyControlsBlockSplit2(cb, succ, s, pred, t)
)
private predicate immediatelyControlsBlockSplit(
BasicBlock succ, ConditionalSuccessor s, ConditionBlock cb
) {
this.immediatelyControlsBlockSplit0(cb, succ, s) and
forall(BasicBlock pred, SuccessorType t |
this.immediatelyControlsBlockSplit1(cb, succ, s, pred, t)
|
this.immediatelyControlsBlockSplit2(cb, succ, s, pred, t)
)
}
pragma[noinline]
private predicate controlsJoinBlockPredecessor(JoinBlock controlled, ConditionalSuccessor s, int i) {
this.controlsBlockSplit(controlled.getJoinBlockPredecessor(i), s)
private predicate controlsJoinBlockPredecessor(
JoinBlock controlled, ConditionalSuccessor s, int i, ConditionBlock cb
) {
this.controlsBlockSplit(controlled.getJoinBlockPredecessor(i), s, cb)
}
private predicate controlsJoinBlockSplit(JoinBlock controlled, ConditionalSuccessor s, int i) {
i = -1 and
this.controlsJoinBlockPredecessor(controlled, s, _)
this.controlsJoinBlockPredecessor(controlled, s, _, _)
or
this.controlsJoinBlockSplit(controlled, s, i - 1) and
(
this.controlsJoinBlockPredecessor(controlled, s, i)
this.controlsJoinBlockPredecessor(controlled, s, i, _)
or
controlled.dominates(controlled.getJoinBlockPredecessor(i))
)
}
cached
private predicate controlsBlockSplit(BasicBlock controlled, ConditionalSuccessor s) {
private predicate controlsBlockSplit(
BasicBlock controlled, ConditionalSuccessor s, ConditionBlock cb
) {
Stages::GuardsStage::forceCachingInSameStage() and
this.immediatelyControlsBlockSplit(controlled, s)
this.immediatelyControlsBlockSplit(controlled, s, cb)
or
// Equivalent with
//
@@ -178,10 +186,11 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
last = max(int i | exists(controlled.(JoinBlock).getJoinBlockPredecessor(i)))
|
this.controlsJoinBlockSplit(controlled, s, last)
)
) and
this.controlsJoinBlockPredecessor(controlled, s, _, cb)
or
not controlled instanceof JoinBlock and
this.controlsBlockSplit(controlled.getAPredecessor(), s)
this.controlsBlockSplit(controlled.getAPredecessor(), s, cb)
}
/**
@@ -200,16 +209,25 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
* ```
*
* as control flow splitting is taken into account.
*
* `cb` records all of the possible condition blocks for this control flow element
* that a path from the callable entry point to `controlled` may go through.
*/
predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s) {
this.controlsBlockSplit(controlled, s)
predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s, ConditionBlock cb) {
this.controlsBlockSplit(controlled, s, cb)
or
exists(ConditionBlock cb | cb.getLastNode() = this.getAControlFlowNode() |
cb.controls(controlled, s)
)
cb.getLastNode() = this.getAControlFlowNode() and
cb.controls(controlled, s)
}
/** DEPRECATED: Use `controlsBlock/3` instead. */
deprecated predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s) {
this.controlsBlock(controlled, s, _)
}
/**
* DEPRECATED.
*
* Holds if control flow element `controlled` is controlled by this control flow
* element with conditional value `s`. That is, `controlled` can only be reached
* from the callable entry point by going via the `s` edge out of this element.
@@ -227,7 +245,7 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
*/
// potentially very large predicate, so must be inlined
pragma[inline]
predicate controlsElement(ControlFlowElement controlled, ConditionalSuccessor s) {
deprecated predicate controlsElement(ControlFlowElement controlled, ConditionalSuccessor s) {
forex(BasicBlock bb | bb = controlled.getAControlFlowNode().getBasicBlock() |
this.controlsBlock(bb, s)
)

View File

@@ -659,13 +659,12 @@ module ControlFlow {
or
cfe =
any(ArrayCreation ac |
if ac.isImplicitlySized()
then
// No length argument: element itself
result = ac
else
// First element of first length argument
result = first(ac.getLengthArgument(0))
// First element of first length argument
result = first(ac.getLengthArgument(0))
or
// No length argument: element itself
not exists(ac.getLengthArgument(0)) and
result = ac
)
or
cfe =

View File

@@ -36,7 +36,7 @@ class Guard extends Expr {
* Holds if basic block `bb` is guarded by this expression having value `v`.
*/
predicate controlsBasicBlock(BasicBlock bb, AbstractValue v) {
Internal::guardControls(this, bb, v)
Internal::guardControls(this, _, bb, v)
}
/**
@@ -612,14 +612,11 @@ private Ssa::Definition getAnSsaQualifier(Expr e, ControlFlow::Node cfn) {
}
private AssignableAccess getATrackedAccess(Ssa::Definition def, ControlFlow::Node cfn) {
(
result = def.getAReadAtNode(cfn)
or
result = def.(Ssa::ExplicitDefinition).getADefinition().getTargetAccess() and
result.getAControlFlowNode() = cfn and
cfn.getBasicBlock() = def.getBasicBlock()
) and
result = def.getAReadAtNode(cfn) and
not def instanceof Ssa::ImplicitUntrackedDefinition
or
result = def.(Ssa::ExplicitDefinition).getADefinition().getTargetAccess() and
cfn = def.getControlFlowNode()
}
/**
@@ -962,41 +959,6 @@ module Internal {
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand())
}
pragma[noinline]
private predicate assertionControlsNodeInSameBasicBlock0(
Guard g, AbstractValue v, BasicBlock bb, int i
) {
exists(Assertion a, Guard g0, AbstractValue v0 |
asserts(a, g0, v0) and
impliesSteps(g0, v0, g, v) and
bb.getNode(i) = a.getAControlFlowNode()
)
}
/**
* Holds if control flow node `cfn` only is reached when guard `g` evaluates to `v`,
* because of an assertion.
*/
private predicate assertionControlsNodeInSameBasicBlock(
Guard g, ControlFlow::Node cfn, AbstractValue v
) {
exists(BasicBlock bb, int i, int j |
assertionControlsNodeInSameBasicBlock0(g, v, bb, i) and
bb.getNode(j) = cfn and
j > i
)
}
/**
* Holds if control flow element `cfe` only is reached when guard `g` evaluates to `v`,
* because of an assertion.
*/
private predicate guardAssertionControlsElement(Guard g, ControlFlowElement cfe, AbstractValue v) {
forex(ControlFlow::Node cfn | cfn = cfe.getAControlFlowNode() |
assertionControlsNodeInSameBasicBlock(g, cfn, v)
)
}
/** Same as `this.getAChildExpr*()`, but avoids `fastTC`. */
private Expr getAChildExprStar(Guard g) {
result = g
@@ -1004,26 +966,6 @@ module Internal {
result = getAChildExprStar(g).getAChildExpr()
}
/**
* Holds if assertion `a` directly asserts that expression `e` evaluates to value `v`.
*/
predicate asserts(Assertion a, Expr e, AbstractValue v) {
e = a.getExpr() and
(
a.getAssertMethod() instanceof AssertTrueMethod and
v.(BooleanValue).getValue() = true
or
a.getAssertMethod() instanceof AssertFalseMethod and
v.(BooleanValue).getValue() = false
or
a.getAssertMethod() instanceof AssertNullMethod and
v.(NullValue).isNull()
or
a.getAssertMethod() instanceof AssertNonNullMethod and
v.(NullValue).isNonNull()
)
}
private Expr stripConditionalExpr(Expr e) {
e =
any(ConditionalExpr ce |
@@ -1453,8 +1395,6 @@ module Internal {
or
val.branch(_, _, e)
or
asserts(_, e, val)
or
e instanceof CollectionExpr and
val = TEmptyCollectionValue(_)
) and
@@ -1767,11 +1707,7 @@ module Internal {
pragma[noinline]
private predicate candidateAux(AccessOrCallExpr e, Declaration target, BasicBlock bb) {
target = e.getTarget() and
exists(Guard g | e = getAChildExprStar(g) |
guardControls(g, bb, _)
or
assertionControlsNodeInSameBasicBlock(g, bb.getANode(), _)
)
exists(Guard g | e = getAChildExprStar(g) | guardControls(g, _, bb, _))
}
}
@@ -1779,42 +1715,52 @@ module Internal {
private module Cached {
private import semmle.code.csharp.Caching
/** Holds if basic block `bb` only is reached when guard `g` has abstract value `v`. */
/**
* Holds if basic block `bb` only is reached when guard `g` has abstract value `v`.
*
* `cb` records all of the possible condition blocks for `g` that a path from the
* callable entry point to `bb` may go through.
*/
cached
predicate guardControls(Guard g, BasicBlock bb, AbstractValue v) {
exists(AbstractValue v0, Guard g0 | impliesSteps(g0, v0, g, v) |
exists(ControlFlowElement cfe, ConditionalSuccessor s |
v0.branch(cfe, s, g0) and cfe.controlsBlock(bb, s)
)
or
exists(Assertion a |
asserts(a, g0, v0) and
a.strictlyDominates(bb)
predicate guardControls(Guard g, ConditionBlock cb, BasicBlock bb, AbstractValue v) {
exists(AbstractValue v0, Guard g0 |
impliesSteps(g0, v0, g, v) and
exists(ControlFlowElement cfe, ConditionalSuccessor cs |
v0.branch(cfe, cs, g0) and cfe.controlsBlock(bb, cs, cb)
)
)
}
pragma[noinline]
private predicate isGuardedByNode0(
ControlFlow::Node cfn, AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub,
AbstractValue v
private predicate nodeIsGuardedBySameSubExpr0(
ControlFlow::Node guardedCfn, AccessOrCallExpr guarded, Guard g, ConditionBlock cb,
AccessOrCallExpr sub, AbstractValue v
) {
Stages::GuardsStage::forceCachingInSameStage() and
cfn = guarded.getAControlFlowNode() and
guardControls(g, cfn.getBasicBlock(), v) and
guardedCfn = guarded.getAControlFlowNode() and
guardControls(g, cb, guardedCfn.getBasicBlock(), v) and
exists(ConditionOnExprComparisonConfig c | c.same(sub, guarded))
}
pragma[noinline]
private predicate isGuardedByExpr1(
AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub, AbstractValue v
private predicate nodeIsGuardedBySameSubExpr(
ControlFlow::Node guardedCfn, AccessOrCallExpr guarded, Guard g, ConditionBlock cb,
AccessOrCallExpr sub, AbstractValue v
) {
forex(ControlFlow::Node cfn | cfn = guarded.getAControlFlowNode() |
isGuardedByNode0(cfn, guarded, g, sub, v)
nodeIsGuardedBySameSubExpr0(guardedCfn, guarded, g, cb, sub, v) and
sub = getAChildExprStar(g)
}
pragma[noinline]
private predicate nodeIsGuardedBySameSubExprSsaDef(
ControlFlow::Node cfn, AccessOrCallExpr guarded, Guard g, ControlFlow::Node subCfn,
AccessOrCallExpr sub, AbstractValue v, Ssa::Definition def
) {
exists(ConditionBlock cb |
nodeIsGuardedBySameSubExpr(cfn, guarded, g, cb, sub, v) and
subCfn.getBasicBlock().dominates(cb) and
def = sub.getAnSsaQualifier(subCfn)
)
or
guardAssertionControlsElement(g, guarded, v) and
exists(ConditionOnExprComparisonConfig c | c.same(sub, guarded))
}
private predicate adjacentReadPairSameVarUniquePredecessor(
@@ -1828,47 +1774,45 @@ module Internal {
)
}
pragma[noinline]
private predicate isGuardedByExpr0(
AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub, AbstractValue v
) {
forex(ControlFlow::Node cfn | cfn = guarded.getAControlFlowNode() |
nodeIsGuardedBySameSubExpr(cfn, guarded, g, _, sub, v)
)
}
cached
predicate isGuardedByExpr(
AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub, AbstractValue v
) {
isGuardedByExpr1(guarded, g, sub, v) and
sub = getAChildExprStar(g) and
forall(Ssa::Definition def, ControlFlow::Node subCfn | def = sub.getAnSsaQualifier(subCfn) |
exists(ControlFlow::Node defCfn | def = guarded.getAnSsaQualifier(defCfn) |
isGuardedByExpr0(guarded, g, sub, v) and
forall(ControlFlow::Node subCfn, Ssa::Definition def |
nodeIsGuardedBySameSubExprSsaDef(_, guarded, g, subCfn, sub, v, def)
|
exists(ControlFlow::Node guardedCfn |
def = guarded.getAnSsaQualifier(guardedCfn) and
if v.isReferentialProperty()
then adjacentReadPairSameVarUniquePredecessor(def, subCfn, defCfn)
then adjacentReadPairSameVarUniquePredecessor(def, subCfn, guardedCfn)
else any()
)
)
}
pragma[noinline]
private predicate isGuardedByNode1(
ControlFlow::Nodes::ElementNode guarded, Guard g, AccessOrCallExpr sub, AbstractValue v
) {
isGuardedByNode0(guarded, _, g, sub, v)
or
assertionControlsNodeInSameBasicBlock(g, guarded, v) and
exists(ConditionOnExprComparisonConfig c | c.same(sub, guarded.getElement()))
}
pragma[noinline]
private predicate isGuardedByNode2(ControlFlow::Nodes::ElementNode guarded, Ssa::Definition def) {
isGuardedByNode1(guarded, _, _, _) and
exists(BasicBlock bb | bb = guarded.getBasicBlock() |
def = guarded.getElement().(AccessOrCallExpr).getAnSsaQualifier(bb.getANode())
)
}
cached
predicate isGuardedByNode(
ControlFlow::Nodes::ElementNode guarded, Guard g, AccessOrCallExpr sub, AbstractValue v
) {
isGuardedByNode1(guarded, g, sub, v) and
sub = getAChildExprStar(g) and
forall(Ssa::Definition def, ControlFlow::Node subCfn | def = sub.getAnSsaQualifier(subCfn) |
isGuardedByNode2(guarded, def) and
nodeIsGuardedBySameSubExpr(guarded, _, g, _, sub, v) and
forall(ControlFlow::Node subCfn, Ssa::Definition def |
nodeIsGuardedBySameSubExprSsaDef(guarded, _, g, subCfn, sub, v, def)
|
def =
guarded
.getElement()
.(AccessOrCallExpr)
.getAnSsaQualifier(guarded.getBasicBlock().getANode()) and
if v.isReferentialProperty()
then adjacentReadPairSameVarUniquePredecessor(def, subCfn, guarded)
else any()

View File

@@ -20,6 +20,7 @@
*/
import csharp
private import semmle.code.csharp.commons.Assertions
private import semmle.code.csharp.commons.Constants
private import semmle.code.csharp.frameworks.System
private import NonReturning
@@ -98,6 +99,13 @@ class Completion extends TCompletion {
cfe instanceof ThrowElement and
this = TThrowCompletion(cfe.(ThrowElement).getThrownExceptionType())
or
exists(AssertMethod m | assertion(cfe, m, _) |
this = TThrowCompletion(m.getExceptionClass())
or
not exists(m.getExceptionClass()) and
this = TExitCompletion()
)
or
completionIsValidForStmt(cfe, this)
or
mustHaveBooleanCompletion(cfe) and
@@ -382,6 +390,11 @@ private predicate invalidCastCandidate(CastExpr ce) {
ce.getType() = ce.getExpr().getType().(ValueOrRefType).getASubType+()
}
private predicate assertion(Assertion a, AssertMethod am, Expr e) {
e = a.getExpr() and
am = a.getAssertMethod()
}
/**
* Holds if a normal completion of `e` must be a Boolean completion.
*/
@@ -409,6 +422,9 @@ private predicate inBooleanContext(Expr e, boolean isBooleanCompletionForParent)
or
exists(SpecificCatchClause scc | scc.getFilterClause() = e | isBooleanCompletionForParent = false)
or
assertion(_, [any(AssertTrueMethod m).(AssertMethod), any(AssertFalseMethod m)], e) and
isBooleanCompletionForParent = false
or
exists(LogicalNotExpr lne | lne.getAnOperand() = e |
inBooleanContext(lne, _) and
isBooleanCompletionForParent = true
@@ -479,6 +495,9 @@ private predicate inNullnessContext(Expr e, boolean isNullnessCompletionForParen
isNullnessCompletionForParent = false
)
or
assertion(_, [any(AssertNullMethod m).(AssertMethod), any(AssertNonNullMethod m)], e) and
isNullnessCompletionForParent = false
or
exists(ConditionalExpr ce | inNullnessContext(ce, _) |
(e = ce.getThen() or e = ce.getElse()) and
isNullnessCompletionForParent = true

View File

@@ -89,10 +89,14 @@ class PreBasicBlock extends ControlFlowElement {
private predicate dominatesPredecessor(PreBasicBlock df) { this.dominates(df.getAPredecessor()) }
}
private Completion getConditionalCompletion(ConditionalCompletion cc) {
result.getInnerCompletion() = cc
}
class ConditionBlock extends PreBasicBlock {
ConditionBlock() {
strictcount(Completion c |
c.getInnerCompletion() instanceof ConditionalCompletion and
c = getConditionalCompletion(_) and
(
exists(succ(this.getLastElement(), c))
or
@@ -102,9 +106,20 @@ class ConditionBlock extends PreBasicBlock {
}
private predicate immediatelyControls(PreBasicBlock succ, ConditionalCompletion cc) {
succ = succ(this.getLastElement(), any(Completion c | c.getInnerCompletion() = cc)) and
forall(PreBasicBlock pred | pred = succ.getAPredecessor() and pred != this |
succ.dominates(pred)
exists(ControlFlowElement last, Completion c |
last = this.getLastElement() and
c = getConditionalCompletion(cc) and
succ = succ(last, c) and
// In the pre-CFG, we need to account for case where one predecessor node has
// two edges to the same successor node. Assertion expressions are examples of
// such nodes.
not exists(Completion other |
succ = succ(last, other) and
other != c
) and
forall(PreBasicBlock pred | pred = succ.getAPredecessor() and pred != this |
succ.dominates(pred)
)
)
}

View File

@@ -27,6 +27,7 @@ private module Cached {
cached
newtype TSplitKind =
TInitializerSplitKind() or
TAssertionSplitKind() or
TFinallySplitKind(int nestLevel) { nestLevel = FinallySplitting::nestLevel(_) } or
TExceptionHandlerSplitKind() or
TBooleanSplitKind(BooleanSplitting::BooleanSplitSubKind kind) { kind.startsSplit(_) } or
@@ -35,6 +36,7 @@ private module Cached {
cached
newtype TSplit =
TInitializerSplit(Constructor c) { InitializerSplitting::constructorInitializes(c, _) } or
TAssertionSplit(AssertionSplitting::Assertion a, boolean success) { success = [true, false] } or
TFinallySplit(FinallySplitting::FinallySplitType type, int nestLevel) {
nestLevel = FinallySplitting::nestLevel(_)
} or
@@ -385,6 +387,135 @@ module InitializerSplitting {
}
}
module AssertionSplitting {
import semmle.code.csharp.commons.Assertions
private import semmle.code.csharp.ExprOrStmtParent
private ControlFlowElement getAnAssertionDescendant(Assertion a) {
result = a
or
result = getAnAssertionDescendant(a).getAChild()
}
/**
* A split for assertions. For example, in
*
* ```csharp
* void M(int i)
* {
* Debug.Assert(i >= 0);
* System.Console.WriteLine("i is positive")
* }
* ```
*
* we record whether `i >= 0` evaluates to `true` or `false`, and restrict the
* edges out of the assertion accordingly.
*/
class AssertionSplitImpl extends SplitImpl, TAssertionSplit {
Assertion a;
boolean success;
AssertionSplitImpl() { this = TAssertionSplit(a, success) }
/** Gets the assertion. */
Assertion getAssertion() { result = a }
/** Holds if this split represents a successful assertion. */
predicate isSuccess() { success = true }
override string toString() {
success = true and result = "assertion success"
or
success = false and result = "assertion failure"
}
}
private class AssertionSplitKind extends SplitKind, TAssertionSplitKind {
override int getListOrder() { result = InitializerSplitting::getNextListOrder() }
override predicate isEnabled(ControlFlowElement cfe) { this.appliesTo(cfe) }
override string toString() { result = "Assertion" }
}
int getNextListOrder() { result = InitializerSplitting::getNextListOrder() + 1 }
private class AssertionSplitInternal extends SplitInternal, AssertionSplitImpl {
override AssertionSplitKind getKind() { any() }
override predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
exists(AssertMethod m |
pred = last(a.getExpr(), c) and
succ = succ(pred, c) and
this.getAssertion() = a and
m = a.getAssertMethod()
|
m instanceof AssertTrueMethod and
(
c instanceof TrueCompletion and success = true
or
c instanceof FalseCompletion and success = false
)
or
m instanceof AssertFalseMethod and
(
c instanceof TrueCompletion and success = false
or
c instanceof FalseCompletion and success = true
)
or
m instanceof AssertNullMethod and
(
c.(NullnessCompletion).isNull() and success = true
or
c.(NullnessCompletion).isNonNull() and success = false
)
or
m instanceof AssertNonNullMethod and
(
c.(NullnessCompletion).isNull() and success = false
or
c.(NullnessCompletion).isNonNull() and success = true
)
)
}
override predicate hasEntry(Callable c, ControlFlowElement succ) { none() }
override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
this.appliesTo(pred) and
pred = a and
succ = succ(pred, c) and
(
success = true and
c instanceof NormalCompletion
or
success = false and
not c instanceof NormalCompletion
)
}
override Callable hasExit(ControlFlowElement pred, Completion c) {
this.appliesTo(pred) and
pred = a and
result = succExit(pred, c) and
(
success = true and
c instanceof NormalCompletion
or
success = false and
not c instanceof NormalCompletion
)
}
override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
this.appliesTo(pred) and
succ = succ(pred, c) and
succ = getAnAssertionDescendant(a)
}
}
}
pragma[noinline]
private ControlFlowElement getAChild(ControlFlowElement cfe, Callable c) {
result = cfe.getAChild() and
@@ -509,11 +640,11 @@ module FinallySplitting {
}
private int getListOrder(FinallySplitKind kind) {
result = InitializerSplitting::getNextListOrder() + kind.getNestLevel()
result = AssertionSplitting::getNextListOrder() + kind.getNestLevel()
}
int getNextListOrder() {
result = max(int i | i = getListOrder(_) + 1 or i = InitializerSplitting::getNextListOrder())
result = max(int i | i = getListOrder(_) + 1 or i = AssertionSplitting::getNextListOrder())
}
private class FinallySplitKind extends SplitKind, TFinallySplitKind {

View File

@@ -0,0 +1,78 @@
/**
* Provides classes for representing abstract bounds for use in, for example, range analysis.
*/
private import internal.rangeanalysis.BoundSpecific
private newtype TBound =
TBoundZero() or
TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or
TBoundExpr(Expr e) {
interestingExprBound(e) and
not exists(SsaVariable v | e = v.getAUse())
}
/**
* A bound that may be inferred for an expression plus/minus an integer delta.
*/
abstract class Bound extends TBound {
/** Gets a textual representation of this bound. */
abstract string toString();
/** Gets an expression that equals this bound plus `delta`. */
abstract Expr getExpr(int delta);
/** Gets an expression that equals this bound. */
Expr getExpr() { result = getExpr(0) }
/**
* Holds if this element is at the specified location.
* The location spans column `sc` of line `sl` to
* column `ec` of line `el` in file `path`.
* For more information, see
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
*/
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
}
}
/**
* The bound that corresponds to the integer 0. This is used to represent all
* integer bounds as bounds are always accompanied by an added integer delta.
*/
class ZeroBound extends Bound, TBoundZero {
override string toString() { result = "0" }
override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta }
}
/**
* A bound corresponding to the value of an SSA variable.
*/
class SsaBound extends Bound, TBoundSsa {
/** Gets the SSA variable that equals this bound. */
SsaVariable getSsa() { this = TBoundSsa(result) }
override string toString() { result = getSsa().toString() }
override Expr getExpr(int delta) { result = getSsa().getAUse() and delta = 0 }
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
getSsa().getLocation().hasLocationInfo(path, sl, sc, el, ec)
}
}
/**
* A bound that corresponds to the value of a specific expression that might be
* interesting, but isn't otherwise represented by the value of an SSA variable.
*/
class ExprBound extends Bound, TBoundExpr {
override string toString() { result = getExpr().toString() }
override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 }
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
getExpr().getLocation().hasLocationInfo(path, sl, sc, el, ec)
}
}

View File

@@ -11,6 +11,7 @@ private import semmle.code.csharp.frameworks.system.io.Compression
private import semmle.code.csharp.frameworks.system.linq.Expressions
private import semmle.code.csharp.frameworks.system.Net
private import semmle.code.csharp.frameworks.system.Text
private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
private import semmle.code.csharp.frameworks.system.threading.Tasks
private import semmle.code.csharp.frameworks.system.Web
private import semmle.code.csharp.frameworks.system.web.ui.WebControls
@@ -34,6 +35,8 @@ private newtype TAccessPath =
or
tail = AccessPath::singleton(_) and
head instanceof ElementContent
or
tail = AccessPath::element()
}
/** An access path. */
@@ -93,6 +96,11 @@ module AccessPath {
result = singleton(any(PropertyContent c | c.getProperty() = p.getSourceDeclaration()))
}
/** Gets a singleton field access path. */
AccessPath field(Field f) {
result = singleton(any(FieldContent c | c.getField() = f.getSourceDeclaration()))
}
/** Gets an access path representing a property inside a collection. */
AccessPath properties(Property p) { result = TConsAccessPath(any(ElementContent c), property(p)) }
}
@@ -339,7 +347,7 @@ abstract class LibraryTypeDataFlow extends Type {
* Holds if data may flow from `source` to `sink` when calling callable `c`.
*
* `sourceAp` describes the contents of `source` that flows to `sink`
* (if any), and `sinkContent` describes the contents of `sink` that it
* (if any), and `sinkAp` describes the contents of `sink` that it
* flows to (if any).
*/
pragma[nomagic]
@@ -718,6 +726,56 @@ class SystemLazyFlow extends LibraryTypeDataFlow, SystemLazyClass {
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(this.getValueProperty())
)
or
preservesValue = false and
c = this.getValueProperty().getGetter() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
}
}
/** Data flow for `System.Nullable<>`. */
class SystemNullableFlow extends LibraryTypeDataFlow, SystemNullableStruct {
override predicate callableFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
preservesValue = true and
c.(Constructor).getDeclaringType() = this and
source = getFlowSourceArg(c, 0, sourceAp) and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(this.getValueProperty())
or
preservesValue = true and
c = this.getAGetValueOrDefaultMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::property(this.getValueProperty()) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
or
preservesValue = false and
c = this.getHasValueProperty().getGetter() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::property(this.getValueProperty()) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
or
preservesValue = true and
c = this.getAGetValueOrDefaultMethod() and
source = getFlowSourceArg(c, 0, _) and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
or
preservesValue = false and
c = this.getValueProperty().getGetter() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
}
}
@@ -1658,7 +1716,6 @@ class SystemThreadingTasksTaskFlow extends LibraryTypeDataFlow, SystemThreadingT
(
m.hasName("ContinueWith") and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty() and
(
// flow from supplied state to supplied delegate
exists(ConstructedDelegateType delegate, int i, int j, int k |
@@ -1670,7 +1727,8 @@ class SystemThreadingTasksTaskFlow extends LibraryTypeDataFlow, SystemThreadingT
) and
delegate.getTypeArgument(k) instanceof ObjectType and
source = TCallableFlowSourceArg(i) and
sink = getDelegateFlowSinkArg(m, j, k)
sink = getDelegateFlowSinkArg(m, j, k) and
sinkAp = AccessPath::empty()
)
or
// flow out of supplied function
@@ -1678,71 +1736,74 @@ class SystemThreadingTasksTaskFlow extends LibraryTypeDataFlow, SystemThreadingT
m.getParameter(i).getType() = func and
func.getUnboundGeneric() instanceof SystemFuncDelegateType and
source = getDelegateFlowSourceArg(m, i) and
sink = TCallableFlowSinkReturn()
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(any(SystemThreadingTasksTaskTClass c).getResultProperty())
)
)
or
m.hasName("FromResult") and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty() and
(
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
)
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(any(SystemThreadingTasksTaskTClass c).getResultProperty())
or
m.hasName("Run") and
m.getReturnType() = any(SystemThreadingTasksTaskTClass c).getAConstructedGeneric() and
m.(UnboundGenericMethod).getNumberOfTypeParameters() = 1 and
source = TCallableFlowSourceDelegateArg(0) and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty() and
(
m.getReturnType() = any(SystemThreadingTasksTaskTClass c).getAConstructedGeneric() and
m.(UnboundGenericMethod).getNumberOfTypeParameters() = 1 and
source = TCallableFlowSourceDelegateArg(0) and
sink = TCallableFlowSinkReturn()
)
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(any(SystemThreadingTasksTaskTClass c).getResultProperty())
or
m.getName().regexpMatch("WhenAll|WhenAny") and
sinkAp = AccessPath::empty() and
(
m.getReturnType() = any(SystemThreadingTasksTaskTClass c).getAConstructedGeneric() and
m.(UnboundGenericMethod).getNumberOfTypeParameters() = 1 and
source = getFlowSourceArg(m, _, sourceAp) and
sink = TCallableFlowSinkReturn()
)
m.getReturnType() = any(SystemThreadingTasksTaskTClass c).getAConstructedGeneric() and
m.(UnboundGenericMethod).getNumberOfTypeParameters() = 1 and
source = getFlowSourceArg(m, _, _) and
sourceAp = AccessPath::properties(any(SystemThreadingTasksTaskTClass c).getResultProperty()) and
sink = TCallableFlowSinkReturn() and
sinkAp =
AccessPath::cons(any(PropertyContent c |
c.getProperty() = any(SystemThreadingTasksTaskTClass tc).getResultProperty()
), AccessPath::element())
)
}
}
/** Data flow for `System.Threading.Tasks.Task<>`. */
class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow {
SystemThreadingTasksTaskTFlow() { this instanceof SystemThreadingTasksTaskTClass }
class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow, SystemThreadingTasksTaskTClass {
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
(
constructorFlow(source, sink, c)
constructorFlow(source, sourceAp, sink, sinkAp, c)
or
methodFlow(source, sink, c)
or
exists(Property p |
propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
)
methodFlow(source, sourceAp, sink, sinkAp, c)
) and
preservesValue = true
or
exists(Property p |
p = this.(SystemThreadingTasksTaskTClass).getResultProperty() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
c = p.getGetter() and
preservesValue = false
)
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
private predicate constructorFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
Constructor c
) {
// flow from supplied function into constructed Task
c.getDeclaringType() = this and
(
c.getParameter(0).getType() = any(SystemFuncDelegateType t).getAConstructedGeneric() and
source = TCallableFlowSourceDelegateArg(0) and
sink = TCallableFlowSinkReturn()
)
c.getParameter(0).getType() = any(SystemFuncDelegateType t).getAConstructedGeneric() and
source = TCallableFlowSourceDelegateArg(0) and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(this.(SystemThreadingTasksTaskTClass).getResultProperty())
or
// flow from supplied state to supplied delegate
c.getDeclaringType() = this and
@@ -1752,12 +1813,15 @@ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow {
func.getUnboundGeneric().(SystemFuncDelegateType).getNumberOfTypeParameters() = 2 and
func.getTypeArgument(0) instanceof ObjectType and
source = TCallableFlowSourceArg(1) and
sink = getDelegateFlowSinkArg(c, 0, 0)
sourceAp = AccessPath::empty() and
sink = getDelegateFlowSinkArg(c, 0, 0) and
sinkAp = AccessPath::empty()
)
}
private predicate methodFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationMethod m
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationMethod m
) {
m.getDeclaringType() = this and
m.hasName("ContinueWith") and
@@ -1774,13 +1838,17 @@ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow {
delegate.getTypeArgument(j) instanceof ObjectType and
m.getParameter(k).getType() instanceof ObjectType and
source = TCallableFlowSourceArg(k) and
sink = getDelegateFlowSinkArg(m, i, j)
sourceAp = AccessPath::empty() and
sink = getDelegateFlowSinkArg(m, i, j) and
sinkAp = AccessPath::empty()
)
or
// flow from this task to supplied delegate
delegate.getTypeArgument(j) = this and
source = TCallableFlowSourceQualifier() and
sink = getDelegateFlowSinkArg(m, i, j)
sourceAp = AccessPath::empty() and
sink = getDelegateFlowSinkArg(m, i, j) and
sinkAp = AccessPath::empty()
)
or
// flow out of supplied function
@@ -1788,13 +1856,19 @@ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow {
m.getParameter(i).getType() = func and
func.getUnboundGeneric() instanceof SystemFuncDelegateType and
source = getDelegateFlowSourceArg(m, i) and
sink = TCallableFlowSinkReturn()
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(this.(SystemThreadingTasksTaskTClass).getResultProperty())
)
)
}
private predicate propertyFlow(Property p) {
p = this.(SystemThreadingTasksTaskTClass).getResultProperty()
or
m = this.getGetAwaiterMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp =
AccessPath::field(any(SystemRuntimeCompilerServicesTaskAwaiterStruct s)
.getUnderlyingTaskField())
}
}
@@ -1806,15 +1880,16 @@ class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
}
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
methodFlow(source, sink, c) and
methodFlow(source, sourceAp, sink, sinkAp, c) and
preservesValue = true
}
private predicate methodFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationMethod m
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationMethod m
) {
m.getDeclaringType() = this and
(
@@ -1831,7 +1906,9 @@ class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
delegate.getUnboundGeneric() instanceof SystemFuncDelegateType
) and
source = TCallableFlowSourceArg(i) and
sink = getDelegateFlowSinkArg(m, j, k)
sourceAp = AccessPath::empty() and
sink = getDelegateFlowSinkArg(m, j, k) and
sinkAp = AccessPath::empty()
)
or
// flow out of supplied function
@@ -1839,7 +1916,9 @@ class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
m.getParameter(i).getType() = func and
func.getUnboundGeneric() instanceof SystemFuncDelegateType and
source = getDelegateFlowSourceArg(m, i) and
sink = TCallableFlowSinkReturn()
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(any(SystemThreadingTasksTaskTClass c).getResultProperty())
)
)
or
@@ -1855,7 +1934,9 @@ class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
) and
delegate.getTypeArgument(k) instanceof ObjectType and
source = TCallableFlowSourceArg(i) and
sink = getDelegateFlowSinkArg(m, j, k)
sourceAp = AccessPath::empty() and
sink = getDelegateFlowSinkArg(m, j, k) and
sinkAp = AccessPath::empty()
)
or
// flow out of supplied function
@@ -1863,13 +1944,38 @@ class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
m.getParameter(i).getType() = func and
func.getUnboundGeneric() instanceof SystemFuncDelegateType and
source = getDelegateFlowSourceArg(m, i) and
sink = TCallableFlowSinkReturn()
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(any(SystemThreadingTasksTaskTClass c).getResultProperty())
)
)
)
}
}
/** Data flow for `System.Runtime.CompilerServices.TaskAwaiter<>`. */
class SystemRuntimeCompilerServicesTaskAwaiterFlow extends LibraryTypeDataFlow,
SystemRuntimeCompilerServicesTaskAwaiterStruct {
override predicate callableFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
preservesValue = true and
c = this.getGetResultMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp =
AccessPath::cons(any(FieldContent fc | fc.getField() = this.getUnderlyingTaskField()),
AccessPath::property(any(SystemThreadingTasksTaskTClass t).getResultProperty())) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
}
override predicate requiresAccessPath(Content head, AccessPath tail) {
head.(FieldContent).getField() = this.getUnderlyingTaskField() and
tail = AccessPath::property(any(SystemThreadingTasksTaskTClass t).getResultProperty())
}
}
/** Data flow for `System.Text.Encoding`. */
library class SystemTextEncodingFlow extends LibraryTypeDataFlow, SystemTextEncodingClass {
override predicate callableFlow(

View File

@@ -0,0 +1,302 @@
/**
* Provides inferences of the form: `e` equals `b + v` modulo `m` where `e` is
* an expression, `b` is a `Bound` (typically zero or the value of an SSA
* variable), and `v` is an integer in the range `[0 .. m-1]`.
*/
private import internal.rangeanalysis.ModulusAnalysisSpecific::Private
private import Bound
private import internal.rangeanalysis.SsaReadPositionCommon
/**
* Holds if `e + delta` equals `v` at `pos`.
*/
private predicate valueFlowStepSsa(SsaVariable v, SsaReadPosition pos, Expr e, int delta) {
ssaUpdateStep(v, e, delta) and pos.hasReadOfVar(v)
or
exists(Guard guard, boolean testIsTrue |
pos.hasReadOfVar(v) and
guard = eqFlowCond(v, e, delta, true, testIsTrue) and
guardDirectlyControlsSsaRead(guard, pos, testIsTrue)
)
}
/**
* Holds if `add` is the addition of `larg` and `rarg`, neither of which are
* `ConstantIntegerExpr`s.
*/
private predicate nonConstAddition(Expr add, Expr larg, Expr rarg) {
exists(AddExpr a | a = add |
larg = a.getLhs() and
rarg = a.getRhs()
) and
not larg instanceof ConstantIntegerExpr and
not rarg instanceof ConstantIntegerExpr
}
/**
* Holds if `sub` is the subtraction of `larg` and `rarg`, where `rarg` is not
* a `ConstantIntegerExpr`.
*/
private predicate nonConstSubtraction(Expr sub, Expr larg, Expr rarg) {
exists(SubExpr s | s = sub |
larg = s.getLhs() and
rarg = s.getRhs()
) and
not rarg instanceof ConstantIntegerExpr
}
/** Gets an expression that is the remainder modulo `mod` of `arg`. */
private Expr modExpr(Expr arg, int mod) {
exists(RemExpr rem |
result = rem and
arg = rem.getLeftOperand() and
rem.getRightOperand().(ConstantIntegerExpr).getIntValue() = mod and
mod >= 2
)
or
exists(ConstantIntegerExpr c |
mod = 2.pow([1 .. 30]) and
c.getIntValue() = mod - 1 and
result.(BitwiseAndExpr).hasOperands(arg, c)
)
}
/**
* Gets a guard that tests whether `v` is congruent with `val` modulo `mod` on
* its `testIsTrue` branch.
*/
private Guard moduloCheck(SsaVariable v, int val, int mod, boolean testIsTrue) {
exists(Expr rem, ConstantIntegerExpr c, int r, boolean polarity |
result.isEquality(rem, c, polarity) and
c.getIntValue() = r and
rem = modExpr(v.getAUse(), mod) and
(
testIsTrue = polarity and val = r
or
testIsTrue = polarity.booleanNot() and
mod = 2 and
val = 1 - r and
(r = 0 or r = 1)
)
)
}
/**
* Holds if a guard ensures that `v` at `pos` is congruent with `val` modulo `mod`.
*/
private predicate moduloGuardedRead(SsaVariable v, SsaReadPosition pos, int val, int mod) {
exists(Guard guard, boolean testIsTrue |
pos.hasReadOfVar(v) and
guard = moduloCheck(v, val, mod, testIsTrue) and
guardControlsSsaRead(guard, pos, testIsTrue)
)
}
/** Holds if `factor` is a power of 2 that divides `mask`. */
bindingset[mask]
private predicate andmaskFactor(int mask, int factor) {
mask % factor = 0 and
factor = 2.pow([1 .. 30])
}
/** Holds if `e` is evenly divisible by `factor`. */
private predicate evenlyDivisibleExpr(Expr e, int factor) {
exists(ConstantIntegerExpr c, int k | k = c.getIntValue() |
e.(MulExpr).getAnOperand() = c and factor = k.abs() and factor >= 2
or
e.(LShiftExpr).getRhs() = c and factor = 2.pow(k) and k > 0
or
e.(BitwiseAndExpr).getAnOperand() = c and factor = max(int f | andmaskFactor(k, f))
)
}
/**
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
* in an arbitrary 1-based numbering of the input edges to `phi`.
*/
private predicate rankedPhiInput(
SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r
) {
edge.phiInput(phi, inp) and
edge =
rank[r](SsaReadPositionPhiInputEdge e | e.phiInput(phi, _) | e order by getId(e.getOrigBlock()))
}
/**
* Holds if `rix` is the number of input edges to `phi`.
*/
private predicate maxPhiInputRank(SsaPhiNode phi, int rix) {
rix = max(int r | rankedPhiInput(phi, _, _, r))
}
/**
* Gets the remainder of `val` modulo `mod`.
*
* For `mod = 0` the result equals `val` and for `mod > 1` the result is within
* the range `[0 .. mod-1]`.
*/
bindingset[val, mod]
private int remainder(int val, int mod) {
mod = 0 and result = val
or
mod > 1 and result = ((val % mod) + mod) % mod
}
/**
* Holds if `inp` is an input to `phi` and equals `phi` modulo `mod` along `edge`.
*/
private predicate phiSelfModulus(
SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int mod
) {
exists(SsaBound phibound, int v, int m |
edge.phiInput(phi, inp) and
phibound.getSsa() = phi and
ssaModulus(inp, edge, phibound, v, m) and
mod = m.gcd(v) and
mod != 1
)
}
/**
* Holds if `b + val` modulo `mod` is a candidate congruence class for `phi`.
*/
private predicate phiModulusInit(SsaPhiNode phi, Bound b, int val, int mod) {
exists(SsaVariable inp, SsaReadPositionPhiInputEdge edge |
edge.phiInput(phi, inp) and
ssaModulus(inp, edge, b, val, mod)
)
}
/**
* Holds if all inputs to `phi` numbered `1` to `rix` are equal to `b + val` modulo `mod`.
*/
private predicate phiModulusRankStep(SsaPhiNode phi, Bound b, int val, int mod, int rix) {
rix = 0 and
phiModulusInit(phi, b, val, mod)
or
exists(SsaVariable inp, SsaReadPositionPhiInputEdge edge, int v1, int m1 |
mod != 1 and
val = remainder(v1, mod)
|
exists(int v2, int m2 |
rankedPhiInput(phi, inp, edge, rix) and
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
ssaModulus(inp, edge, b, v2, m2) and
mod = m1.gcd(m2).gcd(v1 - v2)
)
or
exists(int m2 |
rankedPhiInput(phi, inp, edge, rix) and
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
phiSelfModulus(phi, inp, edge, m2) and
mod = m1.gcd(m2)
)
)
}
/**
* Holds if `phi` is equal to `b + val` modulo `mod`.
*/
private predicate phiModulus(SsaPhiNode phi, Bound b, int val, int mod) {
exists(int r |
maxPhiInputRank(phi, r) and
phiModulusRankStep(phi, b, val, mod, r)
)
}
/**
* Holds if `v` at `pos` is equal to `b + val` modulo `mod`.
*/
private predicate ssaModulus(SsaVariable v, SsaReadPosition pos, Bound b, int val, int mod) {
phiModulus(v, b, val, mod) and pos.hasReadOfVar(v)
or
b.(SsaBound).getSsa() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
or
exists(Expr e, int val0, int delta |
exprModulus(e, b, val0, mod) and
valueFlowStepSsa(v, pos, e, delta) and
val = remainder(val0 + delta, mod)
)
or
moduloGuardedRead(v, pos, val, mod) and b instanceof ZeroBound
}
/**
* Holds if `e` is equal to `b + val` modulo `mod`.
*
* There are two cases for the modulus:
* - `mod = 0`: The equality `e = b + val` is an ordinary equality.
* - `mod > 1`: `val` lies within the range `[0 .. mod-1]`.
*/
cached
predicate exprModulus(Expr e, Bound b, int val, int mod) {
e = b.getExpr(val) and mod = 0
or
evenlyDivisibleExpr(e, mod) and val = 0 and b instanceof ZeroBound
or
exists(SsaVariable v, SsaReadPositionBlock bb |
ssaModulus(v, bb, b, val, mod) and
e = v.getAUse() and
getABasicBlockExpr(bb.getBlock()) = e
)
or
exists(Expr mid, int val0, int delta |
exprModulus(mid, b, val0, mod) and
valueFlowStep(e, mid, delta) and
val = remainder(val0 + delta, mod)
)
or
exists(ConditionalExpr cond, int v1, int v2, int m1, int m2 |
cond = e and
condExprBranchModulus(cond, true, b, v1, m1) and
condExprBranchModulus(cond, false, b, v2, m2) and
mod = m1.gcd(m2).gcd(v1 - v2) and
mod != 1 and
val = remainder(v1, mod)
)
or
exists(Bound b1, Bound b2, int v1, int v2, int m1, int m2 |
addModulus(e, true, b1, v1, m1) and
addModulus(e, false, b2, v2, m2) and
mod = m1.gcd(m2) and
mod != 1 and
val = remainder(v1 + v2, mod)
|
b = b1 and b2 instanceof ZeroBound
or
b = b2 and b1 instanceof ZeroBound
)
or
exists(int v1, int v2, int m1, int m2 |
subModulus(e, true, b, v1, m1) and
subModulus(e, false, any(ZeroBound zb), v2, m2) and
mod = m1.gcd(m2) and
mod != 1 and
val = remainder(v1 - v2, mod)
)
}
private predicate condExprBranchModulus(
ConditionalExpr cond, boolean branch, Bound b, int val, int mod
) {
exprModulus(cond.getTrueExpr(), b, val, mod) and branch = true
or
exprModulus(cond.getFalseExpr(), b, val, mod) and branch = false
}
private predicate addModulus(Expr add, boolean isLeft, Bound b, int val, int mod) {
exists(Expr larg, Expr rarg | nonConstAddition(add, larg, rarg) |
exprModulus(larg, b, val, mod) and isLeft = true
or
exprModulus(rarg, b, val, mod) and isLeft = false
)
}
private predicate subModulus(Expr sub, boolean isLeft, Bound b, int val, int mod) {
exists(Expr larg, Expr rarg | nonConstSubtraction(sub, larg, rarg) |
exprModulus(larg, b, val, mod) and isLeft = true
or
exprModulus(rarg, b, val, mod) and isLeft = false
)
}

View File

@@ -136,30 +136,6 @@ private predicate exprImpliesSsaDef(
)
}
/**
* Holds if the `i`th node of basic block `bb` ensures that SSA definition
* `def` is not `null` in any subsequent uses.
*/
private predicate ensureNotNullAt(BasicBlock bb, int i, Ssa::Definition def) {
exists(Expr e, G::AbstractValue v, NullValue nv |
G::Internal::asserts(bb.getNode(i).getElement(), e, v)
|
exprImpliesSsaDef(e, v, def, nv) and
nv.isNonNull()
)
}
/**
* Holds if the `i`th node of basic block `bb` is a dereference `d` of SSA
* definition `def`, and `def` may potentially be `null`.
*/
private predicate potentialNullDereferenceAt(
BasicBlock bb, int i, Ssa::Definition def, Dereference d
) {
dereferenceAt(bb, i, def, d) and
not exists(int j | ensureNotNullAt(bb, j, def) | j < i)
}
/**
* Gets an element that tests whether a given SSA definition, `def`, is
* `null` or not.
@@ -269,7 +245,6 @@ private predicate defNullImpliesStep(
bb2 = def.getBasicBlock()
)
) and
not ensureNotNullAt(bb1, _, def1) and
not exists(SuccessorTypes::ConditionalSuccessor s, NullValue nv |
bb1.getLastNode() = getANullCheck(def1, s, nv).getAControlFlowNode()
|
@@ -296,7 +271,7 @@ private predicate defMaybeNullInBlock(Ssa::Definition def, BasicBlock bb) {
* dereference.
*/
private predicate nullDerefCandidateVariable(Ssa::SourceVariable v) {
exists(Ssa::Definition def, BasicBlock bb | potentialNullDereferenceAt(bb, _, def, _) |
exists(Ssa::Definition def, BasicBlock bb | dereferenceAt(bb, _, def, _) |
defMaybeNullInBlock(def, bb) and
v = def.getSourceVariable()
)
@@ -328,7 +303,7 @@ private newtype TPathNode =
succNullArgument(_, def, bb)
} or
TSinkPathNode(Ssa::Definition def, BasicBlock bb, int i, Dereference d) {
potentialNullDereferenceAt(bb, i, def, d) and
dereferenceAt(bb, i, def, d) and
(
succStep(_, def, bb)
or

View File

@@ -1430,7 +1430,14 @@ module Ssa {
) {
possiblyLiveAtAllNodes(bb, v) and
callAt(bb, i, call) and
relevantDefinition(_, v.getAssignable(), _)
exists(Assignable a |
a = v.getAssignable() and
relevantDefinition(_, a, _) and
not exists(AssignableDefinitions::OutRefDefinition def |
def.getCall() = call and
def.getTarget() = a
)
)
}
/**

View File

@@ -167,4 +167,9 @@ module Consistency {
not isImmutableOrUnobservable(n) and
msg = "ArgumentNode is missing PostUpdateNode."
}
query predicate postWithInFlow(PostUpdateNode n, string msg) {
simpleLocalFlowStep(_, n) and
msg = "PostUpdateNode should not be the target of local flow."
}
}

View File

@@ -16,6 +16,7 @@ private import semmle.code.csharp.dispatch.Dispatch
private import semmle.code.csharp.frameworks.EntityFramework
private import semmle.code.csharp.frameworks.NHibernate
private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.frameworks.system.threading.Tasks
abstract class NodeImpl extends Node {
/** Do not call: use `getEnclosingCallable()` instead. */
@@ -154,10 +155,6 @@ module LocalFlow {
scope = e2 and
isSuccessor = true
or
e1 = e2.(AwaitExpr).getExpr() and
scope = e2 and
isSuccessor = true
or
// An `=` expression, where the result of the expression is used
e2 =
any(AssignExpr ae |
@@ -174,6 +171,10 @@ module LocalFlow {
e1 = e2.(ArrayCreation).getInitializer() and
scope = e2 and
isSuccessor = false
or
e1 = e2.(SwitchExpr).getACase().getBody() and
scope = e2 and
isSuccessor = false
)
}
@@ -679,6 +680,11 @@ private module Cached {
storeStepLibrary(node1, c, node2)
}
pragma[nomagic]
private PropertyContent getResultContent() {
result.getProperty() = any(SystemThreadingTasksTaskTClass c_).getResultProperty()
}
/**
* Holds if data can flow from `node1` to `node2` via a read of content `c`.
*/
@@ -699,6 +705,10 @@ private module Cached {
node2.(SsaDefinitionNode).getDefinition() = def and
c instanceof ElementContent
)
or
x.hasNodePath(node1, node2) and
node2.asExpr().(AwaitExpr).getExpr() = node1.asExpr() and
c = getResultContent()
)
or
readStepLibrary(node1, c, node2)
@@ -733,7 +743,7 @@ private module Cached {
viableConstantBooleanParamArg(paramNode, bs.getValue().booleanNot(), call) and
paramNode.getDefinition() = param and
param.getARead() = guard and
guard.controlsBlock(n.getControlFlowNode().getBasicBlock(), bs)
guard.controlsBlock(n.getControlFlowNode().getBasicBlock(), bs, _)
)
}
@@ -2180,6 +2190,11 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration
isSuccessor = true and
arrayRead(e1, e2) and
scope = e2
or
exactScope = false and
e1 = e2.(AwaitExpr).getExpr() and
scope = e2 and
isSuccessor = true
}
override predicate candidateDef(

View File

@@ -95,6 +95,10 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
scope = e2 and
isSuccessor = true
)
or
e1 = e2.(AwaitExpr).getExpr() and
scope = e2 and
isSuccessor = true
)
}
}

View File

@@ -0,0 +1,21 @@
/**
* Provides C#-specific definitions for bounds.
*/
private import csharp as CS
private import semmle.code.csharp.dataflow.SSA::Ssa as Ssa
private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU
class SsaVariable extends Ssa::Definition {
/** Gets a read of the source variable underlying this SSA definition. */
Expr getAUse() { result = getARead() }
}
class Expr = CS::Expr;
class IntegralType = CS::IntegralType;
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
/** Holds if `e` is a bound expression and it is not an SSA variable read. */
predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.(CS::PropertyRead)) }

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